harden automation, release provenance, and project evidence #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |