Files
oh-my-pi/.github/actions/build-native/action.yml
T
can1357 71fe258320 ci: migrated release trigger from tag-push to branch-push
- 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.
2026-05-31 02:33:19 +02:00

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