From c0b6575da0da1c901c915d772953f1f138b81037 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Fri, 1 Sep 2017 00:28:10 -0500 Subject: [PATCH] feat: build-target options --- .travis.yml | 7 +++ appveyor.yml | 4 +- circle.yml | 8 ---- package-lock.json | 108 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + src/compiler.ts | 3 +- src/nexe.ts | 10 ++++- src/options.ts | 21 ++++++--- tasks/build.ts | 56 +++++++++++++----------- tasks/ci.ts | 46 ++++++++++---------- tasks/docker.ts | 32 ++++++++++++++ 11 files changed, 228 insertions(+), 69 deletions(-) create mode 100644 .travis.yml create mode 100644 tasks/docker.ts diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f3c92a8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: +- '6' +script: npm run nexe-build +env: + global: + secure: LyC6djYqPfPKz5gHILES9JmSRxQ+ntKOcoaZNM5WID0+gogUoXZBhcmmtvq9RnMpFZN3pYujY6LB5iy7QS2seGjg+feyewNKI30yIK6N9ulJyZZKmrJVDdRx4wvl8YVTkttjcJFkanDGa6zRvFfFDKx/iIdcWLEpnqR/WO1ppf8= diff --git a/appveyor.yml b/appveyor.yml index 75df911..ef4eceb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,9 +2,9 @@ environment: CIRCLE_TOKEN: secure: TQKcepXmTzCNt4+tUBtYpwEQkdSPwFr9A8ugtoMhNbKu/SW1WM1EpjEu6kYXxpQ4 TRAVIS_TOKEN: - secure: IwsFkKeSwogeIs7gbEhpIkRbrziWdGq0eCSMkAVCgBY= + secure: tR7HXYv3x97q90uvPrjUxKZh7R1+uqKct0HdEcqTbsg= GITHUB_TOKEN: - secure: Sx2cy8b/djm/3wSYMSKK0fxbZ0mnFI09rLCHXqjjzwhunfEkug7xILEl14wVrHUS + secure: 3wuEGJsppSKFvdwhp3jprUA9Zkc3WINlc/9oFXjhAR6J05lYMXP7Fl7lXTKpkGZx branches: except: - master diff --git a/circle.yml b/circle.yml index 6dc1ead..3c14fff 100644 --- a/circle.yml +++ b/circle.yml @@ -1,11 +1,3 @@ -# machine: -# environment: -# NODE_VERSION: 6 test: override: - npm run nexe-build -# deployment: -# target: -# branch: bundle-wip -# - npm run nexe-build - diff --git a/package-lock.json b/package-lock.json index 43e072f..15107c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,15 @@ "integrity": "sha1-ox10JBprHtu5c8822XooloNKUfk=", "dev": true }, + "@types/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@types/execa/-/execa-0.7.0.tgz", + "integrity": "sha512-jBDAaCXX9nDnucbfs5tVojSLMRlxa+Dqp1L9OERn9MyOTIEOILRq2ATsu2dvn9IXoJp2NZwK5SVUUuZsq1my2g==", + "dev": true, + "requires": { + "@types/node": "8.0.25" + } + }, "@types/glob": { "version": "5.0.32", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.32.tgz", @@ -525,6 +534,17 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, "cryptiles": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", @@ -802,6 +822,21 @@ "merge": "1.2.0" } }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -2264,6 +2299,12 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", @@ -2470,6 +2511,16 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, "make-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", @@ -2703,6 +2754,15 @@ "pify": "3.0.0" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", @@ -2876,6 +2936,12 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -3006,6 +3072,12 @@ "ipaddr.js": "1.4.0" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -3271,6 +3343,21 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shorthash": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/shorthash/-/shorthash-0.0.2.tgz", @@ -3405,6 +3492,12 @@ "is-natural-number": "4.0.1" } }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -3679,6 +3772,15 @@ "minimist": "1.2.0" } }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -3703,6 +3805,12 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, "yauzl": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", diff --git a/package.json b/package.json index f6eb2a2..a3fdd20 100644 --- a/package.json +++ b/package.json @@ -46,12 +46,14 @@ "devDependencies": { "@types/bluebird": "^3.5.8", "@types/chalk": "^0.4.31", + "@types/execa": "0.7.0", "@types/globby": "^0.6.0", "@types/minimist": "^1.2.0", "@types/mkdirp": "^0.3.29", "@types/ora": "^0.3.31", "@types/pify": "0.0.28", "@types/rimraf": "0.0.28", + "execa": "0.8.0", "got": "^7.1.0", "mocha": "^3.2.0", "prettier": "^1.6.1", diff --git a/src/compiler.ts b/src/compiler.ts index ca310e2..2564272 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -171,11 +171,12 @@ export class NexeCompiler { async compileAsync(target: NexeTarget) { const step = (this.compileStep = this.log.step('Compiling result')) + const build = this.options.build const location = this._getNodeExecutableLocation(target) let binary = (await pathExistsAsync(location)) ? createReadStream(location) : null const header = this._generateHeader() - if (target && !binary) { + if (target && !build) { binary = await this._fetchPrebuiltBinaryAsync(target) } diff --git a/src/nexe.ts b/src/nexe.ts index a0ca53f..2a2291d 100644 --- a/src/nexe.ts +++ b/src/nexe.ts @@ -1,7 +1,13 @@ import { compose, PromiseConfig, Middleware } from 'app-builder' import resource from './steps/resource' import { NexeCompiler } from './compiler' -import { argv, normalizeOptionsAsync, NexeOptions, NexePatch } from './options' +import { + argv, + nexeVersion as version, + normalizeOptionsAsync, + NexeOptions, + NexePatch +} from './options' import cli from './steps/cli' import bundle from './bundling/fuse' import download from './steps/download' @@ -40,4 +46,4 @@ async function compile( : nexe(compiler) } -export { argv, compile } +export { argv, compile, version } diff --git a/src/options.ts b/src/options.ts index 6f8d478..74610c7 100644 --- a/src/options.ts +++ b/src/options.ts @@ -58,7 +58,7 @@ const defaults = { configure: [], make: [], targets: [], - vcBuild: isWindows ? ['nosign', 'release', process.arch] : [], + vcBuild: isWindows ? ['nosign', 'release'] : [], enableNodeCli: false, compress: false, build: false, @@ -201,14 +201,21 @@ function normalizeOptionsAsync(input?: Partial): Promise { if (typeof x === 'string') { return require(x).default diff --git a/tasks/build.ts b/tasks/build.ts index 41ac791..c1ae17d 100644 --- a/tasks/build.ts +++ b/tasks/build.ts @@ -1,22 +1,34 @@ -import { compile } from '../src/nexe' +import * as nexe from '../src/nexe' import { getUnBuiltReleases, getLatestGitRelease } from '../src/releases' import * as ci from './ci' +import { runAlpineBuild } from './docker' import { getTarget } from '../src/target' import { pathExistsAsync, statAsync, readFileAsync, execFileAsync } from '../src/util' import got = require('got') const env = process.env, - branchName = env.CIRCLE_BRANCH || env.APPVEYOR_REPO_BRANCH || 'master', + branchName = env.CIRCLE_BRANCH || env.APPVEYOR_REPO_BRANCH || env.TRAVIS_BRANCH || '', isScheduled = Boolean(env.APPVEYOR_SCHEDULED_BUILD || env.NEXE_TRIGGERED), isLinux = Boolean(env.TRAVIS), isWindows = Boolean(env.APPVEYOR), isMac = Boolean(env.CIRCLECI), - isPullRequest = Boolean(env.CIRCLE_PR_NUMBER) || Boolean(env.APPVEYOR_PULL_REQUEST_NUMBER), + isPullRequest = Boolean(env.CIRCLE_PR_NUMBER) + || Boolean(env.APPVEYOR_PULL_REQUEST_NUMBER) + || Boolean(env.TRAVIS_PULL_REQUEST_BRANCH), headers = { 'Authorization': 'token ' + env.GITHUB_TOKEN } +if (require.main === module) { + if (!isPullRequest) { + build().catch(x => { + console.error(x) + process.exit(1) + }) + } +} + async function build () { if (isScheduled) { const releases = await getUnBuiltReleases({ headers }) @@ -28,7 +40,7 @@ async function build () { const linuxOrAlpine = releases.find(x => x.platform === 'linux' || x.platform === 'alpine') if (linuxOrAlpine) { - await ci.triggerDockerBuild(linuxOrAlpine) + await ci.triggerDockerBuild(linuxOrAlpine, branchName) } if (macBuild) { await ci.triggerMacBuild(macBuild, branchName) @@ -45,23 +57,19 @@ async function build () { options = { empty: true, build: true, - configure: [], - make: [target.arch], - version: target.version, + target, //FIXME output } - if (isWindows) { - await compile(options) + + const stop = keepalive() + if (target.platform === 'alpine') { + await runAlpineBuild(target, nexe.version.split('.')[0]) + } else { + await nexe.compile(options) } - - if (isMac) { - const timeout = setInterval(() => console.log('Building...'), 300 * 1000) - await compile({...options, make: [], configure: ['--dest-cpu=x64']}) - clearInterval(timeout) - } - - if (isLinux) {} - + stop() + + if (await pathExistsAsync(output)) { await assertNexeBinary(output) const gitRelease = await getLatestGitRelease({ headers }) @@ -78,6 +86,11 @@ async function build () { } } +function keepalive () { + const keepalive = setInterval(() => console.log('Building...'), 300 * 1000) + return () => clearInterval(keepalive) +} + function assertNexeBinary (file: string) { return execFileAsync(file).catch(e => { if (e && e.stack && e.stack.includes('Invalid Nexe binary')) { @@ -86,10 +99,3 @@ function assertNexeBinary (file: string) { throw e }) } - -if (require.main === module) { - build().catch(x => { - console.error(x) - process.exit(1) - }) -} diff --git a/tasks/ci.ts b/tasks/ci.ts index fd6c817..e4ddd7c 100644 --- a/tasks/ci.ts +++ b/tasks/ci.ts @@ -3,28 +3,27 @@ import got = require('got') import * as assert from 'assert' const { env } = process -export function triggerDockerBuild(release: NexeTarget) { - return Promise.resolve() - // assert.ok(env.TRAVIS_TOKEN) - // const travis = `https://api.travis-ci.org/repo/nexe/nexe/requests` - // return got(travis, { - // json: true, - // body: { - // request: { - // branch: 'master', - // config: { - // merge_mode: 'deep_merge', - // env: { - // NEXE_VERSION: release - // } - // } - // } - // }, - // headers: { - // 'Travis-API-Version': '3', - // 'Authorization': `token ${env.TRAVIS_TOKEN}` - // } - // }) +export function triggerDockerBuild(release: NexeTarget, branch: string) { + assert.ok(env.TRAVIS_TOKEN) + const travis = `https://api.travis-ci.org/repo/nexe%2Fnexe/requests` + return got(travis, { + json: true, + body: { + request: { + branch: branch, + config: { + merge_mode: 'deep_merge', + env: { + NEXE_VERSION: release + } + } + } + }, + headers: { + 'Travis-API-Version': '3', + 'Authorization': `token ${env.TRAVIS_TOKEN}` + } + }) } export function triggerMacBuild (release: NexeTarget, branch: string) { @@ -34,8 +33,7 @@ export function triggerMacBuild (release: NexeTarget, branch: string) { json: true, body: { build_parameters: { - NEXE_VERSION: release.toString(), - GITHUB_TOKEN: env.GITHUB_TOKEN + NEXE_VERSION: release.toString() } } }) diff --git a/tasks/docker.ts b/tasks/docker.ts new file mode 100644 index 0000000..952fdee --- /dev/null +++ b/tasks/docker.ts @@ -0,0 +1,32 @@ +import { NexeTarget } from '../src/target' +import { writeFileAsync } from '../src/util' +import exec = require('execa') + +function alpine (target: NexeTarget, nexeVersion: string) { + const version = target.version + return ` +FROM i386/alpine:3.6 +RUN apk add --no-cache curl make gcc g++ binutils-gold python linux-headers paxctl libgcc libstdc++ git vim tar gzip wget +WORKDIR / +RUN curl -sSL https://nodejs.org/dist/v${version}/node-v${version}.tar.gz | tar -xz && \ + cd /node-v${version} && \ + ./configure --prefix=/usr --fully-static && \ + make -j$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ + make install && \ + paxctl -cm /usr/bin/node + +RUN mkdir nexe_temp && mv node-v${version} nexe_temp/${version} +RUN npm i nexe@beta -g +ENV NEXE_TEMP=/nexe_temp + +RUN nexe --empty -c="--fully-static" -o /nexe-out`.trim() +} + +export async function runAlpineBuild (target: NexeTarget, nexeVersion: string) { + await writeFileAsync('Dockerfile', alpine(target, nexeVersion)) + const option = { stido: 'inherit' } as any + await exec('docker', ['build', '-t', 'nexe-alpine', '.'], option) + await exec('docker', ['run', '--name', 'nexe', 'nexe-alpine'], option) + await exec('docker', ['cp', 'nexe:/nexe-out', 'out'], option) + await exec('docker', ['rm', 'nexe'], option) +}