diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..38175ef70 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,65 @@ +name: Test deploy + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: macos-latest + - os: ubuntu-latest + - os: ubuntu-22.04-arm + - os: windows-latest + - os: windows-11-arm + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + + - name: Install dependencies + run: npm ci + + - name: Copy prebuild artifacts + run: node scripts/prebuild.js --populate + + - name: Tar prebuild artifacts + run: tar -czf prebuilds-${{ matrix.os }}.tar.gz prebuilds + + - uses: actions/upload-artifact@v4 + with: + name: build-artifacts-${{ matrix.os }} + path: prebuilds-${{ matrix.os }}.tar.gz + if-no-files-found: error + + deploy: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + + - uses: actions/download-artifact@v4 + with: + merge-multiple: true + + - name: Extract prebuild artifacts + run: | + for file in prebuilds-*.tar.gz; do + tar -xzf "$file"; + rm $file; + done + + - name: Install dependencies + run: npm ci + + - name: Publish package + run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 29b1871d4..e26e7ad73 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ fixtures/space folder/ .vscode/settings.json .vscode/ipch/ yarn.lock +/prebuilds/ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 26685b192..8418cd306 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -31,6 +31,8 @@ extends: displayName: 'Install Node.js' - script: npm ci displayName: 'Install dependencies and build' + - script: node scripts/prebuild.js --populate + displayName: 'Copy prebuild artifacts' - script: npm test displayName: 'Test' - script: npm run lint @@ -50,6 +52,8 @@ extends: displayName: Install setuptools (macOS) - script: npm ci displayName: 'Install dependencies and build' + - script: node scripts/prebuild.js --populate + displayName: 'Copy prebuild artifacts' - script: npm test displayName: 'Test' - script: npm run lint @@ -66,6 +70,8 @@ extends: displayName: 'Install Node.js' - script: npm ci displayName: 'Install dependencies and build' + - script: node scripts/prebuild.js --populate + displayName: 'Copy prebuild artifacts' - script: npm test displayName: 'Test' - script: npm run lint diff --git a/package.json b/package.json index 8f6aa3c11..066c5f4c7 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "scripts/", "src/", "deps/", + "prebuilds/", "third_party/", "typings/" ], @@ -37,6 +38,7 @@ "build": "tsc -b ./src/tsconfig.json", "watch": "tsc -b -w ./src/tsconfig.json", "lint": "eslint -c .eslintrc.js --ext .ts src/", + "install": "node scripts/prebuild.js || node-gyp rebuild", "postinstall": "node scripts/post-install.js", "test": "cross-env NODE_ENV=test mocha -R spec --exit lib/*.test.js", "posttest": "npm run lint", diff --git a/publish.yml b/publish.yml index 962837b7e..db7814887 100644 --- a/publish.yml +++ b/publish.yml @@ -41,6 +41,8 @@ extends: buildSteps: - script: npm ci displayName: 'Install dependencies and build' + - script: node scripts/prebuild.js --populate + displayName: 'Copy prebuild artifacts' # The following script leaves the version unchanged for # stable releases, but increments the version for beta releases. - script: node scripts/increment-version.js diff --git a/scripts/post-install.js b/scripts/post-install.js index d192504f0..85512370f 100644 --- a/scripts/post-install.js +++ b/scripts/post-install.js @@ -5,6 +5,7 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); +const PREBUILD_DIR = path.join(__dirname, '..', 'prebuilds', `${process.platform}-${process.arch}`); const RELEASE_DIR = path.join(__dirname, '../build/Release'); const BUILD_FILES = [ path.join(RELEASE_DIR, 'conpty.node'), @@ -24,6 +25,7 @@ const CONPTY_SUPPORTED_ARCH = ['x64', 'arm64']; console.log('\x1b[32m> Cleaning release folder...\x1b[0m'); +/** @param {string} folder */ function cleanFolderRecursive(folder) { var files = []; if (fs.existsSync(folder)) { @@ -78,6 +80,10 @@ if (os.platform() !== 'win32') { } console.log(`\x1b[32m> Generating compile_commands.json...\x1b[0m`); +if (fs.existsSync(PREBUILD_DIR)) { + console.log(` SKIPPED compile_commands since prebuild directory ${PREBUILD_DIR} exists`); + process.exit(0); +} execSync('npx node-gyp configure -- -f compile_commands_json'); process.exit(0); diff --git a/scripts/prebuild.js b/scripts/prebuild.js new file mode 100644 index 000000000..a867e6ffe --- /dev/null +++ b/scripts/prebuild.js @@ -0,0 +1,40 @@ +//@ts-check + +const fs = require('fs'); +const path = require('path'); + +/** + * This scripts either copies the prebuilt binaries from the prebuild directory + * for the current platform and architecture to the build/Release directory or + * copies them in the other direction. + * + * Usage: + * To copy binaries from prebuilds/- to the build/Release: + * + * node scripts/prebuild.js + * + * To copy the binaries from the build/Release directory to the prebuilds dir: + * + * node scripts/prebuild.js --populate + */ + +const POPULATE = process.argv.includes('--populate'); +const PREBUILD_DIR = path.join(__dirname, '..', 'prebuilds', `${process.platform}-${process.arch}`); +const RELEASE_DIR = path.join(__dirname, '../build/Release'); + +/* Populate: Copy all build/Release files to prebuilds/- */ +if (POPULATE) { + console.log('\x1b[32m> Copying release to prebuilds folder...\x1b[0m'); + fs.mkdirSync(PREBUILD_DIR, { recursive: true }); + fs.cpSync(RELEASE_DIR, PREBUILD_DIR, { recursive: true }); + process.exit(0); +} + +/* Default: Copy prebuild files to build/Release */ +console.log('\x1b[32m> Copying prebuilds to release folder...\x1b[0m'); +if (!fs.existsSync(PREBUILD_DIR)) { + console.log(` SKIPPED Prebuild directory ${PREBUILD_DIR} does not exist`); + // Exit with 1 to fall back on node-gyp building the native modules + process.exit(1); +} +fs.cpSync(PREBUILD_DIR, RELEASE_DIR, { recursive: true }); diff --git a/src/windowsTerminal.test.ts b/src/windowsTerminal.test.ts index 705ae5045..8f1274edf 100644 --- a/src/windowsTerminal.test.ts +++ b/src/windowsTerminal.test.ts @@ -127,7 +127,8 @@ if (process.platform === 'win32') { }); describe('resize', () => { - it('should throw a non-native exception when resizing an invalid value', (done) => { + it('should throw a non-native exception when resizing an invalid value', function(done) { + this.timeout(20000); const term = new WindowsTerminal('cmd.exe', [], { useConpty, useConptyDll }); assert.throws(() => term.resize(-1, -1)); assert.throws(() => term.resize(0, 0)); @@ -137,7 +138,8 @@ if (process.platform === 'win32') { }); term.kill(); }); - it('should throw a non-native exception when resizing a killed terminal', (done) => { + it('should throw a non-native exception when resizing a killed terminal', function(done) { + this.timeout(20000); const term = new WindowsTerminal('cmd.exe', [], { useConpty, useConptyDll }); (term)._defer(() => { term.once('exit', () => {