diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 50f8d9af3..8ad24efe8 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -1,341 +1,345 @@ -fs = require 'fs' -path = require 'path' -os = require 'os' - -# This is the main Gruntfile that manages building N1 distributions. -# The reason it's inisde of the build/ folder is so everything can be -# compiled against Node's v8 headers instead of Atom's v8 headers. All -# packages in the root-level node_modules are compiled against Atom's v8 -# headers. -# -# Some useful grunt options are: -# --install-dir -# --build-dir -# -# To keep the various directories straight, here are what the various -# directories might look like on MacOS -# -# tmpDir: /var/folders/xl/_qdlmc512sb6cpqryy_2tzzw0000gn/T/ (aka /tmp) -# -# buildDir = /tmp/nylas-build -# shellAppDir = /tmp/nylas-build/Nylas.app -# contentsDir = /tmp/nylas-build/Nylas.app/Contents -# appDir = /tmp/nylas-build/Nylas.app/Contents/Resources/app -# -# installDir = /Applications/Nylas.app -# -# And on Linux: -# -# tmpDir: /tmp/ -# -# buildDir = /tmp/nylas-build -# shellAppDir = /tmp/nylas-build/Nylas -# contentsDir = /tmp/nylas-build/Nylas -# appDir = /tmp/nylas-build/Nylas/resources/app -# -# installDir = /usr/local OR $INSTALL_PREFIX -# binDir = /usr/local/bin -# shareDir = /usr/local/share/nylas - -# Add support for obselete APIs of vm module so we can make some third-party -# modules work under node v0.11.x. -require 'vm-compatibility-layer' - -_ = require 'underscore' - -packageJson = require '../package.json' - -# Shim harmony collections in case grunt was invoked without harmony -# collections enabled -_.extend(global, require('harmony-collections')) unless global.WeakMap? - -module.exports = (grunt) -> - grunt.loadNpmTasks('grunt-coffeelint-cjsx') - grunt.loadNpmTasks('grunt-lesslint') - grunt.loadNpmTasks('grunt-cson') - grunt.loadNpmTasks('grunt-contrib-csslint') - grunt.loadNpmTasks('grunt-coffee-react') - grunt.loadNpmTasks('grunt-contrib-coffee') - grunt.loadNpmTasks('grunt-contrib-less') - grunt.loadNpmTasks('grunt-shell') - grunt.loadNpmTasks('grunt-markdown') - grunt.loadNpmTasks('grunt-download-electron') - grunt.loadNpmTasks('grunt-electron-installer') - grunt.loadNpmTasks('grunt-peg') - grunt.loadTasks('tasks') - - # This allows all subsequent paths to the relative to the root of the repo - grunt.file.setBase(path.resolve('..')) - - # Commented out because it was causing normal grunt message to dissapear - # for some reason. - # if not grunt.option('verbose') - # grunt.log.writeln = (args...) -> grunt.log - # grunt.log.write = (args...) -> grunt.log - - [major, minor, patch] = packageJson.version.split('.') - tmpDir = os.tmpdir() - appName = if process.platform is 'darwin' then 'Nylas.app' else 'Nylas' - buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'nylas-build') - buildDir = path.resolve(buildDir) - installDir = grunt.option('install-dir') - - home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME - electronDownloadDir = path.join(home, '.nylas', 'electron') - - symbolsDir = path.join(buildDir, 'Atom.breakpad.syms') - shellAppDir = path.join(buildDir, appName) - if process.platform is 'win32' - contentsDir = shellAppDir - appDir = path.join(shellAppDir, 'resources', 'app') - installDir ?= path.join(process.env.ProgramFiles, appName) - killCommand = 'taskkill /F /IM nylas.exe' - else if process.platform is 'darwin' - contentsDir = path.join(shellAppDir, 'Contents') - appDir = path.join(contentsDir, 'Resources', 'app') - installDir ?= path.join('/Applications', appName) - killCommand = 'pkill -9 Nylas' - else - contentsDir = shellAppDir - appDir = path.join(shellAppDir, 'resources', 'app') - installDir ?= process.env.INSTALL_PREFIX ? '/usr/local' - killCommand = 'pkill -9 nylas' - - installDir = path.resolve(installDir) - - cjsxConfig = - glob_to_multiple: - expand: true - src: [ - 'src/**/*.cjsx' - 'internal_packages/**/*.cjsx' - ] - dest: appDir - ext: '.js' - - coffeeConfig = - glob_to_multiple: - expand: true - src: [ - 'src/**/*.coffee' - 'internal_packages/**/*.coffee' - 'static/**/*.coffee' - ] - dest: appDir - ext: '.js' - - lessConfig = - options: - paths: [ - 'static/variables' - 'static' - ] - glob_to_multiple: - expand: true - src: [ - 'static/**/*.less' - ] - dest: appDir - ext: '.css' - - prebuildLessConfig = - src: [ - 'static/**/*.less' - ] - - csonConfig = - options: - rootObject: false - cachePath: path.join(home, '.nylas', 'compile-cache', 'grunt-cson') - - glob_to_multiple: - expand: true - src: [ - 'menus/*.cson' - 'keymaps/*.cson' - 'keymaps/templates/*.cson' - 'static/**/*.cson' - ] - dest: appDir - ext: '.json' - - pegConfig = - glob_to_multiple: - expand: true - src: ['src/**/*.pegjs'] - dest: appDir - ext: '.js' - - for folder in ['node_modules', 'internal_packages'] - for child in fs.readdirSync(folder) when child isnt '.bin' - directory = path.join(folder, child) - metadataPath = path.join(directory, 'package.json') - continue unless grunt.file.isFile(metadataPath) - - {engines, theme} = grunt.file.readJSON(metadataPath) - if engines?.atom? - coffeeConfig.glob_to_multiple.src.push("#{directory}/**/*.coffee") - lessConfig.glob_to_multiple.src.push("#{directory}/**/*.less") - prebuildLessConfig.src.push("#{directory}/**/*.less") unless theme - csonConfig.glob_to_multiple.src.push("#{directory}/**/*.cson") - pegConfig.glob_to_multiple.src.push("#{directory}/**/*.pegjs") - - grunt.initConfig - pkg: grunt.file.readJSON('package.json') - - atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir} - - docsOutputDir: 'docs/output' - - coffee: coffeeConfig - - cjsx: cjsxConfig - - less: lessConfig - - 'prebuild-less': prebuildLessConfig - - cson: csonConfig - - peg: pegConfig - - nylaslint: - src: [ - 'internal_packages/**/*.cjsx' - 'internal_packages/**/*.coffee' - 'dot-nylas/**/*.coffee' - 'src/**/*.coffee' - 'src/**/*.cjsx' - 'spec/**/*.cjsx' - 'spec/**/*.coffee' - ] - - coffeelint: - options: - configFile: 'build/config/coffeelint.json' - src: [ - 'internal_packages/**/*.cjsx' - 'internal_packages/**/*.coffee' - 'dot-nylas/**/*.coffee' - 'src/**/*.coffee' - 'src/**/*.cjsx' - ] - build: [ - 'build/tasks/**/*.coffee' - 'build/Gruntfile.coffee' - ] - test: [ - 'spec/**/*.cjsx' - 'spec/**/*.coffee' - ] - static: [ - 'static/**/*.coffee' - 'static/**/*.cjsx' - ] - target: - grunt.option("target")?.split(" ") or [] - - csslint: - options: - 'adjoining-classes': false - 'duplicate-background-images': false - 'box-model': false - 'box-sizing': false - 'bulletproof-font-face': false - 'compatible-vendor-prefixes': false - 'display-property-grouping': false - 'fallback-colors': false - 'font-sizes': false - 'gradients': false - 'ids': false - 'important': false - 'known-properties': false - 'outline-none': false - 'overqualified-elements': false - 'qualified-headings': false - 'unique-headings': false - 'universal-selector': false - 'vendor-prefix': false - 'duplicate-properties': false # doesn't place nice with mixins - src: [ - 'static/**/*.css' - ] - - lesslint: - src: [ - 'internal_packages/**/*.less' - 'dot-nylas/**/*.less' - 'static/**/*.less' - ] - options: - imports: ['variables/*.less'] - - markdown: - guides: - files: [ - expand: true - cwd: 'docs' - src: '**/*.md' - dest: 'docs/output/' - ext: '.html' - ] - options: - template: 'docs/template.jst' - templateContext: - title: "Documentation" - tag: "v#{major}.#{minor}" - markdownOptions: - gfm: true - preCompile: (src, context) -> - fm = require 'json-front-matter' - parsed = fm.parse(src) - _.extend(context, parsed.attributes) - parsed.body - - 'download-electron': - version: packageJson.electronVersion - outputDir: 'electron' - downloadDir: electronDownloadDir - rebuild: true # rebuild native modules after electron is updated - token: process.env.NYLAS_ACCESS_TOKEN - - 'create-windows-installer': - appDirectory: shellAppDir - outputDirectory: path.join(buildDir, 'installer') - authors: 'Nylas Inc.' - loadingGif: path.resolve(__dirname, 'resources', 'win', 'loading.gif') - iconUrl: 'http://edgehill.s3.amazonaws.com/static/nylas.ico' - setupIcon: path.resolve(__dirname, 'resources', 'win', 'nylas.ico') - - shell: - 'kill-atom': - command: killCommand - options: - stdout: false - stderr: false - failOnError: false - - grunt.registerTask('compile', ['coffee', 'cjsx', 'prebuild-less', 'cson', 'peg']) - grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint', 'nylaslint']) - grunt.registerTask('test', ['shell:kill-atom', 'run-edgehill-specs']) - grunt.registerTask('docs', ['build-docs', 'render-docs']) - - ciTasks = ['output-disk-space', 'download-electron', 'build'] - ciTasks.push('dump-symbols') if process.platform isnt 'win32' - ciTasks.push('set-version', 'lint', 'generate-asar') - ciTasks.push('mkdeb') if process.platform is 'linux' - ciTasks.push('test') if process.platform is 'darwin' - ciTasks.push('codesign') unless process.env.TRAVIS - ciTasks.push('mkdmg') if process.platform is 'darwin' and not process.env.TRAVIS - ciTasks.push('create-windows-installer') if process.platform is 'win32' and not process.env.TRAVIS - # ciTasks.push('publish-docs') if process.platform is 'darwin' and not process.env.TRAVIS - ciTasks.push('publish-nylas-build') if process.platform is 'darwin' and not process.env.TRAVIS - grunt.registerTask('ci', ciTasks) - - defaultTasks = ['download-electron', 'build', 'set-version', 'generate-asar'] - # We don't run `install` on linux because you need to run `sudo`. - # See docs/build-instructions/linux.md - # `sudo script/grunt install` - defaultTasks.push 'mkdmg' if process.platform is 'darwin' - defaultTasks.push 'install' unless process.platform is 'linux' - grunt.registerTask('default', defaultTasks) +fs = require 'fs' +path = require 'path' +os = require 'os' + +# This is the main Gruntfile that manages building N1 distributions. +# The reason it's inisde of the build/ folder is so everything can be +# compiled against Node's v8 headers instead of Atom's v8 headers. All +# packages in the root-level node_modules are compiled against Atom's v8 +# headers. +# +# Some useful grunt options are: +# --install-dir +# --build-dir +# +# To keep the various directories straight, here are what the various +# directories might look like on MacOS +# +# tmpDir: /var/folders/xl/_qdlmc512sb6cpqryy_2tzzw0000gn/T/ (aka /tmp) +# +# buildDir = /tmp/nylas-build +# shellAppDir = /tmp/nylas-build/Nylas.app +# contentsDir = /tmp/nylas-build/Nylas.app/Contents +# appDir = /tmp/nylas-build/Nylas.app/Contents/Resources/app +# +# installDir = /Applications/Nylas.app +# +# And on Linux: +# +# tmpDir: /tmp/ +# +# buildDir = /tmp/nylas-build +# shellAppDir = /tmp/nylas-build/Nylas +# contentsDir = /tmp/nylas-build/Nylas +# appDir = /tmp/nylas-build/Nylas/resources/app +# +# installDir = /usr/local OR $INSTALL_PREFIX +# binDir = /usr/local/bin +# shareDir = /usr/local/share/nylas + +# Add support for obselete APIs of vm module so we can make some third-party +# modules work under node v0.11.x. +require 'vm-compatibility-layer' + +_ = require 'underscore' + +packageJson = require '../package.json' + +# Shim harmony collections in case grunt was invoked without harmony +# collections enabled +_.extend(global, require('harmony-collections')) unless global.WeakMap? + +module.exports = (grunt) -> + grunt.loadNpmTasks('grunt-coffeelint-cjsx') + grunt.loadNpmTasks('grunt-lesslint') + grunt.loadNpmTasks('grunt-cson') + grunt.loadNpmTasks('grunt-contrib-csslint') + grunt.loadNpmTasks('grunt-coffee-react') + grunt.loadNpmTasks('grunt-contrib-coffee') + grunt.loadNpmTasks('grunt-contrib-less') + grunt.loadNpmTasks('grunt-shell') + grunt.loadNpmTasks('grunt-markdown') + grunt.loadNpmTasks('grunt-download-electron') + grunt.loadNpmTasks('grunt-electron-installer') + grunt.loadNpmTasks('grunt-peg') + grunt.loadTasks('tasks') + + # This allows all subsequent paths to the relative to the root of the repo + grunt.file.setBase(path.resolve('..')) + + # Commented out because it was causing normal grunt message to dissapear + # for some reason. + # if not grunt.option('verbose') + # grunt.log.writeln = (args...) -> grunt.log + # grunt.log.write = (args...) -> grunt.log + + [major, minor, patch] = packageJson.version.split('.') + tmpDir = os.tmpdir() + appName = if process.platform is 'darwin' then 'Nylas.app' else 'Nylas' + buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'nylas-build') + buildDir = path.resolve(buildDir) + installDir = grunt.option('install-dir') + + home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME + electronDownloadDir = path.join(home, '.nylas', 'electron') + + symbolsDir = path.join(buildDir, 'Atom.breakpad.syms') + shellAppDir = path.join(buildDir, appName) + if process.platform is 'win32' + contentsDir = shellAppDir + appDir = path.join(shellAppDir, 'resources', 'app') + installDir ?= path.join(process.env.ProgramFiles, appName) + killCommand = 'taskkill /F /IM nylas.exe' + else if process.platform is 'darwin' + contentsDir = path.join(shellAppDir, 'Contents') + appDir = path.join(contentsDir, 'Resources', 'app') + installDir ?= path.join('/Applications', appName) + killCommand = 'pkill -9 Nylas' + else + contentsDir = shellAppDir + appDir = path.join(shellAppDir, 'resources', 'app') + installDir ?= process.env.INSTALL_PREFIX ? '/usr/local' + killCommand = 'pkill -9 nylas' + + installDir = path.resolve(installDir) + + cjsxConfig = + glob_to_multiple: + expand: true + src: [ + 'src/**/*.cjsx' + 'internal_packages/**/*.cjsx' + ] + dest: appDir + ext: '.js' + + coffeeConfig = + glob_to_multiple: + expand: true + src: [ + 'src/**/*.coffee' + 'internal_packages/**/*.coffee' + 'static/**/*.coffee' + ] + dest: appDir + ext: '.js' + + lessConfig = + options: + paths: [ + 'static/variables' + 'static' + ] + glob_to_multiple: + expand: true + src: [ + 'static/**/*.less' + ] + dest: appDir + ext: '.css' + + prebuildLessConfig = + src: [ + 'static/**/*.less' + ] + + csonConfig = + options: + rootObject: false + cachePath: path.join(home, '.nylas', 'compile-cache', 'grunt-cson') + + glob_to_multiple: + expand: true + src: [ + 'menus/*.cson' + 'keymaps/*.cson' + 'keymaps/templates/*.cson' + 'static/**/*.cson' + ] + dest: appDir + ext: '.json' + + pegConfig = + glob_to_multiple: + expand: true + src: ['src/**/*.pegjs'] + dest: appDir + ext: '.js' + + for folder in ['node_modules', 'internal_packages'] + for child in fs.readdirSync(folder) when child isnt '.bin' + directory = path.join(folder, child) + metadataPath = path.join(directory, 'package.json') + continue unless grunt.file.isFile(metadataPath) + + {engines, theme} = grunt.file.readJSON(metadataPath) + if engines?.atom? + coffeeConfig.glob_to_multiple.src.push("#{directory}/**/*.coffee") + lessConfig.glob_to_multiple.src.push("#{directory}/**/*.less") + prebuildLessConfig.src.push("#{directory}/**/*.less") unless theme + csonConfig.glob_to_multiple.src.push("#{directory}/**/*.cson") + pegConfig.glob_to_multiple.src.push("#{directory}/**/*.pegjs") + + grunt.initConfig + pkg: grunt.file.readJSON('package.json') + + atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir} + + docsOutputDir: 'docs/output' + + coffee: coffeeConfig + + cjsx: cjsxConfig + + less: lessConfig + + 'prebuild-less': prebuildLessConfig + + cson: csonConfig + + peg: pegConfig + + nylaslint: + src: [ + 'internal_packages/**/*.cjsx' + 'internal_packages/**/*.coffee' + 'dot-nylas/**/*.coffee' + 'src/**/*.coffee' + 'src/**/*.cjsx' + 'spec/**/*.cjsx' + 'spec/**/*.coffee' + ] + + coffeelint: + options: + configFile: 'build/config/coffeelint.json' + src: [ + 'internal_packages/**/*.cjsx' + 'internal_packages/**/*.coffee' + 'dot-nylas/**/*.coffee' + 'src/**/*.coffee' + 'src/**/*.cjsx' + ] + build: [ + 'build/tasks/**/*.coffee' + 'build/Gruntfile.coffee' + ] + test: [ + 'spec/**/*.cjsx' + 'spec/**/*.coffee' + ] + static: [ + 'static/**/*.coffee' + 'static/**/*.cjsx' + ] + target: + grunt.option("target")?.split(" ") or [] + + csslint: + options: + 'adjoining-classes': false + 'duplicate-background-images': false + 'box-model': false + 'box-sizing': false + 'bulletproof-font-face': false + 'compatible-vendor-prefixes': false + 'display-property-grouping': false + 'fallback-colors': false + 'font-sizes': false + 'gradients': false + 'ids': false + 'important': false + 'known-properties': false + 'outline-none': false + 'overqualified-elements': false + 'qualified-headings': false + 'unique-headings': false + 'universal-selector': false + 'vendor-prefix': false + 'duplicate-properties': false # doesn't place nice with mixins + src: [ + 'static/**/*.css' + ] + + lesslint: + src: [ + 'internal_packages/**/*.less' + 'dot-nylas/**/*.less' + 'static/**/*.less' + ] + options: + imports: ['variables/*.less'] + + markdown: + guides: + files: [ + expand: true + cwd: 'docs' + src: '**/*.md' + dest: 'docs/output/' + ext: '.html' + ] + options: + template: 'docs/template.jst' + templateContext: + title: "Documentation" + tag: "v#{major}.#{minor}" + markdownOptions: + gfm: true + preCompile: (src, context) -> + fm = require 'json-front-matter' + parsed = fm.parse(src) + _.extend(context, parsed.attributes) + parsed.body + + 'download-electron': + version: packageJson.electronVersion + outputDir: 'electron' + downloadDir: electronDownloadDir + rebuild: true # rebuild native modules after electron is updated + token: process.env.NYLAS_ACCESS_TOKEN + + 'create-windows-installer': + installer: + appDirectory: shellAppDir + outputDirectory: path.join(buildDir, 'installer') + authors: 'Nylas Inc.' + loadingGif: path.resolve(__dirname, 'resources', 'win', 'loading.gif') + iconUrl: 'http://edgehill.s3.amazonaws.com/static/nylas.ico' + setupIcon: path.resolve(__dirname, 'resources', 'win', 'nylas.ico') + certificateFile: process.env.CERTIFICATE_FILE + certificatePassword: process.env.CERTIFICATE_PASSWORD + exe: 'nylas.exe' + + shell: + 'kill-atom': + command: killCommand + options: + stdout: false + stderr: false + failOnError: false + + grunt.registerTask('compile', ['coffee', 'cjsx', 'prebuild-less', 'cson', 'peg']) + grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint', 'nylaslint']) + grunt.registerTask('test', ['shell:kill-atom', 'run-edgehill-specs']) + grunt.registerTask('docs', ['build-docs', 'render-docs']) + + ciTasks = ['output-disk-space', 'download-electron', 'build'] + ciTasks.push('dump-symbols') if process.platform isnt 'win32' + ciTasks.push('set-version', 'lint', 'generate-asar') + ciTasks.push('mkdeb') if process.platform is 'linux' + ciTasks.push('test') if process.platform is 'darwin' + ciTasks.push('codesign') unless process.env.TRAVIS + ciTasks.push('mkdmg') if process.platform is 'darwin' and not process.env.TRAVIS + ciTasks.push('create-windows-installer:installer') if process.platform is 'win32' and not process.env.TRAVIS + # ciTasks.push('publish-docs') if process.platform is 'darwin' and not process.env.TRAVIS + ciTasks.push('publish-nylas-build') if process.platform in ['darwin', 'win32'] and not process.env.TRAVIS + grunt.registerTask('ci', ciTasks) + + defaultTasks = ['download-electron', 'build', 'set-version', 'generate-asar'] + # We don't run `install` on linux because you need to run `sudo`. + # See docs/build-instructions/linux.md + # `sudo script/grunt install` + defaultTasks.push 'mkdmg' if process.platform is 'darwin' + defaultTasks.push 'install' unless process.platform is 'linux' + grunt.registerTask('default', defaultTasks) diff --git a/build/resources/win/atom.sh b/build/resources/win/N1.sh similarity index 100% rename from build/resources/win/atom.sh rename to build/resources/win/N1.sh diff --git a/build/tasks/publish-nylas-build-task.coffee b/build/tasks/publish-nylas-build-task.coffee index 957f01e94..fa3fc8ec2 100644 --- a/build/tasks/publish-nylas-build-task.coffee +++ b/build/tasks/publish-nylas-build-task.coffee @@ -1,166 +1,141 @@ -_ = require 'underscore' -s3 = require 's3' -fs = require 'fs' -path = require 'path' -request = require 'request' -Promise = require 'bluebird' - -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" - - defaultPublishPath = -> path.join(process.env.HOME, "Downloads") - - publishPath = -> - process.env.PUBLISH_PATH ? defaultPublishPath() - - runEmailIntegrationTest = (s3Client) -> - 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] - , (error) -> - if error - reject(error) - return - resolve() - - postToSlack = (msg) -> - new Promise (resolve, reject) -> - url = "https://hooks.slack.com/services/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" - request.post - url: url - json: - username: "Edgehill Builds" - text: msg - , (err, httpResponse, body) -> - if err then reject(err) - else resolve() - - # Returns a properly bound s3obj - prepareS3 = -> - awsKey = process.env.AWS_ACCESS_KEY_ID ? "" - awsSecret = process.env.AWS_SECRET_ACCESS_KEY ? "" - - if awsKey.length is 0 - grunt.log.error "Please set the AWS_ACCESS_KEY_ID environment variable" - return false - if awsSecret.length is 0 - grunt.log.error "Please set the AWS_SECRET_ACCESS_KEY environment variable" - return false - - s3Client = s3.createClient - s3Options: - accessKeyId: process.env.AWS_ACCESS_KEY_ID - scretAccessKey: process.env.AWS_SECRET_ACCESS_KEY - - return s3Client - - uploadFile = (s3Client, localSource, destName) -> - grunt.log.writeln ">> Uploading #{localSource} to S3…" - - write = grunt.log.writeln - ext = path.extname(destName) - lastPc = 0 - - new Promise (resolve, reject) -> - uploader = s3Client.uploadFile - localFile: localSource - s3Params: - Key: destName - ACL: "public-read" - Bucket: "edgehill" - ContentDisposition:"attachment; filename=\"N1#{ext}\"" - - uploader.on "error", (err) -> - reject(err) - uploader.on "progress", -> - pc = Math.round(uploader.progressAmount / uploader.progressTotal * 100.0) - if pc isnt lastPc - lastPc = pc - write(">> Uploading #{destName} #{pc}%") - uploader.on "end", (data) -> - resolve(data) - - uploadDMGToS3 = (s3Client) -> - destName = "#{process.platform}/Edgehill_#{getVersion()}.dmg" - dmgPath = path.join(grunt.config.get('atom.buildDir'), dmgName()) - new Promise (resolve, reject) -> - uploadFile(s3Client, dmgPath, destName) - .then (data) -> - grunt.log.ok "Uploaded DMG to #{data.Location}" - msg = "New Mac Edgehill build! <#{data.Location}|#{destName}>" - postToSlack(msg).then -> - resolve(data) - .catch(reject) - .catch(reject) - - uploadZipToS3 = (s3Client) -> - destName = "#{process.platform}/Edgehill_#{getVersion()}.zip" - buildDir = grunt.config.get('atom.buildDir') - - grunt.log.writeln ">> Creating zip file…" - new Promise (resolve, reject) -> - appToZip = path.join(buildDir, appName()) - zipPath = path.join(buildDir, zipName()) - - rm zipPath - - orig = process.cwd() - process.chdir(buildDir) - - spawn - cmd: "zip" - args: ["-9", "-y", "-r", zipName(), appName()] - , (error) -> - if error - process.chdir(orig) - reject(error) - return - - grunt.log.writeln ">> Created #{zipPath}" - grunt.log.writeln ">> Uploading…" - uploadFile(s3Client, zipPath, destName) - .then (data) -> - grunt.log.ok "Uploaded zip to #{data.Location}" - process.chdir(orig) - resolve(data) - .catch (err) -> - process.chdir(orig) - reject(err) - - grunt.registerTask "publish-nylas-build", "Publish Nylas build", -> - done = @async() - - runEmailIntegrationTest().then -> - dmgPath = path.join(grunt.config.get('atom.buildDir'), dmgName()) - - if not fs.existsSync dmgPath - grunt.log.error "DMG does not exist at #{dmgPath}. Run script/grunt build first." - cp dmgPath, path.join(publishPath(), dmgName()) - - grunt.log.ok "Copied DMG to #{publishPath()}" - if publishPath() is defaultPublishPath() - grunt.log.ok "Set the PUBLISH_PATH environment variable to change where Edgehill copies the built file to." - - s3Client = prepareS3() - if s3Client - Promise.all([uploadDMGToS3(s3Client), uploadZipToS3(s3Client)]) - .then -> - done() - .catch (err) -> - grunt.log.error(err) - return false - else - return false +_ = require 'underscore' +s3 = require 's3' +fs = require 'fs' +path = require 'path' +request = require 'request' +Promise = require 'bluebird' + +s3Client = 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" + + 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] + , (error) -> + if error + reject(error) + return + resolve() + + postToSlack = (msg) -> + new Promise (resolve, reject) -> + url = "https://hooks.slack.com/services/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" + request.post + url: url + json: + username: "Edgehill Builds" + text: msg + , (err, httpResponse, body) -> + if err then reject(err) + else resolve() + + put = (localSource, destName) -> + grunt.log.writeln ">> Uploading #{localSource} to S3…" + + write = grunt.log.writeln + ext = path.extname(destName) + lastPc = 0 + + new Promise (resolve, reject) -> + uploader = s3Client.uploadFile + localFile: localSource + s3Params: + Key: destName + ACL: "public-read" + Bucket: "edgehill" + ContentDisposition:"attachment; filename=\"N1#{ext}\"" + + uploader.on "error", (err) -> + reject(err) + uploader.on "progress", -> + pc = Math.round(uploader.progressAmount / uploader.progressTotal * 100.0) + if pc isnt lastPc + lastPc = pc + write(">> Uploading #{destName} #{pc}%") + uploader.on "end", (data) -> + resolve(data) + + uploadToS3 = (filename, key) -> + filepath = path.join(grunt.config.get('atom.buildDir'), filename) + + grunt.log.writeln ">> Uploading #{filename} to #{key}…" + put(filepath, key).then (data) -> + msg = "N1 release asset uploaded: <#{data.Location}|#{filename}>" + postToSlack(msg).then -> + Promise.resolve(data) + + uploadZipToS3 = (filename, key) -> + filepath = path.join(grunt.config.get('atom.buildDir'), filename) + + grunt.log.writeln ">> Creating zip file…" + new Promise (resolve, reject) -> + zipFilepath = filepath + ".zip" + rm(zipPath) + orig = process.cwd() + process.chdir(buildDir) + + spawn + cmd: "zip" + args: ["-9", "-y", "-r", zipFilepath, filepath] + , (error) -> + process.chdir(orig) + if error + reject(error) + return + + grunt.log.writeln ">> Created #{zipPath}" + grunt.log.writeln ">> Uploading…" + uploadToS3(zipFilepath, key).then(resolve).catch(reject) + + grunt.registerTask "publish-nylas-build", "Publish Nylas build", -> + awsKey = process.env.AWS_ACCESS_KEY_ID ? "" + awsSecret = process.env.AWS_SECRET_ACCESS_KEY ? "" + + if awsKey.length is 0 + grunt.log.error "Please set the AWS_ACCESS_KEY_ID environment variable" + return false + if awsSecret.length is 0 + grunt.log.error "Please set the AWS_SECRET_ACCESS_KEY environment variable" + return false + + s3Client = s3.createClient + s3Options: + accessKeyId: process.env.AWS_ACCESS_KEY_ID + scretAccessKey: process.env.AWS_SECRET_ACCESS_KEY + + 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()}") + + Promise.all(uploadPromises).then(done).catch (err) -> + grunt.log.error(err) + return false diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index d86481484..8b5d505da 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -1,57 +1,57 @@ -fs = require 'fs' -path = require 'path' - -module.exports = (grunt) -> - {spawn} = require('./task-helpers')(grunt) - - getVersion = (callback) -> - onBuildMachine = process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master' - inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) - {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) - if onBuildMachine or not inRepository - callback(null, version) - else - cmd = 'git' - args = ['rev-parse', '--short', 'HEAD'] - spawn {cmd, args}, (error, {stdout}={}, code) -> - commitHash = stdout?.trim?() - combinedVersion = "#{version}-#{commitHash}" - callback(error, combinedVersion) - - grunt.registerTask 'set-version', 'Set the version in the plist and package.json', -> - done = @async() - - getVersion (error, version) -> - if error? - done(error) - return - - appDir = grunt.config.get('atom.appDir') - - # Replace version field of package.json. - packageJsonPath = path.join(appDir, 'package.json') - packageJson = require(packageJsonPath) - packageJson.version = version - packageJsonString = JSON.stringify(packageJson) - fs.writeFileSync(packageJsonPath, packageJsonString) - - if process.platform is 'darwin' - cmd = 'script/set-version' - args = [grunt.config.get('atom.buildDir'), version] - spawn {cmd, args}, (error, result, code) -> done(error) - - else if process.platform is 'win32' - shellAppDir = grunt.config.get('atom.shellAppDir') - shellExePath = path.join(shellAppDir, 'nylas.exe') - - strings = - CompanyName: 'Nylas, Inc.' - FileDescription: 'Nylas' - LegalCopyright: 'Copyright (C) 2014-2015 Nylas, Inc. All rights reserved' - ProductName: 'Nylas' - ProductVersion: version - - rcedit = require('rcedit') - rcedit(shellExePath, {'version-string': strings}, done) - else - done() +fs = require 'fs' +path = require 'path' + +module.exports = (grunt) -> + {spawn} = require('./task-helpers')(grunt) + + getVersion = (callback) -> + onBuildMachine = true + inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) + {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) + if onBuildMachine or not inRepository + callback(null, version) + else + cmd = 'git' + args = ['rev-parse', '--short', 'HEAD'] + spawn {cmd, args}, (error, {stdout}={}, code) -> + commitHash = stdout?.trim?() + combinedVersion = "#{version}-#{commitHash}" + callback(error, combinedVersion) + + grunt.registerTask 'set-version', 'Set the version in the plist and package.json', -> + done = @async() + + getVersion (error, version) -> + if error? + done(error) + return + + appDir = grunt.config.get('atom.appDir') + + # Replace version field of package.json. + packageJsonPath = path.join(appDir, 'package.json') + packageJson = require(packageJsonPath) + packageJson.version = version + packageJsonString = JSON.stringify(packageJson) + fs.writeFileSync(packageJsonPath, packageJsonString) + + if process.platform is 'darwin' + cmd = 'script/set-version' + args = [grunt.config.get('atom.buildDir'), version] + spawn {cmd, args}, (error, result, code) -> done(error) + + else if process.platform is 'win32' + shellAppDir = grunt.config.get('atom.shellAppDir') + shellExePath = path.join(shellAppDir, 'nylas.exe') + + strings = + CompanyName: 'Nylas, Inc.' + FileDescription: 'Nylas' + LegalCopyright: 'Copyright (C) 2014-2015 Nylas, Inc. All rights reserved' + ProductName: 'Nylas' + ProductVersion: version + + rcedit = require('rcedit') + rcedit(shellExePath, {'version-string': strings}, done) + else + done()