2013-12-10 20:22:06 +04:00
|
|
|
child_process = require 'child_process'
|
|
|
|
path = require 'path'
|
|
|
|
|
2013-12-11 04:34:26 +04:00
|
|
|
_ = require 'underscore-plus'
|
2014-02-28 12:49:03 +04:00
|
|
|
async = require 'async'
|
2013-12-10 20:51:30 +04:00
|
|
|
fs = require 'fs-plus'
|
2014-01-15 00:07:23 +04:00
|
|
|
GitHub = require 'github-releases'
|
2013-12-10 20:22:06 +04:00
|
|
|
request = require 'request'
|
|
|
|
|
2014-01-03 22:49:03 +04:00
|
|
|
grunt = null
|
2013-12-11 21:17:47 +04:00
|
|
|
maxReleases = 10
|
2014-02-28 09:30:55 +04:00
|
|
|
assets = [
|
2014-02-28 09:42:32 +04:00
|
|
|
{assetName: 'atom-mac.zip', sourceName: 'Atom.app'}
|
|
|
|
{assetName: 'atom-mac-symbols.zip', sourceName: 'Atom.breakpad.syms'}
|
2014-02-28 09:30:55 +04:00
|
|
|
]
|
2013-12-11 04:34:26 +04:00
|
|
|
commitSha = process.env.JANKY_SHA1
|
2013-12-10 20:22:06 +04:00
|
|
|
token = process.env.ATOM_ACCESS_TOKEN
|
2013-12-11 04:34:26 +04:00
|
|
|
defaultHeaders =
|
|
|
|
Authorization: "token #{token}"
|
|
|
|
'User-Agent': 'Atom'
|
2013-12-10 20:22:06 +04:00
|
|
|
|
2014-01-03 22:49:03 +04:00
|
|
|
module.exports = (gruntObject) ->
|
|
|
|
grunt = gruntObject
|
2014-02-28 09:30:55 +04:00
|
|
|
|
2014-01-02 23:41:34 +04:00
|
|
|
grunt.registerTask 'publish-build', 'Publish the built app', ->
|
|
|
|
return unless process.platform is 'darwin'
|
|
|
|
return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
|
|
|
|
|
|
|
|
done = @async()
|
2014-02-28 09:30:55 +04:00
|
|
|
buildDir = grunt.config.get('atom.buildDir')
|
2014-01-02 23:41:34 +04:00
|
|
|
|
2014-04-30 20:29:05 +04:00
|
|
|
zipApps buildDir, assets, (error) ->
|
2014-01-02 23:41:34 +04:00
|
|
|
return done(error) if error?
|
2014-04-30 20:43:01 +04:00
|
|
|
getAtomDraftRelease (error, release) ->
|
2014-02-28 12:49:03 +04:00
|
|
|
return done(error) if error?
|
2014-04-30 20:43:01 +04:00
|
|
|
assetNames = (asset.assetName for asset in assets)
|
|
|
|
deleteExistingAssets release, assetNames, (error) ->
|
2014-01-02 23:41:34 +04:00
|
|
|
return done(error) if error?
|
2014-04-30 20:43:01 +04:00
|
|
|
uploadAssets(release, buildDir, assets, done)
|
2014-01-02 23:41:34 +04:00
|
|
|
|
|
|
|
logError = (message, error, details) ->
|
|
|
|
grunt.log.error(message)
|
|
|
|
grunt.log.error(error.message ? error) if error?
|
|
|
|
grunt.log.error(details) if details
|
|
|
|
|
2014-02-28 12:49:03 +04:00
|
|
|
zipApps = (buildDir, assets, callback) ->
|
|
|
|
zip = (directory, sourceName, assetName, callback) ->
|
|
|
|
options = {cwd: directory, maxBuffer: Infinity}
|
|
|
|
child_process.exec "zip -r --symlinks #{assetName} #{sourceName}", options, (error, stdout, stderr) ->
|
|
|
|
if error?
|
|
|
|
logError("Zipping #{sourceName} failed", error, stderr)
|
|
|
|
callback(error)
|
2013-12-10 20:22:06 +04:00
|
|
|
|
2014-02-28 12:49:03 +04:00
|
|
|
tasks = []
|
|
|
|
for {assetName, sourceName} in assets
|
|
|
|
fs.removeSync(path.join(buildDir, assetName))
|
|
|
|
tasks.push(zip.bind(this, buildDir, sourceName, assetName))
|
|
|
|
async.parallel(tasks, callback)
|
2013-12-10 20:22:06 +04:00
|
|
|
|
2014-01-15 00:07:23 +04:00
|
|
|
getAtomDraftRelease = (callback) ->
|
|
|
|
atomRepo = new GitHub({repo: 'atom/atom', token})
|
|
|
|
atomRepo.getReleases (error, releases=[]) ->
|
|
|
|
if error?
|
|
|
|
logError('Fetching atom/atom releases failed', error, releases)
|
|
|
|
callback(error)
|
|
|
|
else
|
|
|
|
for release in releases when release.draft
|
|
|
|
callback(null, release)
|
|
|
|
return
|
|
|
|
callback(new Error('No draft release in atom/atom repo'))
|
|
|
|
|
2013-12-11 21:17:47 +04:00
|
|
|
deleteRelease = (release) ->
|
|
|
|
options =
|
|
|
|
uri: release.url
|
|
|
|
method: 'DELETE'
|
|
|
|
headers: defaultHeaders
|
|
|
|
json: true
|
|
|
|
request options, (error, response, body='') ->
|
|
|
|
if error? or response.statusCode isnt 204
|
2014-01-02 23:41:34 +04:00
|
|
|
logError('Deleting release failed', error, body)
|
2013-12-11 21:17:47 +04:00
|
|
|
|
2014-02-28 12:49:03 +04:00
|
|
|
deleteExistingAssets = (release, assetNames, callback) ->
|
|
|
|
[callback, assetNames] = [assetNames, callback] if not callback?
|
|
|
|
|
|
|
|
deleteAsset = (url, callback) ->
|
2013-12-10 20:22:06 +04:00
|
|
|
options =
|
2014-02-28 12:49:03 +04:00
|
|
|
uri: url
|
2013-12-10 20:51:30 +04:00
|
|
|
method: 'DELETE'
|
2013-12-11 04:34:26 +04:00
|
|
|
headers: defaultHeaders
|
2013-12-10 20:51:30 +04:00
|
|
|
request options, (error, response, body='') ->
|
2013-12-11 05:47:43 +04:00
|
|
|
if error? or response.statusCode isnt 204
|
2014-01-02 23:41:34 +04:00
|
|
|
logError('Deleting existing release asset failed', error, body)
|
2014-01-02 23:45:04 +04:00
|
|
|
callback(error ? new Error(response.statusCode))
|
2013-12-10 20:51:30 +04:00
|
|
|
else
|
|
|
|
callback()
|
|
|
|
|
2014-02-28 12:49:03 +04:00
|
|
|
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)
|
2013-12-10 20:51:30 +04:00
|
|
|
|
2014-02-28 12:49:03 +04:00
|
|
|
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)
|
2013-12-11 04:34:26 +04:00
|
|
|
|
2014-02-28 12:49:03 +04:00
|
|
|
tasks = []
|
|
|
|
for {assetName, sourceName} in assets
|
|
|
|
assetPath = path.join(buildDir, assetName)
|
|
|
|
tasks.push(upload.bind(this, release, assetName, assetPath))
|
|
|
|
async.parallel(tasks, callback)
|