- Removed `tags: ["v*"]` trigger; release now fires from the single atomic `main` push that carries the tag. - Replaced `gate.skip` with `gate.is-release` and `gate.release-tag` so downstream jobs detect the tag via `git tag --points-at HEAD`. - Passed `release-tag` explicitly to release steps (gh-release, curl, release notes) since `github.ref` is now `refs/heads/main`, not the tag. - Fixed rust-cache key collision on macOS x64 by setting `RUSTFLAGS` (target-cpu) before cache restore and including the native source hash in the shared key.
186 lines
7.6 KiB
YAML
186 lines
7.6 KiB
YAML
name: Build native addon
|
|
description: Build the pi_natives cdylib for one platform/arch/variant and upload it as a hash-tagged artifact.
|
|
|
|
inputs:
|
|
hash:
|
|
description: Rust source hash used in the artifact name
|
|
required: true
|
|
platform:
|
|
description: Target platform (linux, darwin, win32)
|
|
required: true
|
|
arch:
|
|
description: Target arch (x64, arm64)
|
|
required: true
|
|
variant:
|
|
description: Optional build variant (baseline, modern); required for native x64 builds.
|
|
required: false
|
|
default: ""
|
|
target:
|
|
description: Optional rustc target triple for cross-compilation
|
|
required: false
|
|
default: ""
|
|
rust_checks:
|
|
description: Run clippy/rustfmt checks (only one matrix entry should set this)
|
|
required: false
|
|
default: "false"
|
|
save_cache:
|
|
description: Whether Swatinem/rust-cache should write a cache entry
|
|
required: false
|
|
default: "false"
|
|
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- uses: dtolnay/rust-toolchain@nightly
|
|
with:
|
|
toolchain: nightly-2026-04-29
|
|
components: ${{ inputs.rust_checks == 'true' && 'clippy, rustfmt' || '' }}
|
|
targets: ${{ inputs.target }}
|
|
- name: Prepend rustup toolchain bin to PATH
|
|
shell: bash
|
|
run: |
|
|
# Homebrew on macOS runners ships rustup-init with shadow proxies
|
|
# for `cargo`/`rustc`/etc. that error out as the installer
|
|
# ("unexpected argument 'metadata' found"). Force the real
|
|
# toolchain binaries to win on PATH.
|
|
toolchain_bin="$(dirname "$(rustup which cargo)")"
|
|
echo "$toolchain_bin" >> "$GITHUB_PATH"
|
|
echo "Prepended $toolchain_bin to PATH"
|
|
# `Swatinem/rust-cache` keys target/ off its restore-time environment, so
|
|
# set RUSTFLAGS before restoring it. If x64 target-cpu is only selected
|
|
# inside ci-build-native.ts/build-native.ts, cargo invalidates the restored
|
|
# target/ but rust-cache sees an exact key and refuses to save the rebuilt
|
|
# artifacts, causing macOS x64 baseline to rebuild forever.
|
|
#
|
|
# Include the native source hash in the shared key as well: rust-cache's
|
|
# lockfile scan misses the workspace root Cargo.toml version that Cargo
|
|
# fingerprints for workspace crates. Without it, release version bumps can
|
|
# get an exact hit for artifacts Cargo must rebuild.
|
|
#
|
|
# sccache is still layered on top of rust-cache: target/ wins when warm,
|
|
# sccache fills the gaps when target/ is cold.
|
|
- name: Configure native Rust flags
|
|
if: inputs.target == ''
|
|
shell: bash
|
|
env:
|
|
TARGET_ARCH: ${{ inputs.arch }}
|
|
TARGET_VARIANT: ${{ inputs.variant }}
|
|
run: |
|
|
case "$TARGET_ARCH:$TARGET_VARIANT" in
|
|
x64:modern)
|
|
rustflags="-C target-cpu=x86-64-v3"
|
|
;;
|
|
x64:baseline)
|
|
rustflags="-C target-cpu=x86-64-v2"
|
|
;;
|
|
x64:*)
|
|
echo "::error::x64 native builds require variant=modern or variant=baseline"
|
|
exit 1
|
|
;;
|
|
*)
|
|
if [ -n "${RUSTFLAGS:-}" ]; then
|
|
echo "Using caller-provided RUSTFLAGS=$RUSTFLAGS"
|
|
exit 0
|
|
fi
|
|
rustflags="-C target-cpu=native"
|
|
;;
|
|
esac
|
|
|
|
echo "RUSTFLAGS=$rustflags" >> "$GITHUB_ENV"
|
|
echo "Configured RUSTFLAGS=$rustflags"
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: native-${{ inputs.platform }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-h${{ inputs.hash }}
|
|
cache-on-failure: true
|
|
save-if: ${{ inputs.save_cache == 'true' }}
|
|
cache-workspace-crates: true
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.10
|
|
- name: Enable sccache for cargo
|
|
# `CARGO_INCREMENTAL=0` is required: sccache silently skips caching
|
|
# when incremental is enabled, which would turn the wrapper into a
|
|
# no-op. rust-cache also sets this today, but pin it here so sccache
|
|
# stays effective if rust-cache is removed or changes defaults. Also
|
|
# overrides `profile.dev.incremental = true` for `bun run test:rs`.
|
|
shell: bash
|
|
run: |
|
|
{
|
|
echo "SCCACHE_GHA_ENABLED=true"
|
|
echo "RUSTC_WRAPPER=sccache"
|
|
echo "CARGO_INCREMENTAL=0"
|
|
} >> "$GITHUB_ENV"
|
|
- uses: taiki-e/install-action@v2
|
|
if: inputs.target == ''
|
|
with:
|
|
tool: nextest
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3"
|
|
- shell: bash
|
|
run: bun install --frozen-lockfile
|
|
# Cross-compile toolchain selection: non-MSVC targets (e.g.
|
|
# `aarch64-unknown-linux-gnu`) build with `cargo-zigbuild`; MSVC targets
|
|
# (e.g. `x86_64-pc-windows-msvc`) build with `cargo-xwin`. The napi CLI's
|
|
# `--cross-compile` flag picks the backend; we just install what it needs.
|
|
- name: Setup zig (non-MSVC cross-compile)
|
|
if: inputs.target != '' && !endsWith(inputs.target, '-msvc')
|
|
uses: mlugg/setup-zig@v2
|
|
with:
|
|
version: 0.16.0
|
|
- name: Install cargo-zigbuild (non-MSVC cross-compile)
|
|
if: inputs.target != '' && !endsWith(inputs.target, '-msvc')
|
|
uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: cargo-zigbuild
|
|
- name: Install LLVM tooling (MSVC cross-compile)
|
|
if: endsWith(inputs.target, '-msvc')
|
|
shell: bash
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y clang lld llvm
|
|
- name: Install cargo-xwin (MSVC cross-compile)
|
|
if: endsWith(inputs.target, '-msvc')
|
|
uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: cargo-xwin
|
|
- name: Cache cargo-xwin Windows SDK
|
|
if: endsWith(inputs.target, '-msvc')
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.cache/cargo-xwin
|
|
key: cargo-xwin-${{ runner.os }}-v1
|
|
- name: Accept xwin license
|
|
if: endsWith(inputs.target, '-msvc')
|
|
shell: bash
|
|
run: echo "XWIN_ACCEPT_LICENSE=1" >> "$GITHUB_ENV"
|
|
- name: Rust checks
|
|
if: inputs.rust_checks == 'true'
|
|
shell: bash
|
|
run: bun run check:rs
|
|
- name: Test workspace (Rust)
|
|
# macOS has no `#[cfg(target_os = "macos")]` tests in the workspace,
|
|
# and Windows-only tests are no longer exercised in CI (`win32-x64`
|
|
# cross-builds on Linux). Skipping the duplicate Linux runs on macOS
|
|
# saves ~10 min of parallel runner time.
|
|
if: inputs.target == '' && inputs.platform != 'darwin'
|
|
shell: bash
|
|
run: bun run test:rs
|
|
- name: Build native addon(s)
|
|
shell: bash
|
|
env:
|
|
CROSS_TARGET: ${{ inputs.target }}
|
|
TARGET_PLATFORM: ${{ inputs.platform }}
|
|
TARGET_ARCH: ${{ inputs.arch }}
|
|
TARGET_VARIANTS: ${{ inputs.variant }}
|
|
run: bun run ci:build:native
|
|
- name: Upload native addon(s)
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: pi-natives-${{ inputs.platform }}-${{ inputs.arch }}${{ inputs.variant && format('-{0}', inputs.variant) || '' }}-h${{ inputs.hash }}
|
|
path: packages/natives/native/pi_natives.${{ inputs.platform }}-${{ inputs.arch }}*.node
|
|
if-no-files-found: error
|
|
# Explicit so the rust-hash canary lookup keeps working even if org
|
|
# defaults shift; bump if Rust source ever stays stable for >90 days
|
|
# of main pushes and you want to avoid rebuilds.
|
|
retention-days: 90
|