ci(*): Put the commit hashes back in release filenames

This commit is contained in:
Ben Gotow 2015-10-16 14:01:29 -07:00
parent 9cae62dc63
commit 584da13788
3 changed files with 38 additions and 225 deletions

View file

@ -1,200 +0,0 @@
child_process = require 'child_process'
path = require 'path'
_ = require 'underscore'
async = require 'async'
fs = require 'fs-plus'
GitHub = require 'github-releases'
request = require 'request'
grunt = null
commitSha = process.env.JANKY_SHA1
token = process.env.EDGEHILL_ACCESS_TOKEN
defaultHeaders =
Authorization: "token #{token}"
'User-Agent': 'N1'
module.exports = (gruntObject) ->
grunt = gruntObject
{cp} = require('./task-helpers')(grunt)
grunt.registerTask 'publish-build', 'Publish the built app', ->
tasks = []
tasks.push('build-docs', 'prepare-docs') if process.platform is 'darwin'
tasks.push('upload-assets') if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master'
grunt.task.run(tasks)
grunt.registerTask 'prepare-docs', 'Move api.json to edgehill-api.json', ->
docsOutputDir = grunt.config.get('docsOutputDir')
buildDir = grunt.config.get('atom.buildDir')
cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'edgehill-api.json')
grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', ->
doneCallback = @async()
startTime = Date.now()
done = (args...) ->
elapsedTime = Math.round((Date.now() - startTime) / 100) / 10
grunt.log.ok("Upload time: #{elapsedTime}s")
doneCallback(args...)
unless token
return done(new Error('EDGEHILL_ACCESS_TOKEN environment variable not set'))
buildDir = grunt.config.get('atom.buildDir')
assets = getAssets()
zipAssets buildDir, assets, (error) ->
return done(error) if error?
getAtomDraftRelease (error, release) ->
return done(error) if error?
assetNames = (asset.assetName for asset in assets)
deleteExistingAssets release, assetNames, (error) ->
return done(error) if error?
uploadAssets(release, buildDir, assets, done)
getAssets = ->
{cp} = require('./task-helpers')(grunt)
{version} = grunt.file.readJSON('package.json')
buildDir = grunt.config.get('atom.buildDir')
switch process.platform
when 'darwin'
[
{assetName: 'nylas-mac.zip', sourcePath: 'Nylas.app'}
{assetName: 'nylas-mac-symbols.zip', sourcePath: 'Nylas.breakpad.syms'}
{assetName: 'nylas-api.json', sourcePath: 'nylas-api.json'}
]
when 'win32'
assets = [{assetName: 'nylas-windows.zip', sourcePath: 'Nylas'}]
for squirrelAsset in ['NylasSetup.exe', 'RELEASES', "nylas-#{version}-full.nupkg"]
cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset)
assets.push({assetName: squirrelAsset, sourcePath: assetName})
assets
when 'linux'
if process.arch is 'ia32'
arch = 'i386'
else
arch = 'amd64'
# Check for a Debian build
sourcePath = "#{buildDir}/edgehill-#{version}-#{arch}.deb"
assetName = "edgehill-#{arch}.deb"
# Check for a Fedora build
unless fs.isFileSync(sourcePath)
rpmName = fs.readdirSync("#{buildDir}/rpm")[0]
sourcePath = "#{buildDir}/rpm/#{rpmName}"
if process.arch is 'ia32'
arch = 'i386'
else
arch = 'x86_64'
assetName = "edgehill.#{arch}.rpm"
cp sourcePath, path.join(buildDir, assetName)
[
{assetName, sourcePath}
]
logError = (message, error, details) ->
grunt.log.error(message)
grunt.log.error(error.message ? error) if error?
grunt.log.error(details) if details
zipAssets = (buildDir, assets, callback) ->
zip = (directory, sourcePath, assetName, callback) ->
if process.platform is 'win32'
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourcePath}"
else
zipCommand = "zip -r --symlinks #{assetName} #{sourcePath}"
options = {cwd: directory, maxBuffer: Infinity}
child_process.exec zipCommand, options, (error, stdout, stderr) ->
logError("Zipping #{sourcePath} failed", error, stderr) if error?
callback(error)
tasks = []
for {assetName, sourcePath} in assets when path.extname(assetName) is '.zip'
fs.removeSync(path.join(buildDir, assetName))
tasks.push(zip.bind(this, buildDir, sourcePath, assetName))
async.parallel(tasks, callback)
getAtomDraftRelease = (callback) ->
atomRepo = new GitHub({repo: 'nylas/edgehill', token})
atomRepo.getReleases (error, releases=[]) ->
if error?
logError('Fetching nylas/edgehill releases failed', error, releases)
callback(error)
else
[firstDraft] = releases.filter ({draft}) -> draft
if firstDraft?
options =
uri: firstDraft.assets_url
method: 'GET'
headers: defaultHeaders
json: true
request options, (error, response, assets=[]) ->
if error? or response.statusCode isnt 200
logError('Fetching draft release assets failed', error, assets)
callback(error ? new Error(response.statusCode))
else
firstDraft.assets = assets
callback(null, firstDraft)
else
callback(new Error('No draft release in nylas/edgehill repo'))
deleteRelease = (release) ->
options =
uri: release.url
method: 'DELETE'
headers: defaultHeaders
json: true
request options, (error, response, body='') ->
if error? or response.statusCode isnt 204
logError('Deleting release failed', error, body)
deleteExistingAssets = (release, assetNames, callback) ->
[callback, assetNames] = [assetNames, callback] if not callback?
deleteAsset = (url, callback) ->
options =
uri: url
method: 'DELETE'
headers: defaultHeaders
request options, (error, response, body='') ->
if error? or response.statusCode isnt 204
logError('Deleting existing release asset failed', error, body)
callback(error ? new Error(response.statusCode))
else
callback()
tasks = []
for asset in release.assets when not assetNames? or asset.name in assetNames
tasks.push(deleteAsset.bind(this, asset.url))
async.parallel(tasks, callback)
uploadAssets = (release, buildDir, assets, callback) ->
upload = (release, assetName, assetPath, callback) ->
options =
uri: release.upload_url.replace(/\{.*$/, "?name=#{assetName}")
method: 'POST'
headers: _.extend({
'Content-Type': 'application/zip'
'Content-Length': fs.getSizeSync(assetPath)
}, defaultHeaders)
assetRequest = request options, (error, response, body='') ->
if error? or response.statusCode >= 400
logError("Upload release asset #{assetName} failed", error, body)
callback(error ? new Error(response.statusCode))
else
callback(null, release)
fs.createReadStream(assetPath).pipe(assetRequest)
tasks = []
for {assetName} in assets
assetPath = path.join(buildDir, assetName)
tasks.push(upload.bind(this, release, assetName, assetPath))
async.parallel(tasks, callback)

View file

@ -6,32 +6,41 @@ request = require 'request'
Promise = require 'bluebird'
s3Client = null
packageVersion = null
fullVersion = null
module.exports = (grunt) ->
{cp, spawn, rm} = require('./task-helpers')(grunt)
getVersion = ->
{version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json'))
return version
appName = -> grunt.config.get('atom.appName')
dmgName = -> "#{appName().split('.')[0]}.dmg"
zipName = -> "#{appName().split('.')[0]}.zip"
winReleasesName = -> "RELEASES"
winSetupName = -> "Nylas N1Setup.exe"
winNupkgName = -> "nylas-#{getVersion()}-full.nupkg"
winNupkgName = -> "nylas-#{packageVersion}-full.nupkg"
populateVersion = ->
new Promise (resolve, reject) ->
json = require(path.join(grunt.config.get('atom.appDir'), 'package.json'))
cmd = 'git'
args = ['rev-parse', '--short', 'HEAD']
spawn {cmd, args}, (error, {stdout}={}, code) ->
return reject() if error
commitHash = stdout?.trim?()
packageVersion = json.version
fullVersion = "#{json.version}-#{commitHash}"
resolve()
runEmailIntegrationTest = ->
return Promise.resolve() unless process.platform is 'darwin'
buildDir = grunt.config.get('atom.buildDir')
buildVersion = getVersion()
new Promise (resolve, reject) ->
appToRun = path.join(buildDir, appName())
scriptToRun = "./build/run-build-and-send-screenshot.scpt"
spawn
cmd: "osascript"
args: [scriptToRun, appToRun, buildVersion]
args: [scriptToRun, appToRun, fullVersion]
, (error) ->
if error
reject(error)
@ -77,7 +86,8 @@ module.exports = (grunt) ->
resolve(data)
uploadToS3 = (filename, key) ->
filepath = path.join(grunt.config.get('atom.buildDir'), filename)
buildDir = grunt.config.get('atom.buildDir')
filepath = path.join(buildDir, filename)
grunt.log.writeln ">> Uploading #{filename} to #{key}"
put(filepath, key).then (data) ->
@ -86,12 +96,13 @@ module.exports = (grunt) ->
Promise.resolve(data)
uploadZipToS3 = (filename, key) ->
filepath = path.join(grunt.config.get('atom.buildDir'), filename)
buildDir = grunt.config.get('atom.buildDir')
filepath = path.join(buildDir, filename)
grunt.log.writeln ">> Creating zip file…"
new Promise (resolve, reject) ->
zipFilepath = filepath + ".zip"
rm(zipPath)
rm(zipFilepath)
orig = process.cwd()
process.chdir(buildDir)
@ -104,7 +115,7 @@ module.exports = (grunt) ->
reject(error)
return
grunt.log.writeln ">> Created #{zipPath}"
grunt.log.writeln ">> Created #{zipFilepath}"
grunt.log.writeln ">> Uploading…"
uploadToS3(zipFilepath, key).then(resolve).catch(reject)
@ -126,16 +137,17 @@ module.exports = (grunt) ->
done = @async()
runEmailIntegrationTest().then ->
uploadPromises = []
if process.platform is 'darwin'
uploadPromises.push uploadToS3(dmgName(), "#{process.platform}/N1-#{getVersion()}.dmg")
uploadPromises.push uploadZipToS3(appName(), "#{process.platform}/N1-#{getVersion()}.zip")
if process.platform is 'win32'
uploadPromises.push uploadToS3("installer/"+winReleasesName(), "#{process.platform}/nylas-#{getVersion()}-RELEASES.txt")
uploadPromises.push uploadToS3("installer/"+winSetupName(), "#{process.platform}/nylas-#{getVersion()}.exe")
uploadPromises.push uploadToS3("installer/"+winNupkgName(), "#{process.platform}/#{winNupkgName()}")
populateVersion().then ->
runEmailIntegrationTest().then ->
uploadPromises = []
if process.platform is 'darwin'
uploadPromises.push uploadToS3(dmgName(), "#{process.platform}/N1-#{fullVersion}.dmg")
uploadPromises.push uploadZipToS3(appName(), "#{process.platform}/N1-#{fullVersion}.zip")
if process.platform is 'win32'
uploadPromises.push uploadToS3("installer/"+winReleasesName(), "#{process.platform}/nylas-#{fullVersion}-RELEASES.txt")
uploadPromises.push uploadToS3("installer/"+winSetupName(), "#{process.platform}/nylas-#{fullVersion}.exe")
uploadPromises.push uploadToS3("installer/"+winNupkgName(), "#{process.platform}/nylas-#{fullVersion}-full.nupkg")
Promise.all(uploadPromises).then(done).catch (err) ->
grunt.log.error(err)
return false
Promise.all(uploadPromises).then(done).catch (err) ->
grunt.log.error(err)
return false

View file

@ -5,10 +5,11 @@ module.exports = (grunt) ->
{spawn} = require('./task-helpers')(grunt)
getVersion = (callback) ->
onBuildMachine = true
onBuildMachine = process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master'
onWindows = process.platform is 'win32'
inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git'))
{version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json'))
if onBuildMachine or not inRepository
if onBuildMachine or onWindows or not inRepository
callback(null, version)
else
cmd = 'git'