Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -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
25 changes: 18 additions & 7 deletions build-sea.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
Loading