ci: configured native artifact caching and parallel execution in ci workflows
- Enhanced CI workflows and GitHub actions to support native artifact caching and parallel builds. - Added composite actions and scripts for computing sources, finding artifacts, and managing caches. - Updated infrastructure documentation and runner deployment scripts with revised resource limits.
This commit is contained in:
@@ -28,10 +28,9 @@ inputs:
|
||||
default: ""
|
||||
glibc:
|
||||
description: >
|
||||
Optional glibc floor (e.g. "2.17") for linux-gnu builds. Routes the build
|
||||
through cargo-zigbuild against that floor without affecting the rustup
|
||||
target or the host-arch native test steps. Combine with `target` to pin a
|
||||
cross-arch linux build, or set alone for a host-arch (x64) linux build.
|
||||
Optional glibc floor override for linux-gnu builds (defaults to "2.17").
|
||||
Routes the build through cargo-zigbuild against that floor without
|
||||
affecting the rustup target or host-arch native test steps.
|
||||
required: false
|
||||
default: ""
|
||||
libc:
|
||||
@@ -43,16 +42,19 @@ inputs:
|
||||
required: false
|
||||
default: "false"
|
||||
skip_validation:
|
||||
description: >
|
||||
Skip clippy/rustfmt and the Rust test suite. Set on release runs: the
|
||||
version-bump commit only changes version strings, and the tagged
|
||||
content's Rust code already passed validation on its main-push run.
|
||||
description: Skip clippy/rustfmt and the Rust test suite for build-only matrix entries.
|
||||
required: false
|
||||
default: "false"
|
||||
skip_build:
|
||||
description: Run validation and cache population without building or uploading a native addon.
|
||||
required: false
|
||||
default: "false"
|
||||
cache_scope:
|
||||
description: Separates target snapshots whose Cargo work differs (for example, build and validation).
|
||||
required: false
|
||||
default: "build"
|
||||
save_cache:
|
||||
description: >
|
||||
Whether to write build caches: Swatinem/rust-cache on GitHub-hosted
|
||||
runners, the RustFS target/ snapshot on omp-kata.
|
||||
description: Whether to persist the GitHub-hosted or RustFS target snapshot.
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
@@ -82,9 +84,20 @@ runs:
|
||||
env:
|
||||
TARGET: ${{ inputs.target }}
|
||||
GLIBC: ${{ inputs.glibc }}
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
LIBC: ${{ inputs.libc }}
|
||||
ARCH: ${{ inputs.arch }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Keep the portability floor here: this action is included in the
|
||||
# native source hash, and every workflow then consumes one value.
|
||||
if [ "$PLATFORM" = linux ] && [ "$LIBC" != musl ]; then
|
||||
GLIBC="${GLIBC:-2.17}"
|
||||
elif [ -n "$GLIBC" ]; then
|
||||
echo "::error::glibc floor '$GLIBC' is only valid for linux-gnu builds"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# `cross_target` is what the napi build feeds cargo: cargo-zigbuild reads
|
||||
# the glibc floor as a `.<major>.<minor>` triple suffix. `bare_target` is
|
||||
# what rustup needs — never glibc-suffixed (rustup rejects the suffix)
|
||||
@@ -98,11 +111,13 @@ runs:
|
||||
fi
|
||||
cross_target=""
|
||||
if [ -n "$GLIBC" ]; then
|
||||
if [ -z "$base" ]; then
|
||||
echo "::error::glibc floor '$GLIBC' set but no linux-gnu base triple for arch '$ARCH'"
|
||||
exit 1
|
||||
fi
|
||||
cross_target="${base}.${GLIBC}"
|
||||
case "$base" in
|
||||
*-linux-gnu) cross_target="${base}.${GLIBC}" ;;
|
||||
*)
|
||||
echo "::error::glibc floor '$GLIBC' requires a linux-gnu target, got '$base'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
elif [ -n "$TARGET" ]; then
|
||||
cross_target="$TARGET"
|
||||
fi
|
||||
@@ -187,25 +202,28 @@ runs:
|
||||
echo "RUSTFLAGS=$rustflags" >> "$GITHUB_ENV"
|
||||
echo "Configured RUSTFLAGS=$rustflags"
|
||||
|
||||
# --- target/ cache (GitHub-hosted only) ---------------------------------
|
||||
# Swatinem keys target/ off its restore-time environment, so it must run
|
||||
# after RUSTFLAGS is set: if x64 target-cpu were only selected later, cargo
|
||||
# would invalidate the restored target/ while rust-cache saw an exact key
|
||||
# and refused to save the rebuilt artifacts (macOS x64 baseline rebuilds
|
||||
# forever). The native source hash is in the shared key too: rust-cache's
|
||||
# lockfile scan misses the workspace-root Cargo.toml version Cargo
|
||||
# fingerprints, so a version bump could otherwise get an exact hit for
|
||||
# artifacts Cargo must rebuild. On omp-kata the reuse layers are the
|
||||
# mounted Cargo registry, RustFS sccache, and the RustFS target/ snapshot
|
||||
# (see "Restore target/ cache" below), so Swatinem stays GitHub-only.
|
||||
- name: Cache Rust target/ (GitHub-hosted)
|
||||
# --- Cargo + rolling target cache (GitHub-hosted only) ------------------
|
||||
# Swatinem keeps the registry/tool cache. target/ uses an explicit rolling
|
||||
# key: a new source hash restores the latest compatible snapshot through
|
||||
# restore-keys, then saves the rebuilt state under a fresh immutable key.
|
||||
# This is especially important for the three-core Intel macOS runner.
|
||||
- name: Cache Cargo dependencies (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
shared-key: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-h${{ inputs.hash }}
|
||||
shared-key: native-deps-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}
|
||||
cache-on-failure: true
|
||||
save-if: ${{ inputs.save_cache == 'true' }}
|
||||
cache-workspace-crates: true
|
||||
cache-targets: false
|
||||
- name: Restore rolling Rust target/ (GitHub-hosted)
|
||||
id: gha-target
|
||||
if: steps.detect.outputs.on_infra == 'false'
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: target
|
||||
key: native-target-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}-${{ hashFiles('rust-toolchain.toml') }}-h${{ inputs.hash }}
|
||||
restore-keys: |
|
||||
native-target-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}-${{ hashFiles('rust-toolchain.toml') }}-
|
||||
|
||||
# --- sccache ------------------------------------------------------------
|
||||
- name: Ensure baked sccache (omp-kata)
|
||||
@@ -225,10 +243,24 @@ runs:
|
||||
env:
|
||||
CROSS_TARGET: ${{ steps.resolve.outputs.cross_target }}
|
||||
run: |
|
||||
jobs="${OMP_CI_CPU_COUNT:-$(getconf _NPROCESSORS_ONLN)}"
|
||||
if [ -z "${OMP_CI_CPU_COUNT:-}" ] && [ -r /sys/fs/cgroup/cpu.max ]; then
|
||||
read -r quota period < /sys/fs/cgroup/cpu.max
|
||||
if [ "$quota" != "max" ]; then
|
||||
quota_jobs=$((quota / period))
|
||||
[ "$quota_jobs" -ge 1 ] || quota_jobs=1
|
||||
[ "$quota_jobs" -ge "$jobs" ] || jobs="$quota_jobs"
|
||||
fi
|
||||
fi
|
||||
{
|
||||
echo "OMP_CI_CPU_COUNT=$jobs"
|
||||
echo "RUSTC_WRAPPER=sccache"
|
||||
echo "CARGO_INCREMENTAL=0"
|
||||
echo "CARGO_BUILD_JOBS=$jobs"
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$jobs"
|
||||
echo "NEXTEST_TEST_THREADS=$jobs"
|
||||
} >> "$GITHUB_ENV"
|
||||
echo "Native build parallelism: $jobs"
|
||||
# Route CMake-built C (audiopus_sys' bundled opus) through sccache
|
||||
# too — build scripts bypass RUSTC_WRAPPER. Non-cross builds only:
|
||||
# cross builds compile C with zig cc / clang-cl wrapper scripts that
|
||||
@@ -248,13 +280,13 @@ runs:
|
||||
|
||||
# --- cargo-nextest (native test runner; non-cross builds only) ----------
|
||||
- name: Ensure baked cargo-nextest (omp-kata)
|
||||
if: steps.detect.outputs.on_infra == 'true' && inputs.target == ''
|
||||
if: steps.detect.outputs.on_infra == 'true' && inputs.target == '' && inputs.skip_validation != 'true'
|
||||
uses: ./.github/actions/ensure-cargo-tool
|
||||
with:
|
||||
binary: cargo-nextest
|
||||
crate: cargo-nextest
|
||||
- name: Install cargo-nextest (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false' && inputs.target == ''
|
||||
if: steps.detect.outputs.on_infra == 'false' && inputs.target == '' && inputs.skip_validation != 'true'
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: nextest
|
||||
@@ -323,12 +355,17 @@ runs:
|
||||
# cargo's fingerprint/link work bypass it. Snapshot target/ to the same
|
||||
# RustFS S3 bucket, keyed per platform/libc/arch/variant + toolchain and
|
||||
# overwritten on each save so storage stays bounded at one snapshot per
|
||||
# key. GitHub-hosted runners get the same effect from Swatinem above.
|
||||
# key. GitHub-hosted runners get the same effect from the rolling cache above.
|
||||
- name: Verify target cache compressor (omp-kata)
|
||||
if: steps.detect.outputs.on_infra == 'true'
|
||||
shell: bash
|
||||
run: zstd --version
|
||||
|
||||
- name: Restore target/ cache (omp-kata)
|
||||
if: steps.detect.outputs.on_infra == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
TARGET_CACHE_KEY: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}
|
||||
TARGET_CACHE_KEY: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}
|
||||
run: bun scripts/ci-target-cache.ts restore "$TARGET_CACHE_KEY"
|
||||
|
||||
# --- Checks, build, upload (shared) -------------------------------------
|
||||
@@ -345,29 +382,46 @@ runs:
|
||||
shell: bash
|
||||
run: bun run test:rs
|
||||
- name: Build native addon(s)
|
||||
if: inputs.skip_build != 'true'
|
||||
shell: bash
|
||||
env:
|
||||
CROSS_TARGET: ${{ steps.resolve.outputs.cross_target }}
|
||||
TARGET_PLATFORM: ${{ inputs.platform }}
|
||||
TARGET_ARCH: ${{ inputs.arch }}
|
||||
TARGET_VARIANTS: ${{ inputs.variant }}
|
||||
run: bun run ci:build:native
|
||||
run: |
|
||||
if [ "$CROSS_TARGET" = x86_64-apple-darwin ]; then
|
||||
# Do not accept Homebrew's arm64 libopus through pkg-config;
|
||||
# build audiopus_sys's bundled x64 archive.
|
||||
export OPUS_NO_PKG_CONFIG=1
|
||||
fi
|
||||
bun run ci:build:native
|
||||
- name: sccache stats
|
||||
shell: bash
|
||||
run: sccache --show-stats || true
|
||||
- name: Save native addon(s) to in-cluster cache
|
||||
if: inputs.skip_build != 'true' && steps.detect.outputs.on_infra == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
ARTIFACT_NAME: pi-natives-${{ inputs.platform }}-${{ inputs.libc && format('{0}-', inputs.libc) || '' }}${{ inputs.arch }}${{ inputs.variant && format('-{0}', inputs.variant) || '' }}-h${{ inputs.hash }}
|
||||
run: bun scripts/ci-native-artifact-cache.ts save "${{ inputs.hash }}" "$ARTIFACT_NAME"
|
||||
- name: Upload native addon(s)
|
||||
if: inputs.skip_build != 'true'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pi-natives-${{ inputs.platform }}-${{ inputs.libc && format('{0}-', inputs.libc) || '' }}${{ 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 native_artifact_lookup canary 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
|
||||
- name: Save target/ cache (omp-kata)
|
||||
if: steps.detect.outputs.on_infra == 'true' && inputs.save_cache == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
TARGET_CACHE_KEY: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}
|
||||
TARGET_CACHE_KEY: native-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}
|
||||
run: bun scripts/ci-target-cache.ts save "$TARGET_CACHE_KEY"
|
||||
- name: Save rolling Rust target/ (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false' && inputs.save_cache == 'true' && steps.gha-target.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: target
|
||||
key: native-target-v1-${{ runner.os }}-${{ runner.arch }}-${{ inputs.platform }}-${{ inputs.libc || 'default' }}-${{ inputs.arch }}-${{ inputs.variant || 'default' }}-${{ inputs.cache_scope }}-${{ hashFiles('rust-toolchain.toml') }}-h${{ inputs.hash }}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
name: Find reusable native artifacts
|
||||
description: Find complete trusted native artifact sets for one source hash, including canceled main runs.
|
||||
|
||||
inputs:
|
||||
hash:
|
||||
description: Native source hash embedded in artifact names
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
linux-x64-run-id:
|
||||
description: Run containing both Linux x64 variants
|
||||
value: ${{ steps.find.outputs.linux-x64-run-id }}
|
||||
cross-platform-run-id:
|
||||
description: Run containing every cross-platform artifact
|
||||
value: ${{ steps.find.outputs.cross-platform-run-id }}
|
||||
validation-run-id:
|
||||
description: Run containing the successful Rust validation marker
|
||||
value: ${{ steps.find.outputs.validation-run-id }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Find complete artifact sets
|
||||
id: find
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
REPOSITORY_ID: ${{ github.repository_id }}
|
||||
SOURCE_HASH: ${{ inputs.hash }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
artifact_run_ids() {
|
||||
local artifact_name="$1"
|
||||
gh api --paginate "/repos/${REPOSITORY}/actions/artifacts?name=${artifact_name}&per_page=100" \
|
||||
--jq ".artifacts[] | select(.expired == false and .workflow_run.head_branch == \"main\" and .workflow_run.head_repository_id == ${REPOSITORY_ID}) | .workflow_run.id" \
|
||||
| sort -rn | uniq
|
||||
}
|
||||
|
||||
find_complete_run() {
|
||||
local canary="$1"
|
||||
shift
|
||||
local candidate names required complete
|
||||
while read -r candidate; do
|
||||
[ -n "$candidate" ] || continue
|
||||
names="$(gh api "/repos/${REPOSITORY}/actions/runs/${candidate}/artifacts?per_page=100" \
|
||||
--jq '.artifacts[] | select(.expired == false) | .name')"
|
||||
complete=true
|
||||
for required in "$@"; do
|
||||
if ! grep -qFx "$required" <<<"$names"; then
|
||||
complete=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
if $complete; then
|
||||
echo "$candidate"
|
||||
return 0
|
||||
fi
|
||||
done < <(artifact_run_ids "$canary")
|
||||
}
|
||||
|
||||
linux_baseline="pi-natives-linux-x64-baseline-h${SOURCE_HASH}"
|
||||
linux_modern="pi-natives-linux-x64-modern-h${SOURCE_HASH}"
|
||||
cross_required=(
|
||||
"pi-natives-linux-arm64-h${SOURCE_HASH}"
|
||||
"pi-natives-linux-musl-x64-baseline-h${SOURCE_HASH}"
|
||||
"pi-natives-linux-musl-arm64-h${SOURCE_HASH}"
|
||||
"pi-natives-darwin-x64-baseline-h${SOURCE_HASH}"
|
||||
"pi-natives-darwin-arm64-h${SOURCE_HASH}"
|
||||
"pi-natives-win32-x64-baseline-h${SOURCE_HASH}"
|
||||
)
|
||||
validation_marker="pi-natives-rust-validation-h${SOURCE_HASH}"
|
||||
|
||||
linux_x64_run_id="$(find_complete_run "$linux_modern" "$linux_baseline" "$linux_modern")"
|
||||
cross_platform_run_id="$(find_complete_run "${cross_required[3]}" "${cross_required[@]}")"
|
||||
validation_run_id="$(find_complete_run "$validation_marker" "$validation_marker")"
|
||||
|
||||
if [ -n "$linux_x64_run_id" ]; then
|
||||
echo "Reusing Linux x64 native artifacts from run $linux_x64_run_id"
|
||||
else
|
||||
echo "No complete Linux x64 artifact set for hash $SOURCE_HASH"
|
||||
fi
|
||||
if [ -n "$cross_platform_run_id" ]; then
|
||||
echo "Reusing cross-platform native artifacts from run $cross_platform_run_id"
|
||||
else
|
||||
echo "No complete cross-platform artifact set for hash $SOURCE_HASH"
|
||||
fi
|
||||
if [ -n "$validation_run_id" ]; then
|
||||
echo "Reusing Rust validation from run $validation_run_id"
|
||||
else
|
||||
echo "No Rust validation marker for hash $SOURCE_HASH"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "linux-x64-run-id=$linux_x64_run_id"
|
||||
echo "cross-platform-run-id=$cross_platform_run_id"
|
||||
echo "validation-run-id=$validation_run_id"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
@@ -0,0 +1,30 @@
|
||||
name: Compute native source hash
|
||||
description: Hash every source, toolchain, and build-or-validation input that governs reusable native artifacts.
|
||||
|
||||
outputs:
|
||||
source-hash:
|
||||
description: Stable 16-hex native source fingerprint
|
||||
value: ${{ steps.compute.outputs.source-hash }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Compute native source hash
|
||||
id: compute
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
source_hash=$(find \
|
||||
crates \
|
||||
packages/natives/scripts \
|
||||
Cargo.toml Cargo.lock rust-toolchain.toml rustfmt.toml \
|
||||
packages/natives/package.json \
|
||||
scripts/ci-build-native.ts scripts/ci-target-cache.ts scripts/host-detect.ts scripts/run-rs-task.ts \
|
||||
.github/actions/build-native/action.yml .github/actions/native-source-hash/action.yml \
|
||||
-type f -print0 \
|
||||
| sort -z \
|
||||
| xargs -0 sha256sum \
|
||||
| sha256sum \
|
||||
| cut -c1-16)
|
||||
echo "source-hash=$source_hash" >> "$GITHUB_OUTPUT"
|
||||
echo "Native source hash: $source_hash"
|
||||
@@ -0,0 +1,54 @@
|
||||
name: Restore Linux x64 native addons
|
||||
description: Restore both Linux x64 variants from the in-cluster cache or a trusted GitHub artifact run.
|
||||
|
||||
inputs:
|
||||
hash:
|
||||
description: Native source hash embedded in artifact names
|
||||
required: true
|
||||
native-job-result:
|
||||
description: Result of the current run's Linux x64 native matrix
|
||||
required: true
|
||||
cached-run-id:
|
||||
description: Prior run containing both Linux x64 variants
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Restore native addons from in-cluster cache
|
||||
id: local
|
||||
shell: bash
|
||||
run: |
|
||||
bun scripts/ci-native-artifact-cache.ts restore \
|
||||
"${{ inputs.hash }}" \
|
||||
packages/natives/native \
|
||||
"pi-natives-linux-x64-baseline-h${{ inputs.hash }}" \
|
||||
"pi-natives-linux-x64-modern-h${{ inputs.hash }}"
|
||||
|
||||
- name: Resolve GitHub artifact run
|
||||
if: steps.local.outputs.hit != 'true'
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ "${{ inputs.native-job-result }}" = "success" ]; then
|
||||
run_id="${{ github.run_id }}"
|
||||
else
|
||||
run_id="${{ inputs.cached-run-id }}"
|
||||
fi
|
||||
if [ -z "$run_id" ]; then
|
||||
echo "No Linux x64 native artifact source is available" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "run-id=$run_id" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Download native addons from GitHub
|
||||
if: steps.local.outputs.hit != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ inputs.hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.run-id }}
|
||||
github-token: ${{ github.token }}
|
||||
+147
-280
@@ -30,12 +30,6 @@ concurrency:
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
# glibc floor for shipped linux native addons. The omp-kata runner image is
|
||||
# Ubuntu 24.04 (glibc 2.39); a plain native build links 2.39 symbol versions
|
||||
# and fails to dlopen on older distros. Building the linux-gnu addons through
|
||||
# cargo-zigbuild against this floor keeps them portable. Bump to raise the
|
||||
# minimum supported glibc.
|
||||
GLIBC_FLOOR: "2.17"
|
||||
# audiopus_sys bundles an opus tree whose CMakeLists declares a
|
||||
# cmake_minimum_required below 3.5; CMake 4.x refuses to configure it
|
||||
# without this override (macOS runner images ship CMake 4).
|
||||
@@ -96,18 +90,14 @@ jobs:
|
||||
echo "release-tag=$release_tag"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Compute a stable hash of every input that affects the native cdylib output,
|
||||
# then look for any prior successful main run that already uploaded the
|
||||
# native artifacts for this hash. Two independent outputs:
|
||||
# * `linux-x64-run-id` — set when the linux x64 canary
|
||||
# (`pi-natives-linux-x64-modern-h<hash>`) is present on a prior main run,
|
||||
# so native-dependent TS test jobs and `native_linux_x64` can reuse it.
|
||||
# * `cross-platform-run-id` — set when ALL cross-platform native artifacts
|
||||
# also have non-expired artifacts on that same prior run, so
|
||||
# `native_cross_platform` can skip the cold rebuild on main pushes after
|
||||
# dep changes have already warmed sccache there.
|
||||
# Non-release native jobs are skipped when their canary hits; the canary
|
||||
# retention window (see build-native action) is the effective TTL.
|
||||
# Compute one native source hash, then validate complete artifact sets from
|
||||
# any trusted main-branch run. Run conclusion is deliberately irrelevant:
|
||||
# an upload proves that build step completed before a later job failed or a
|
||||
# newer push canceled the workflow.
|
||||
#
|
||||
# Linux x64, the full cross-platform matrix, and Rust validation are tracked
|
||||
# independently. Consumers either use a complete prior set or build the
|
||||
# missing set in this run; no single canary can hide a partial matrix.
|
||||
native_artifact_lookup:
|
||||
name: Look up cached native artifacts
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
@@ -115,92 +105,18 @@ jobs:
|
||||
source-hash: ${{ steps.compute.outputs.source-hash }}
|
||||
linux-x64-run-id: ${{ steps.find.outputs.linux-x64-run-id }}
|
||||
cross-platform-run-id: ${{ steps.find.outputs.cross-platform-run-id }}
|
||||
validation-run-id: ${{ steps.find.outputs.validation-run-id }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compute native source hash
|
||||
id: compute
|
||||
shell: bash
|
||||
run: |
|
||||
source_hash=$(find crates Cargo.toml Cargo.lock rust-toolchain.toml \
|
||||
packages/natives/scripts packages/natives/package.json \
|
||||
scripts/ci-build-native.ts scripts/host-detect.ts \
|
||||
-type f -print0 \
|
||||
| sort -z \
|
||||
| xargs -0 sha256sum \
|
||||
| sha256sum \
|
||||
| cut -c1-16)
|
||||
echo "source-hash=$source_hash" >> "$GITHUB_OUTPUT"
|
||||
echo "Native source hash: $source_hash"
|
||||
- name: Find prior main build with matching native artifacts
|
||||
uses: ./.github/actions/native-source-hash
|
||||
- name: Find trusted reusable artifacts
|
||||
id: find
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
shell: bash
|
||||
run: |
|
||||
hash="${{ steps.compute.outputs.source-hash }}"
|
||||
# Canary for native_linux_x64: presence of the modern artifact
|
||||
# implies the baseline sibling is also there (they upload from the
|
||||
# same job).
|
||||
linux_canary="pi-natives-linux-x64-modern-h${hash}"
|
||||
# Required set for cross-platform reuse — names must match the
|
||||
# `actions/upload-artifact` `name:` template in build-native action.
|
||||
cross_platform_required=(
|
||||
"pi-natives-linux-arm64-h${hash}"
|
||||
"pi-natives-linux-musl-x64-baseline-h${hash}"
|
||||
"pi-natives-linux-musl-arm64-h${hash}"
|
||||
"pi-natives-darwin-x64-baseline-h${hash}"
|
||||
"pi-natives-darwin-arm64-h${hash}"
|
||||
"pi-natives-win32-x64-baseline-h${hash}"
|
||||
)
|
||||
linux_x64_run_id=""
|
||||
cross_platform_run_id=""
|
||||
for candidate in $(gh run list \
|
||||
--workflow=ci.yml --branch=main --status=success --event=push \
|
||||
--limit=20 --json databaseId --jq='.[].databaseId'); do
|
||||
names=$(gh api "/repos/${{ github.repository }}/actions/runs/$candidate/artifacts?per_page=100" \
|
||||
--jq '.artifacts[] | select(.expired == false) | .name')
|
||||
if [ -z "$linux_x64_run_id" ] && echo "$names" | grep -qFx "$linux_canary"; then
|
||||
linux_x64_run_id="$candidate"
|
||||
fi
|
||||
if [ -z "$cross_platform_run_id" ]; then
|
||||
all_found=true
|
||||
# Cross-platform reuse requires the linux canary AND every
|
||||
# cross-platform artifact, since release_binary downloads them
|
||||
# from the same run.
|
||||
if ! echo "$names" | grep -qFx "$linux_canary"; then
|
||||
all_found=false
|
||||
else
|
||||
for req in "${cross_platform_required[@]}"; do
|
||||
if ! echo "$names" | grep -qFx "$req"; then
|
||||
all_found=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if $all_found; then
|
||||
cross_platform_run_id="$candidate"
|
||||
fi
|
||||
fi
|
||||
if [ -n "$linux_x64_run_id" ] && [ -n "$cross_platform_run_id" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -n "$linux_x64_run_id" ]; then
|
||||
echo "Reusing Linux x64 native artifacts from run $linux_x64_run_id"
|
||||
else
|
||||
echo "No cached Linux x64 native artifacts for hash $hash; native_linux_x64 will rebuild."
|
||||
fi
|
||||
if [ -n "$cross_platform_run_id" ]; then
|
||||
echo "Reusing cross-platform native artifacts from run $cross_platform_run_id"
|
||||
else
|
||||
echo "No cached cross-platform native artifacts for hash $hash; native_cross_platform will rebuild on main."
|
||||
fi
|
||||
{
|
||||
echo "linux-x64-run-id=$linux_x64_run_id"
|
||||
echo "cross-platform-run-id=$cross_platform_run_id"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
uses: ./.github/actions/find-native-artifacts
|
||||
with:
|
||||
hash: ${{ steps.compute.outputs.source-hash }}
|
||||
|
||||
# Fast lint, type check, and browser bundle build (no Rust, no native build needed)
|
||||
check:
|
||||
name: Lint, type check & web build
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
@@ -212,22 +128,44 @@ jobs:
|
||||
- name: Build collab web
|
||||
run: bun run collab:web:build
|
||||
|
||||
# Linux x64 baseline + modern: required by `test`, so it runs on every PR
|
||||
# unless native_artifact_lookup found a cached run. Release runs always
|
||||
# rebuild for fresh artifacts but skip clippy + Rust tests (skip_validation):
|
||||
# the bump commit only changes version strings over content that already
|
||||
# passed validation on its main-push run.
|
||||
rust_validation:
|
||||
name: Validate Rust workspace
|
||||
needs: [native_artifact_lookup]
|
||||
if: ${{ needs.native_artifact_lookup.outputs.validation-run-id == '' }}
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-native
|
||||
with:
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
platform: linux
|
||||
arch: x64
|
||||
variant: baseline
|
||||
rust_checks: "true"
|
||||
skip_build: "true"
|
||||
cache_scope: validation
|
||||
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
- name: Create validation marker
|
||||
shell: bash
|
||||
run: echo "${{ needs.native_artifact_lookup.outputs.source-hash }}" > "$RUNNER_TEMP/rust-validation"
|
||||
- name: Upload validation marker
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pi-natives-rust-validation-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: ${{ runner.temp }}/rust-validation
|
||||
retention-days: 90
|
||||
|
||||
# Linux x64 baseline + modern supply the TS and install jobs. Rust validation
|
||||
# is a separate parallel job, so both matrix entries are build-only.
|
||||
native_linux_x64:
|
||||
name: "Native: Linux x64 (${{ matrix.variant }})"
|
||||
needs: [release_metadata, native_artifact_lookup]
|
||||
if: ${{ needs.release_metadata.outputs.is-release == 'true' || needs.native_artifact_lookup.outputs.linux-x64-run-id == '' }}
|
||||
needs: [native_artifact_lookup]
|
||||
if: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id == '' }}
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { variant: baseline, rust_checks: true }
|
||||
- { variant: modern }
|
||||
variant: [baseline, modern]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-native
|
||||
@@ -236,18 +174,15 @@ jobs:
|
||||
platform: linux
|
||||
arch: x64
|
||||
variant: ${{ matrix.variant }}
|
||||
glibc: ${{ env.GLIBC_FLOOR }}
|
||||
rust_checks: ${{ matrix.rust_checks && 'true' || 'false' }}
|
||||
skip_validation: ${{ needs.release_metadata.outputs.is-release }}
|
||||
skip_validation: "true"
|
||||
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
|
||||
# Pre-warm the cross-platform native build cache on `main`, in addition to
|
||||
# building the artifacts that ship in releases. Skipped on main when
|
||||
# native_artifact_lookup already found a recent run with all artifacts intact.
|
||||
# Cross-platform builds stay in this workflow only as a release fallback.
|
||||
# Successful main CI runs launch the non-blocking native-prewarm workflow.
|
||||
native_cross_platform_kata:
|
||||
name: "Native: ${{ matrix.platform }} ${{ matrix.libc || '' }} ${{ matrix.arch }}"
|
||||
needs: [release_metadata, native_artifact_lookup]
|
||||
if: ${{ needs.release_metadata.outputs.is-release == 'true' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '') }}
|
||||
if: ${{ needs.release_metadata.outputs.is-release == 'true' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -267,18 +202,18 @@ jobs:
|
||||
libc: ${{ matrix.libc }}
|
||||
variant: ${{ matrix.variant }}
|
||||
target: ${{ matrix.target }}
|
||||
glibc: ${{ matrix.platform == 'linux' && matrix.libc != 'musl' && env.GLIBC_FLOOR || '' }}
|
||||
skip_validation: "true"
|
||||
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
|
||||
native_cross_platform_macos:
|
||||
name: "Native: ${{ matrix.platform }} ${{ matrix.arch }}"
|
||||
needs: [release_metadata, native_artifact_lookup]
|
||||
if: ${{ needs.release_metadata.outputs.is-release == 'true' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '') }}
|
||||
if: ${{ needs.release_metadata.outputs.is-release == 'true' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { os: macos-15-intel, platform: darwin, arch: x64, variant: baseline }
|
||||
- { os: macos-14, platform: darwin, arch: x64, target: x86_64-apple-darwin, variant: baseline }
|
||||
- { os: macos-14, platform: darwin, arch: arm64 }
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
@@ -290,7 +225,9 @@ jobs:
|
||||
arch: ${{ matrix.arch }}
|
||||
variant: ${{ matrix.variant }}
|
||||
target: ${{ matrix.target }}
|
||||
skip_validation: "true"
|
||||
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
|
||||
test_workspace:
|
||||
name: Test TS workspace fast
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
@@ -301,24 +238,14 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Test workspace packages and repo scripts (TS)
|
||||
env:
|
||||
OMP_TEST_CONCURRENCY: "4"
|
||||
run: bun run ci:test:ts:workspace
|
||||
|
||||
test_coding_agent_singleton:
|
||||
@@ -331,23 +258,11 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Test coding-agent singleton/global-state bucket
|
||||
# Keep global Settings/env/fake-timer tests serial; native addon
|
||||
# artifacts are still available like every other coding-agent bucket.
|
||||
@@ -364,24 +279,14 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Test native/TUI/browser-ish packages (TS)
|
||||
env:
|
||||
OMP_TEST_CONCURRENCY: "4"
|
||||
run: bun run ci:test:ts:native
|
||||
|
||||
test_coding_agent_ui:
|
||||
@@ -395,24 +300,14 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Test coding-agent UI/TUI bucket
|
||||
env:
|
||||
OMP_TEST_CONCURRENCY: "2"
|
||||
run: bun run ci:test:coding-agent:ui
|
||||
|
||||
test_coding_agent_runtime:
|
||||
@@ -425,26 +320,16 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Test coding-agent runtime bucket
|
||||
# Runtime/session tests import native-backed barrels too; keep this
|
||||
# separate for concurrency, not as a native-free guardrail.
|
||||
env:
|
||||
OMP_TEST_CONCURRENCY: "4"
|
||||
run: bun run ci:test:coding-agent:runtime
|
||||
|
||||
test_coding_agent_native:
|
||||
@@ -458,24 +343,14 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Test coding-agent native/unit bucket
|
||||
env:
|
||||
OMP_TEST_CONCURRENCY: "4"
|
||||
run: bun run ci:test:coding-agent:native
|
||||
|
||||
test_smoke:
|
||||
@@ -489,84 +364,41 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.source.outputs.artifact-run-id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: CLI smoke test
|
||||
run: bun run ci:test:smoke
|
||||
|
||||
install_methods:
|
||||
name: Install method smoke tests
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
needs: [native_linux_x64, native_artifact_lookup]
|
||||
if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/ensure-rust-toolchain
|
||||
with:
|
||||
toolchain: nightly-2026-04-29
|
||||
- uses: ./.github/actions/ensure-cmake
|
||||
- name: Detect runner environment
|
||||
id: detect
|
||||
shell: bash
|
||||
run: |
|
||||
# $SCCACHE_BUCKET is injected only on self-hosted omp-kata pods; its
|
||||
# presence selects baked sccache + shared S3. GitHub-hosted runners
|
||||
# (PRs) need sccache-action to export the GHA cache URL/token into the
|
||||
# step env — a bare binary install leaves SCCACHE_GHA_ENABLED set with
|
||||
# no cache URL, so sccache server startup fails ("cache url for ghac
|
||||
# not found"). Mirrors the build-native action's sccache wiring.
|
||||
if [ -n "${SCCACHE_BUCKET:-}" ]; then
|
||||
echo "on_infra=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "on_infra=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Ensure baked sccache (omp-kata)
|
||||
if: steps.detect.outputs.on_infra == 'true'
|
||||
uses: ./.github/actions/ensure-sccache
|
||||
with:
|
||||
version: "0.15.0"
|
||||
- name: Setup sccache (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false'
|
||||
uses: mozilla-actions/sccache-action@v0.0.10
|
||||
- name: Enable sccache for cargo
|
||||
# Conditional backend: self-hosted omp-kata injects a shared S3
|
||||
# (RustFS) sccache via pod env; GitHub-hosted runners keep the GHA
|
||||
# cache. CARGO_INCREMENTAL=0 keeps sccache from silently no-oping.
|
||||
shell: bash
|
||||
run: |
|
||||
{
|
||||
echo "RUSTC_WRAPPER=sccache"
|
||||
echo "CARGO_INCREMENTAL=0"
|
||||
} >> "$GITHUB_ENV"
|
||||
if [ -n "${SCCACHE_BUCKET:-}" ]; then
|
||||
echo "sccache backend: shared S3 ($SCCACHE_BUCKET @ $SCCACHE_ENDPOINT)"
|
||||
else
|
||||
echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV"
|
||||
echo "sccache backend: GitHub Actions cache"
|
||||
fi
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- uses: ./.github/actions/restore-linux-native
|
||||
with:
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
native-job-result: ${{ needs.native_linux_x64.result }}
|
||||
cached-run-id: ${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}
|
||||
- name: Install method smoke tests
|
||||
env:
|
||||
OMP_INSTALL_TEST_SKIP_NATIVE_BUILD: "1"
|
||||
run: bun run ci:test:install-methods
|
||||
|
||||
|
||||
release_binary:
|
||||
name: "Release binary: ${{ matrix.target_id }}"
|
||||
if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() &&
|
||||
needs.native_linux_x64.result == 'success' && needs.native_cross_platform_kata.result ==
|
||||
'success' && needs.native_cross_platform_macos.result == 'success' &&
|
||||
needs.rust_validation.result != 'failure' &&
|
||||
needs.native_linux_x64.result != 'failure' &&
|
||||
needs.native_cross_platform_kata.result != 'failure' &&
|
||||
needs.native_cross_platform_macos.result != 'failure' &&
|
||||
needs.test_workspace.result == 'success' &&
|
||||
needs.test_coding_agent_singleton.result == 'success' &&
|
||||
needs.test_ts_native.result == 'success' &&
|
||||
@@ -575,7 +407,7 @@ jobs:
|
||||
needs.test_coding_agent_native.result == 'success' &&
|
||||
needs.test_smoke.result == 'success' && needs.check.result == 'success' &&
|
||||
needs.install_methods.result == 'success' }}
|
||||
needs: [release_metadata, check, native_linux_x64, native_cross_platform_kata, native_cross_platform_macos, test_workspace, test_coding_agent_singleton, test_ts_native, test_coding_agent_ui, test_coding_agent_runtime, test_coding_agent_native, test_smoke, install_methods, native_artifact_lookup]
|
||||
needs: [release_metadata, check, rust_validation, native_linux_x64, native_cross_platform_kata, native_cross_platform_macos, test_workspace, test_coding_agent_singleton, test_ts_native, test_coding_agent_ui, test_coding_agent_runtime, test_coding_agent_native, test_smoke, install_methods, native_artifact_lookup]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -641,6 +473,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
id-token: write
|
||||
env:
|
||||
MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }}
|
||||
@@ -667,12 +500,36 @@ jobs:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
|
||||
- run: bun install --frozen-lockfile
|
||||
- name: Resolve native artifact run
|
||||
id: native-source
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ "${{ matrix.target_id }}" = "linux-x64" ]; then
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
run_id="${{ github.run_id }}"
|
||||
else
|
||||
run_id="${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}"
|
||||
fi
|
||||
elif [ "${{ needs.native_cross_platform_kata.result }}" = "success" ] || \
|
||||
[ "${{ needs.native_cross_platform_macos.result }}" = "success" ]; then
|
||||
run_id="${{ github.run_id }}"
|
||||
else
|
||||
run_id="${{ needs.native_artifact_lookup.outputs.cross-platform-run-id }}"
|
||||
fi
|
||||
if [ -z "$run_id" ]; then
|
||||
echo "No native artifact run for ${{ matrix.target_id }}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "run-id=$run_id" >> "$GITHUB_OUTPUT"
|
||||
- name: Download native addon(s)
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
pattern: ${{ matrix.native_artifact_pattern }}-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.native-source.outputs.run-id }}
|
||||
github-token: ${{ github.token }}
|
||||
- name: Build release binary
|
||||
env:
|
||||
RELEASE_TARGETS: ${{ matrix.target_id }}
|
||||
@@ -806,7 +663,7 @@ jobs:
|
||||
needs.release_binary.result == 'success' &&
|
||||
needs.release_github_verify.result == 'success' &&
|
||||
!inputs.skip_npm }}
|
||||
needs: [release_metadata, release_binary, release_github_verify, native_artifact_lookup]
|
||||
needs: [release_metadata, release_binary, release_github_verify, native_linux_x64, native_artifact_lookup]
|
||||
runs-on: ubuntu-22.04
|
||||
# `id-token: write` lets npm mint the GitHub OIDC token it exchanges for a
|
||||
# short-lived publish token (trusted publishing + provenance). When a
|
||||
@@ -815,6 +672,7 @@ jobs:
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
actions: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
@@ -836,15 +694,24 @@ jobs:
|
||||
- run: bun install --frozen-lockfile
|
||||
# The pi-coding-agent prepack executes workspace code (bundle-dist
|
||||
# imports the pi-utils barrel, which loads the pi-natives addon), so
|
||||
# this job needs the linux x64 native addons just like `test` does.
|
||||
# Release runs always rebuild natives in this same run, so the
|
||||
# default run-id resolves the artifacts.
|
||||
# this job needs the Linux x64 native addons just like TS tests do.
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: native-source
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then
|
||||
echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
path: packages/natives/native
|
||||
merge-multiple: true
|
||||
run-id: ${{ steps.native-source.outputs.run-id }}
|
||||
github-token: ${{ github.token }}
|
||||
- name: Publish to npm
|
||||
env:
|
||||
# Fallback auth: setup-node wrote an .npmrc referencing
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
name: Native prewarm
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [CI]
|
||||
types: [completed]
|
||||
workflow_dispatch:
|
||||
# Prewarming must never extend the required CI workflow. Keep one warmup running
|
||||
# to completion so it publishes the target snapshot; GitHub coalesces newer
|
||||
# pending runs in this concurrency group.
|
||||
concurrency:
|
||||
group: native-prewarm-main
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lookup:
|
||||
name: Look up cross-platform artifacts
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main') }}
|
||||
runs-on: omp-kata
|
||||
outputs:
|
||||
source-hash: ${{ steps.compute.outputs.source-hash }}
|
||||
cross-platform-run-id: ${{ steps.find.outputs.cross-platform-run-id }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
- id: compute
|
||||
uses: ./.github/actions/native-source-hash
|
||||
- id: find
|
||||
uses: ./.github/actions/find-native-artifacts
|
||||
with:
|
||||
hash: ${{ steps.compute.outputs.source-hash }}
|
||||
|
||||
cross_platform_kata:
|
||||
name: "Prewarm native: ${{ matrix.platform }} ${{ matrix.libc || '' }} ${{ matrix.arch }}"
|
||||
needs: [lookup]
|
||||
if: ${{ needs.lookup.outputs.cross-platform-run-id == '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 2
|
||||
matrix:
|
||||
include:
|
||||
- { platform: linux, arch: arm64, target: aarch64-unknown-linux-gnu }
|
||||
- { platform: linux, libc: musl, arch: x64, target: x86_64-unknown-linux-musl, variant: baseline }
|
||||
- { platform: linux, libc: musl, arch: arm64, target: aarch64-unknown-linux-musl }
|
||||
- { platform: win32, arch: x64, target: x86_64-pc-windows-msvc, variant: baseline }
|
||||
runs-on: omp-kata
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
- uses: ./.github/actions/build-native
|
||||
with:
|
||||
hash: ${{ needs.lookup.outputs.source-hash }}
|
||||
platform: ${{ matrix.platform }}
|
||||
libc: ${{ matrix.libc }}
|
||||
arch: ${{ matrix.arch }}
|
||||
variant: ${{ matrix.variant }}
|
||||
target: ${{ matrix.target }}
|
||||
skip_validation: "true"
|
||||
save_cache: "true"
|
||||
|
||||
cross_platform_macos:
|
||||
name: "Prewarm native: darwin ${{ matrix.arch }}"
|
||||
needs: [lookup]
|
||||
if: ${{ needs.lookup.outputs.cross-platform-run-id == '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { os: macos-14, arch: x64, target: x86_64-apple-darwin, variant: baseline }
|
||||
- { os: macos-14, arch: arm64 }
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
- uses: ./.github/actions/build-native
|
||||
with:
|
||||
hash: ${{ needs.lookup.outputs.source-hash }}
|
||||
platform: darwin
|
||||
arch: ${{ matrix.arch }}
|
||||
variant: ${{ matrix.variant }}
|
||||
target: ${{ matrix.target }}
|
||||
skip_validation: "true"
|
||||
save_cache: "true"
|
||||
Reference in New Issue
Block a user