CI/CD Integration
Automate cross-platform builds with GitHub Actions and other CI systems.
Overview
Hakobu is designed to work seamlessly in CI/CD pipelines. This guide covers GitHub Actions workflows for building, signing, and releasing cross-platform executables.
GitHub Actions Matrix Build
The recommended approach uses a matrix strategy to build each platform on its native runner:
name: Build & Release
on:
push:
tags:
- 'v*'
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- target: node24-linux-x64
os: ubuntu-latest
- target: node24-linux-arm64
os: ubuntu-24.04-arm
- target: node24-win-x64
os: windows-latest
- target: node24-macos-arm64
os: macos-latest
- target: node24-macos-x64
os: macos-13
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install dependencies
run: npm ci
- name: Build executable
run: npx hakobu . --target ${{ matrix.target }} --output ./dist/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.target }}
path: ./dist/*Use fail-fast: false so that a failure on one platform does not cancel builds for the other platforms.
Caching Base Binaries
Hakobu downloads patched Node.js base binaries on first use and caches them in ~/.hakobu/cache/. Cache this directory to speed up subsequent builds:
- name: Cache Hakobu base binaries
uses: actions/cache@v4
with:
path: ~/.hakobu/cache
key: hakobu-base-${{ matrix.target }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
hakobu-base-${{ matrix.target }}-The cache path is configurable via the HAKOBU_CACHE_PATH environment variable if ~/.hakobu/cache does not suit your CI setup.
Adding Code Signing
Extend the matrix workflow to sign executables on each platform.
macOS signing and notarization
- name: Install signing certificate
if: runner.os == 'macOS'
env:
P12_BASE64: ${{ secrets.APPLE_DEVELOPER_ID_P12 }}
P12_PASSWORD: ${{ secrets.APPLE_DEVELOPER_ID_PASSWORD }}
run: |
echo "$P12_BASE64" | base64 --decode > cert.p12
security create-keychain -p "" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "" build.keychain
security import cert.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k "" build.keychain
rm cert.p12
- name: Build executable (macOS)
if: runner.os == 'macOS'
env:
HAKOBU_SIGN_IDENTITY: ${{ secrets.APPLE_SIGN_IDENTITY }}
HAKOBU_APPLE_ID: ${{ secrets.APPLE_ID }}
HAKOBU_APPLE_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
HAKOBU_APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: npx hakobu . --target ${{ matrix.target }} --output ./dist/ --notarizeWindows Authenticode signing
- name: Decode signing certificate
if: runner.os == 'Windows'
run: |
echo "${{ secrets.WIN_CERT_BASE64 }}" > cert-base64.txt
certutil -decode cert-base64.txt cert.pfx
del cert-base64.txt
shell: cmd
- name: Build executable (Windows)
if: runner.os == 'Windows'
env:
HAKOBU_WIN_CERT: cert.pfx
HAKOBU_WIN_CERT_PASSWORD: ${{ secrets.WIN_CERT_PASSWORD }}
run: npx hakobu . --target ${{ matrix.target }} --output ./dist/
- name: Clean up certificate
if: always() && runner.os == 'Windows'
run: del cert.pfx
shell: cmdCreating a Release
Add a job that collects all build artifacts and creates a GitHub Release:
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
merge-multiple: true
- name: Generate checksums
run: |
cd artifacts
sha256sum * > CHECKSUMS.sha256
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: ./artifacts/*
generate_release_notes: trueComplete Workflow
Here is the full workflow combining all steps -- matrix builds, caching, signing, and release creation:
Configure repository secrets
Add these secrets in your repository settings (Settings, then Secrets and variables, then Actions):
| Secret | Purpose |
|---|---|
APPLE_DEVELOPER_ID_P12 | Base64-encoded .p12 certificate |
APPLE_DEVELOPER_ID_PASSWORD | Password for the .p12 |
APPLE_SIGN_IDENTITY | Signing identity string |
APPLE_ID | Apple ID email |
APPLE_APP_SPECIFIC_PASSWORD | App-specific password |
APPLE_TEAM_ID | Apple Developer Team ID |
WIN_CERT_BASE64 | Base64-encoded .pfx certificate |
WIN_CERT_PASSWORD | PFX password |
Create the workflow file
Create .github/workflows/release.yml with the matrix build, signing steps, and release job shown in the sections above.
Tag a release
Push a version tag to trigger the workflow:
git tag v1.0.0
git push origin v1.0.0The workflow builds executables for all platforms, signs them, generates checksums, and publishes a GitHub Release with all artifacts.
Cross-Platform Builds from a Single Runner
If you prefer not to use a matrix strategy, Hakobu can build for all platforms from a single machine:
- name: Build all targets
run: npx hakobu . --target all --output ./dist/Cross-platform builds from a single runner cannot natively sign executables for other platforms. macOS notarization requires a macOS runner, and Windows signtool requires a Windows runner. Use osslsigncode on Linux/macOS for cross-signing Windows binaries.
Other CI Systems
The same principles apply to any CI system. The key requirements are:
- Node.js 24.x available on the runner
- Hakobu installed as a dev dependency or via
npx - Base binary cache persisted between builds for speed
- Signing credentials stored securely and available as environment variables
- Platform-specific runners for native signing (macOS notarization, Windows signtool)
For example, in GitLab CI:
build:linux:
image: node:24
script:
- npm ci
- npx hakobu . --target node24-linux-x64 --output ./dist/
artifacts:
paths:
- dist/
cache:
key: hakobu-linux
paths:
- ~/.hakobu/cache/