From 74a72d9bccd9585c6a91c4e4fcef5acda9ecc336 Mon Sep 17 00:00:00 2001 From: Hamdi LAADHARI Date: Fri, 21 Aug 2026 03:58:57 +0200 Subject: [PATCH] add CI with cross-platform build matrix, fix Windows output naming Adds a GitHub Actions workflow that installs, typechecks, tests, and builds the SEA binary on ubuntu-latest/macos-latest/windows-latest on every push to main and every PR, then smoke-tests the resulting binary. This is the only way to catch a regression in build:sea before someone downloads a broken binary. While wiring this up: sea-config.json's output ("dist/hello", no extension) isn't directly runnable on Windows. build-sea.js now renames it to dist/hello.exe on win32 after the build -- the file is already a valid PE binary at that point (it started as a copy of node.exe), so a plain rename is enough. Closes #8, closes #11. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/ci.yml | 37 +++++++++++++++++++++++++++++++++++++ build-sea.js | 25 ++++++++++++++++++------- 2 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9046d24 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + + - run: npm ci + - run: npm run build:js + - run: npm test + - run: npm run build:bundle + - run: npm run build:sea + + - name: Smoke test the binary (Unix) + if: runner.os != 'Windows' + run: ./dist/hello CI + + - name: Smoke test the binary (Windows) + if: runner.os == 'Windows' + run: .\dist\hello.exe CI diff --git a/build-sea.js b/build-sea.js index a9c3d8b..176cf47 100644 --- a/build-sea.js +++ b/build-sea.js @@ -16,24 +16,35 @@ try { execSync('node --build-sea sea-config.json', { stdio: 'inherit' }); } catch (error) { console.error('\nFailed to build the SEA binary.'); - console.error(`node --build-sea requires Node.js 24 "Krypton" LTS or newer — you are running ${process.version}.`); - console.error('Switch with: nvm install lts/krypton && nvm use lts/krypton'); + console.error(`node --build-sea requires Node.js 25.5+ — you are running ${process.version}.`); + console.error('As of this writing it only ships on the Node 26 "Current" release line (not yet backported to the 24 LTS line). Switch with: nvm install 26 && nvm use 26'); process.exit(1); } -// Step 2: Sign the binary (macOS specific; required for the binary to run +// Step 2: sea-config.json's "output" is a plain "dist/hello" with no +// extension. On Windows that isn't directly runnable -- the file itself is +// still a valid PE binary (it started as a copy of node.exe), so a plain +// rename to add .exe is enough; no need to rebuild anything. +let outputPath = 'dist/hello'; +if (process.platform === 'win32') { + const exePath = 'dist/hello.exe'; + fs.renameSync(outputPath, exePath); + outputPath = exePath; +} + +// Step 3: Sign the binary (macOS specific; required for the binary to run // without a Gatekeeper prompt on Apple Silicon) if (process.platform === 'darwin') { console.log('Signing the binary (macOS ad-hoc signature)...'); try { - execSync('codesign --sign - dist/hello'); + execSync(`codesign --sign - ${outputPath}`); } catch (error) { console.error('Failed to sign binary:', error.message); process.exit(1); } } else if (process.platform === 'win32') { - console.log('On Windows, sign dist/hello.exe yourself if you need a trusted binary:'); - console.log(' signtool sign /fd SHA256 dist\\hello.exe'); + console.log(`On Windows, sign ${outputPath} yourself if you need a trusted binary:`); + console.log(` signtool sign /fd SHA256 ${outputPath}`); } -console.log('SEA binary creation complete! The executable is ready: ./dist/hello'); +console.log(`SEA binary creation complete! The executable is ready: ./${outputPath}`);