Skip to content

harden automation, release provenance, and project evidence #5

harden automation, release provenance, and project evidence

harden automation, release provenance, and project evidence #5

# Cross-compile stdin-napi (.node files) for all 5 platforms whenever
# packages/stdin-napi/native/ source changes. Outputs are uploaded as
# artifacts and committed by a follow-up job to vendor/<arch>-<plat>/.
#
# Why a separate workflow (not part of release.yml): the .node binaries are
# committed to the repo so they ship with `bun run build:platforms` without a
# build step on the user's machine. Cross-compiling rust on every release is
# too slow; we cache the artifacts in git instead.
#
# Same shape as build-ripgrep-napi.yml. Note: on win32 the rust side is a
# termios-free stub (the reader is unix-only) — we still build + vendor the
# .node so the literal-require loads and isReaderSupported() returns false.
name: Build stdin-napi
on:
workflow_dispatch:
push:
# Restrict to branches — tag pushes (release.yml triggers) check out a
# detached HEAD, which makes the auto-commit job try to `git push` without
# a branch ref and fail. Branches-only avoids that false red.
branches:
- main
paths:
- 'packages/stdin-napi/native/**'
- '.github/workflows/build-stdin-napi.yml'
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
target: aarch64-apple-darwin
vendor-dir: arm64-darwin
artifact-name: stdin-napi-arm64-darwin
node-name: stdin.node
- os: macos-latest
target: x86_64-apple-darwin
vendor-dir: x64-darwin
artifact-name: stdin-napi-x64-darwin
node-name: stdin.node
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
vendor-dir: arm64-linux
artifact-name: stdin-napi-arm64-linux
node-name: stdin.node
cross: true
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
vendor-dir: x64-linux
artifact-name: stdin-napi-x64-linux
node-name: stdin.node
- os: windows-latest
target: x86_64-pc-windows-msvc
vendor-dir: x64-win32
artifact-name: stdin-napi-x64-win32
node-name: stdin.node
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- name: Install rust toolchain
uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
with:
targets: ${{ matrix.target }}
- name: Cache cargo registry + index
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ matrix.target }}-${{ hashFiles('packages/stdin-napi/native/Cargo.lock') }}
restore-keys: |
${{ matrix.target }}-
- name: Install cross-compile linker (Linux arm64)
if: matrix.cross == true
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
mkdir -p ~/.cargo
cat >> ~/.cargo/config.toml <<EOF
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
EOF
- name: Build stdin-napi
working-directory: packages/stdin-napi/native
run: cargo build --release --target ${{ matrix.target }}
- name: Stage .node artifact (Unix)
if: matrix.os != 'windows-latest'
run: |
# cargo writes to <repo>/target/stdin-napi/<target>/release/.
# Source filename varies by platform:
# darwin: libstdin_napi.dylib
# linux: libstdin_napi.so
src=""
for cand in \
target/stdin-napi/${{ matrix.target }}/release/libstdin_napi.dylib \
target/stdin-napi/${{ matrix.target }}/release/libstdin_napi.so; do
if [ -f "$cand" ]; then src="$cand"; break; fi
done
if [ -z "$src" ]; then
echo "::error::no built artifact found"
exit 1
fi
mkdir -p staged
cp "$src" "staged/${{ matrix.node-name }}"
- name: Stage .node artifact (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
$src = "target/stdin-napi/${{ matrix.target }}/release/stdin_napi.dll"
if (-not (Test-Path $src)) {
Write-Error "no built artifact found at $src"
exit 1
}
New-Item -ItemType Directory -Force -Path staged | Out-Null
Copy-Item $src "staged/${{ matrix.node-name }}"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ${{ matrix.artifact-name }}
path: staged/${{ matrix.node-name }}
if-no-files-found: error
commit:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
path: artifacts
- name: Move artifacts into vendor/
run: |
for dir in arm64-darwin x64-darwin arm64-linux x64-linux x64-win32; do
artifact_name="stdin-napi-${dir}"
src="artifacts/${artifact_name}/stdin.node"
dst="packages/stdin-napi/vendor/${dir}/stdin.node"
if [ -f "$src" ]; then
mkdir -p "$(dirname "$dst")"
cp "$src" "$dst"
echo "staged $dst ($(stat -c%s "$dst") bytes)"
else
echo "::warning::missing $src — skipping"
fi
done
- name: Commit + push if changes
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git diff --quiet packages/stdin-napi/vendor/; then
echo "no changes — skipping commit"
exit 0
fi
git add packages/stdin-napi/vendor/
msg="stdin-napi: refresh vendored .node binaries (CI run ${{ github.run_number }} from ${{ github.sha }})"
git commit -m "$msg" -m "Co-Authored-By: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
git push