feat(infra): migrated runner caches to PVC-backed Bun/Cargo and RustFS sccache
- Updated bun-install action to set mounted cache mode and use PVC cache paths. - Removed RustFS Bun restore/save and maintenance scripts, replacing them with mounted cache setup. - Removed zstd from runner image installation and baked-tool verification checks. - Updated infra docs to describe split caching with RustFS for sccache and PVC for Bun/Cargo.
This commit is contained in:
@@ -1,134 +0,0 @@
|
||||
name: Build native addon (omp-kata)
|
||||
description: >
|
||||
Build the pi_natives cdylib on the preloaded omp-kata runner image, using
|
||||
baked toolchains and the shared RustFS-backed sccache instead of per-job tool
|
||||
setup downloads.
|
||||
|
||||
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: Kept for interface parity with the GitHub-hosted action; unused here.
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: ./.github/actions/ensure-rust-toolchain
|
||||
with:
|
||||
toolchain: nightly-2026-04-29
|
||||
components: ${{ inputs.rust_checks == 'true' && 'clippy,rustfmt' || '' }}
|
||||
target: ${{ inputs.target }}
|
||||
- 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: ./.github/actions/ensure-sccache
|
||||
with:
|
||||
version: "0.15.0"
|
||||
- name: Enable sccache for cargo
|
||||
shell: bash
|
||||
run: |
|
||||
{
|
||||
echo "RUSTC_WRAPPER=sccache"
|
||||
echo "CARGO_INCREMENTAL=0"
|
||||
} >> "$GITHUB_ENV"
|
||||
echo "sccache backend: shared S3 ($SCCACHE_BUCKET @ $SCCACHE_ENDPOINT)"
|
||||
- uses: ./.github/actions/ensure-cargo-tool
|
||||
if: inputs.target == ''
|
||||
with:
|
||||
binary: cargo-nextest
|
||||
crate: cargo-nextest
|
||||
- uses: ./.github/actions/bun-install
|
||||
- uses: ./.github/actions/ensure-zig
|
||||
if: inputs.target != '' && !endsWith(inputs.target, '-msvc')
|
||||
with:
|
||||
version: "0.16.0"
|
||||
- uses: ./.github/actions/ensure-cargo-tool
|
||||
if: inputs.target != '' && !endsWith(inputs.target, '-msvc')
|
||||
with:
|
||||
binary: cargo-zigbuild
|
||||
crate: cargo-zigbuild
|
||||
- uses: ./.github/actions/ensure-cargo-tool
|
||||
if: endsWith(inputs.target, '-msvc')
|
||||
with:
|
||||
binary: cargo-xwin
|
||||
crate: 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)
|
||||
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
|
||||
retention-days: 90
|
||||
@@ -1,5 +1,12 @@
|
||||
name: Build native addon
|
||||
description: Build the pi_natives cdylib for one platform/arch/variant and upload it as a hash-tagged artifact.
|
||||
description: >
|
||||
Build the pi_natives cdylib for one platform/arch/variant and upload it as a
|
||||
hash-tagged artifact. Self-detects the runner via $SCCACHE_BUCKET (injected
|
||||
only on the self-hosted omp-kata pods): on-infra it uses the image's baked
|
||||
toolchains + the RustFS-backed sccache; on GitHub-hosted runners it installs
|
||||
the toolchains and uses Swatinem target/ cache + the GitHub Actions sccache
|
||||
backend. PRs run on GitHub-hosted runners, so the on-infra path only ever
|
||||
serves trusted push/main + release builds.
|
||||
|
||||
inputs:
|
||||
hash:
|
||||
@@ -24,48 +31,64 @@ inputs:
|
||||
required: false
|
||||
default: "false"
|
||||
save_cache:
|
||||
description: Whether Swatinem/rust-cache should write a cache entry
|
||||
description: Whether Swatinem/rust-cache should write a cache entry (GitHub-hosted only)
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- name: Detect runner environment
|
||||
id: detect
|
||||
shell: bash
|
||||
run: |
|
||||
# $SCCACHE_BUCKET is injected only on the self-hosted omp-kata runner
|
||||
# pods (envFrom sccache-s3); its presence is the repo's single
|
||||
# "on can.internal infra?" signal. On-infra: baked toolchains, RustFS
|
||||
# sccache, no GitHub target/ cache. Off-infra (GitHub-hosted): install
|
||||
# toolchains, Swatinem target/ cache, GitHub Actions sccache backend.
|
||||
if [ -n "${SCCACHE_BUCKET:-}" ]; then
|
||||
echo "on_infra=true" >> "$GITHUB_OUTPUT"
|
||||
echo "runner: self-hosted omp-kata (baked tools + RustFS sccache)"
|
||||
else
|
||||
echo "on_infra=false" >> "$GITHUB_OUTPUT"
|
||||
echo "runner: GitHub-hosted (install tools + Swatinem cache + GHA sccache)"
|
||||
fi
|
||||
|
||||
# --- Rust toolchain -----------------------------------------------------
|
||||
- name: Ensure baked Rust toolchain (omp-kata)
|
||||
if: steps.detect.outputs.on_infra == 'true'
|
||||
uses: ./.github/actions/ensure-rust-toolchain
|
||||
with:
|
||||
toolchain: nightly-2026-04-29
|
||||
components: ${{ inputs.rust_checks == 'true' && 'clippy,rustfmt' || '' }}
|
||||
target: ${{ inputs.target }}
|
||||
- name: Install Rust toolchain (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false'
|
||||
uses: dtolnay/rust-toolchain@nightly
|
||||
with:
|
||||
toolchain: nightly-2026-04-29
|
||||
components: ${{ inputs.rust_checks == 'true' && 'clippy, rustfmt' || '' }}
|
||||
targets: ${{ inputs.target }}
|
||||
- name: Install Linux build prerequisites
|
||||
if: runner.os == 'Linux'
|
||||
- name: Install Linux build prerequisites (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false' && runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential
|
||||
- name: Prepend rustup toolchain bin to PATH
|
||||
- name: Prepend rustup toolchain bin to PATH (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false'
|
||||
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.
|
||||
# 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. (ensure-rust-toolchain already does this on omp-kata.)
|
||||
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 deciding whether to restore 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.
|
||||
#
|
||||
# On GitHub-hosted runners, rust-cache can still warm target/. On omp-kata,
|
||||
# the shared RustFS-backed sccache is the primary reuse layer and avoids a
|
||||
# second GitHub-cache restore for Cargo dirs/target.
|
||||
|
||||
# --- Rust flags (shared) ------------------------------------------------
|
||||
- name: Configure native Rust flags
|
||||
if: inputs.target == ''
|
||||
shell: bash
|
||||
@@ -95,34 +118,40 @@ runs:
|
||||
|
||||
echo "RUSTFLAGS=$rustflags" >> "$GITHUB_ENV"
|
||||
echo "Configured RUSTFLAGS=$rustflags"
|
||||
- name: Decide Rust artifact cache
|
||||
id: rust_artifact_cache
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -n "${SCCACHE_BUCKET:-}" ]; then
|
||||
echo "use_rust_cache=false" >> "$GITHUB_OUTPUT"
|
||||
echo "Rust target cache: skipped on shared-sccache runners"
|
||||
else
|
||||
echo "use_rust_cache=true" >> "$GITHUB_OUTPUT"
|
||||
echo "Rust target cache: GitHub Actions"
|
||||
fi
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
if: steps.rust_artifact_cache.outputs.use_rust_cache == 'true'
|
||||
|
||||
# --- 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 mounted Cargo registry +
|
||||
# RustFS sccache are the reuse layers, so there is no second cache restore.
|
||||
- name: Cache Rust target/ (GitHub-hosted)
|
||||
if: steps.detect.outputs.on_infra == 'false'
|
||||
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
|
||||
|
||||
# --- sccache ------------------------------------------------------------
|
||||
- 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
|
||||
# `CARGO_INCREMENTAL=0` is required: sccache silently skips caching when
|
||||
# incremental is enabled, turning the wrapper into a no-op. The backend
|
||||
# is conditional: self-hosted omp-kata runners inject a shared S3 (RustFS)
|
||||
# cache via pod env (SCCACHE_BUCKET/ENDPOINT/REGION + AWS creds) that
|
||||
# sccache reads from the inherited environment; GitHub-hosted runners
|
||||
# (macOS, ubuntu-arm) can't reach the private RustFS and keep the GHA
|
||||
# cache backend.
|
||||
# CARGO_INCREMENTAL=0 is required: sccache silently skips caching when
|
||||
# incremental is enabled, turning the wrapper into a no-op. The backend is
|
||||
# conditional: omp-kata reads the shared S3 (RustFS) config from the
|
||||
# inherited pod env; GitHub-hosted runners use the GHA cache backend.
|
||||
shell: bash
|
||||
run: |
|
||||
{
|
||||
@@ -135,33 +164,64 @@ runs:
|
||||
echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV"
|
||||
echo "sccache backend: GitHub Actions cache"
|
||||
fi
|
||||
- uses: taiki-e/install-action@v2
|
||||
if: inputs.target == ''
|
||||
|
||||
# --- 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 == ''
|
||||
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 == ''
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: nextest
|
||||
|
||||
- uses: ./.github/actions/bun-install
|
||||
# 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')
|
||||
|
||||
# --- Cross-compile toolchains -------------------------------------------
|
||||
# Non-MSVC targets (e.g. aarch64-unknown-linux-gnu) build with
|
||||
# cargo-zigbuild (needs zig); MSVC targets (e.g. x86_64-pc-windows-msvc)
|
||||
# build with cargo-xwin (needs clang/lld/llvm). The napi CLI's
|
||||
# --cross-compile flag picks the backend; we just install what it needs.
|
||||
# Cross builds only run on push/main + release (omp-kata), so the
|
||||
# GitHub-hosted cross branches exist for portability and never fire here.
|
||||
- name: Ensure baked zig (omp-kata, non-MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'true' && inputs.target != '' && !endsWith(inputs.target, '-msvc')
|
||||
uses: ./.github/actions/ensure-zig
|
||||
with:
|
||||
version: "0.16.0"
|
||||
- name: Setup zig (GitHub-hosted, non-MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'false' && 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')
|
||||
- name: Ensure baked cargo-zigbuild (omp-kata, non-MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'true' && inputs.target != '' && !endsWith(inputs.target, '-msvc')
|
||||
uses: ./.github/actions/ensure-cargo-tool
|
||||
with:
|
||||
binary: cargo-zigbuild
|
||||
crate: cargo-zigbuild
|
||||
- name: Install cargo-zigbuild (GitHub-hosted, non-MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'false' && 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')
|
||||
- name: Install LLVM tooling (GitHub-hosted, MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'false' && 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')
|
||||
- name: Ensure baked cargo-xwin (omp-kata, MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'true' && endsWith(inputs.target, '-msvc')
|
||||
uses: ./.github/actions/ensure-cargo-tool
|
||||
with:
|
||||
binary: cargo-xwin
|
||||
crate: cargo-xwin
|
||||
- name: Install cargo-xwin (GitHub-hosted, MSVC cross)
|
||||
if: steps.detect.outputs.on_infra == 'false' && endsWith(inputs.target, '-msvc')
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-xwin
|
||||
@@ -175,15 +235,17 @@ runs:
|
||||
if: endsWith(inputs.target, '-msvc')
|
||||
shell: bash
|
||||
run: echo "XWIN_ACCEPT_LICENSE=1" >> "$GITHUB_ENV"
|
||||
|
||||
# --- Checks, build, upload (shared) -------------------------------------
|
||||
- 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.
|
||||
# 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
|
||||
@@ -201,7 +263,7 @@ runs:
|
||||
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 native_artifact_lookup canary keeps working even if org
|
||||
# defaults shift; bump if Rust source ever stays stable for >90 days
|
||||
# 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
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
name: "bun install (shared cache)"
|
||||
description: >
|
||||
Ensure bun is on PATH, then run `bun install --frozen-lockfile` with a shared
|
||||
dependency cache. bun setup is skipped when the runner image already ships it
|
||||
package store. bun setup is skipped when the runner image already ships it
|
||||
(the preloaded omp-kata image), and only fetched on runners that lack it
|
||||
(e.g. GitHub-hosted). The cache uses the in-cluster RustFS S3 when the sccache
|
||||
credentials are present, and the stock actions/cache backend otherwise.
|
||||
(e.g. GitHub-hosted). Self-hosted omp-kata runners use the mounted Bun store
|
||||
PVC; GitHub-hosted runners use the stock actions/cache backend.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
@@ -24,10 +24,11 @@ runs:
|
||||
fi
|
||||
# The repo keys "are we on can.internal infra?" off $SCCACHE_BUCKET (see
|
||||
# actions/build-native). RUNNER_ENVIRONMENT is empty on ARC pods, so it
|
||||
# is not a usable signal here.
|
||||
if [ -n "${SCCACHE_BUCKET:-}" ] && [ -n "${AWS_ACCESS_KEY_ID:-}" ]; then
|
||||
echo "cache=rustfs" >> "$GITHUB_OUTPUT"
|
||||
echo "bun cache backend: RustFS S3 ($SCCACHE_BUCKET @ $SCCACHE_ENDPOINT)"
|
||||
# is not a usable signal here. On infra, the ARC pod mounts the shared
|
||||
# Bun store at the default cache path; off infra, actions/cache restores it.
|
||||
if [ -n "${SCCACHE_BUCKET:-}" ]; then
|
||||
echo "cache=mounted" >> "$GITHUB_OUTPUT"
|
||||
echo "bun cache backend: mounted PVC (${BUN_INSTALL_CACHE_DIR:-${HOME}/.bun/install/cache})"
|
||||
else
|
||||
echo "cache=gha" >> "$GITHUB_OUTPUT"
|
||||
echo "bun cache backend: GitHub Actions cache"
|
||||
@@ -48,17 +49,13 @@ runs:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
|
||||
|
||||
# On-infra (omp-kata): RustFS store + node_modules over the LAN.
|
||||
- name: Restore bun caches (RustFS)
|
||||
if: steps.env.outputs.cache == 'rustfs'
|
||||
# On-infra (omp-kata): the pod mounts a shared PVC at bun's store path.
|
||||
- name: Prepare mounted bun store
|
||||
if: steps.env.outputs.cache == 'mounted'
|
||||
shell: bash
|
||||
run: bash "$GITHUB_ACTION_PATH/rustfs-cache.sh" restore
|
||||
run: mkdir -p "${BUN_INSTALL_CACHE_DIR:-${HOME}/.bun/install/cache}"
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Save bun caches (RustFS)
|
||||
if: steps.env.outputs.cache == 'rustfs'
|
||||
shell: bash
|
||||
run: bash "$GITHUB_ACTION_PATH/rustfs-cache.sh" save
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared bun dependency cache backed by the in-cluster RustFS (S3) object store.
|
||||
#
|
||||
# Used by .github/actions/bun-install on the self-hosted omp-kata runners. There
|
||||
# the stock `actions/cache` restore of ~/.bun/install/cache costs 130-186s per
|
||||
# job because GitHub's cache backend is only reachable over the node's NAT
|
||||
# egress, and ~9 jobs contend on it at once. RustFS lives in the same k3s node
|
||||
# (svc :9000, already allowed by the runner egress NetworkPolicy), so the same
|
||||
# payload moves at LAN speed.
|
||||
#
|
||||
# Credentials are the ones sccache already gets via the `sccache-s3` secret
|
||||
# (envFrom on every runner pod): AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY /
|
||||
# SCCACHE_ENDPOINT / SCCACHE_BUCKET / SCCACHE_REGION / SCCACHE_S3_USE_SSL.
|
||||
#
|
||||
# Two objects per lockfile, under the bun-cache/ key prefix of the sccache
|
||||
# bucket:
|
||||
# store-<os>-<lockhash> the bun global package store (~/.bun/install/cache)
|
||||
# nm-<os>-<lockhash> the installed node_modules trees (root + workspaces)
|
||||
# The store additionally publishes a rolling store-<os>-latest alias, so a
|
||||
# changed lockfile still warm-starts from the previous store and `bun install`
|
||||
# only fetches the delta. A node_modules hit short-circuits everything: the
|
||||
# subsequent `bun install --frozen-lockfile` is a no-op, so the store is neither
|
||||
# fetched nor saved.
|
||||
set -euo pipefail
|
||||
|
||||
mode="${1:?usage: rustfs-cache.sh restore|save}"
|
||||
|
||||
: "${SCCACHE_BUCKET:?SCCACHE_BUCKET required}"
|
||||
: "${SCCACHE_ENDPOINT:?SCCACHE_ENDPOINT required}"
|
||||
: "${AWS_ACCESS_KEY_ID:?AWS_ACCESS_KEY_ID required}"
|
||||
: "${AWS_SECRET_ACCESS_KEY:?AWS_SECRET_ACCESS_KEY required}"
|
||||
|
||||
region="${SCCACHE_REGION:-us-east-1}"
|
||||
if [ "${SCCACHE_S3_USE_SSL:-false}" = "true" ]; then scheme=https; else scheme=http; fi
|
||||
base="${scheme}://${SCCACHE_ENDPOINT}/${SCCACHE_BUCKET}/bun-cache"
|
||||
os="${RUNNER_OS:-$(uname -s)}"
|
||||
store_dir="${BUN_INSTALL_CACHE_DIR:-${HOME}/.bun/install/cache}"
|
||||
work="${RUNNER_TEMP:-/tmp}/bun-rustfs-cache"
|
||||
mkdir -p "$work"
|
||||
|
||||
# Prefer multi-threaded zstd (baked into the omp-kata runner image); fall back to
|
||||
# gzip so the action still works on an image that predates the zstd addition. The
|
||||
# object suffix records the codec, and restore only inflates archives this host
|
||||
# can actually decompress.
|
||||
if command -v zstd >/dev/null 2>&1; then
|
||||
tar_c=(-I "zstd -3 -T0"); ext="tzst"; alt_ext="tgz"
|
||||
else
|
||||
tar_c=(-I "gzip -6"); ext="tgz"; alt_ext="tzst"
|
||||
fi
|
||||
|
||||
lock_hash="$(sha256sum bun.lock | cut -c1-32)"
|
||||
store_key="store-${os}-${lock_hash}"
|
||||
store_latest="store-${os}-latest"
|
||||
nm_key="nm-${os}-${lock_hash}"
|
||||
|
||||
auth=(--aws-sigv4 "aws:amz:${region}:s3" --user "${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}")
|
||||
# 404 (-f) and connection errors are non-zero; transient errors retry, 4xx do not.
|
||||
s3_get() { curl -fsS --retry 3 --retry-connrefused "${auth[@]}" "${base}/$1" -o "$2"; }
|
||||
s3_exists() { curl -fsS -I --retry 3 --retry-connrefused "${auth[@]}" "${base}/$1" -o /dev/null >/dev/null 2>&1; }
|
||||
s3_put() { curl -fsS --retry 3 --retry-connrefused "${auth[@]}" -T "$2" "${base}/$1" -o /dev/null; }
|
||||
|
||||
# Download <name>.<ext> (then the alternate codec) and extract into dir $2.
|
||||
# tar auto-detects the codec from the archive; a present-but-uninflatable archive
|
||||
# (codec mismatch with this host) is treated as a miss.
|
||||
fetch_extract() { # name dest
|
||||
local name="$1" dest="$2" e f
|
||||
for e in "$ext" "$alt_ext"; do
|
||||
f="${work}/${name}.${e}"
|
||||
if s3_get "${name}.${e}" "$f" 2>/dev/null; then
|
||||
mkdir -p "$dest"
|
||||
if tar -xf "$f" -C "$dest" 2>/dev/null; then rm -f "$f"; return 0; fi
|
||||
rm -f "$f"
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
case "$mode" in
|
||||
restore)
|
||||
if fetch_extract "$nm_key" "$PWD"; then
|
||||
echo "bun cache: node_modules HIT ($nm_key) — install becomes a no-op"
|
||||
: > "${work}/nm_hit"
|
||||
exit 0
|
||||
fi
|
||||
echo "bun cache: node_modules miss ($nm_key)"
|
||||
if fetch_extract "$store_key" "$store_dir"; then
|
||||
echo "bun cache: store HIT ($store_key)"
|
||||
elif fetch_extract "$store_latest" "$store_dir"; then
|
||||
echo "bun cache: store warm-start ($store_latest)"
|
||||
else
|
||||
echo "bun cache: store miss — cold install"
|
||||
fi
|
||||
;;
|
||||
save)
|
||||
if [ -f "${work}/nm_hit" ]; then
|
||||
echo "bun cache: node_modules was a hit — nothing to save"
|
||||
exit 0
|
||||
fi
|
||||
# Store (+ rolling latest): save when this exact lockfile has none yet.
|
||||
if [ -d "$store_dir" ] && ! s3_exists "${store_key}.${ext}"; then
|
||||
tar "${tar_c[@]}" -cf "${work}/store.${ext}" -C "$store_dir" .
|
||||
s3_put "${store_key}.${ext}" "${work}/store.${ext}"
|
||||
s3_put "${store_latest}.${ext}" "${work}/store.${ext}"
|
||||
rm -f "${work}/store.${ext}"
|
||||
echo "bun cache: saved store ($store_key + $store_latest)"
|
||||
fi
|
||||
# node_modules: save the installed trees for this exact lockfile.
|
||||
if ! s3_exists "${nm_key}.${ext}"; then
|
||||
shopt -s nullglob
|
||||
nm_paths=()
|
||||
for p in node_modules packages/*/node_modules python/robomp/web/node_modules; do
|
||||
[ -d "$p" ] && nm_paths+=("$p")
|
||||
done
|
||||
if [ ${#nm_paths[@]} -gt 0 ]; then
|
||||
tar "${tar_c[@]}" -cf "${work}/nm.${ext}" "${nm_paths[@]}"
|
||||
s3_put "${nm_key}.${ext}" "${work}/nm.${ext}"
|
||||
rm -f "${work}/nm.${ext}"
|
||||
echo "bun cache: saved node_modules ($nm_key, ${#nm_paths[@]} trees)"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "rustfs-cache.sh: unknown mode '$mode' (want restore|save)" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
+17
-14
@@ -44,7 +44,7 @@ jobs:
|
||||
# ref (or from a tagged main HEAD) is also treated as a release.
|
||||
release_metadata:
|
||||
name: Resolve release metadata
|
||||
runs-on: omp-kata
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
outputs:
|
||||
is-release: ${{ steps.detect.outputs.is-release }}
|
||||
release-tag: ${{ steps.detect.outputs.release-tag }}
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
# retention window (see build-native action) is the effective TTL.
|
||||
native_artifact_lookup:
|
||||
name: Look up cached native artifacts
|
||||
runs-on: omp-kata
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
outputs:
|
||||
source-hash: ${{ steps.compute.outputs.source-hash }}
|
||||
linux-x64-run-id: ${{ steps.find.outputs.linux-x64-run-id }}
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
# Fast lint, type check, and browser bundle build (no Rust, no native build needed)
|
||||
check:
|
||||
name: Lint, type check & web build
|
||||
runs-on: omp-kata
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/bun-install
|
||||
@@ -203,7 +203,7 @@ jobs:
|
||||
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 == '' }}
|
||||
runs-on: omp-kata
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -212,7 +212,7 @@ jobs:
|
||||
- { variant: modern }
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-native-kata
|
||||
- uses: ./.github/actions/build-native
|
||||
with:
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
platform: linux
|
||||
@@ -237,7 +237,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-native-kata
|
||||
- uses: ./.github/actions/build-native
|
||||
with:
|
||||
hash: ${{ needs.native_artifact_lookup.outputs.source-hash }}
|
||||
platform: ${{ matrix.platform }}
|
||||
@@ -269,12 +269,13 @@ jobs:
|
||||
save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
test_workspace:
|
||||
name: Test TS workspace fast
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
@@ -298,12 +299,13 @@ jobs:
|
||||
|
||||
test_coding_agent_singleton:
|
||||
name: Test coding-agent singleton/global-state (TS)
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
@@ -329,7 +331,7 @@ jobs:
|
||||
|
||||
test_ts_native:
|
||||
name: Test TS native/integration packages
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 25
|
||||
@@ -359,7 +361,7 @@ jobs:
|
||||
|
||||
test_coding_agent_ui:
|
||||
name: Test coding-agent UI/TUI (TS)
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 25
|
||||
@@ -389,12 +391,13 @@ jobs:
|
||||
|
||||
test_coding_agent_runtime:
|
||||
name: Test coding-agent runtime/session (TS)
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup-system-deps
|
||||
- uses: ./.github/actions/bun-install
|
||||
- name: Resolve Linux x64 native artifact run
|
||||
id: source
|
||||
@@ -420,7 +423,7 @@ jobs:
|
||||
|
||||
test_coding_agent_native:
|
||||
name: Test coding-agent native/unit (TS)
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 25
|
||||
@@ -450,7 +453,7 @@ jobs:
|
||||
|
||||
test_smoke:
|
||||
name: Test CLI smoke (TS)
|
||||
runs-on: omp-kata
|
||||
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' }}
|
||||
timeout-minutes: 15
|
||||
@@ -480,7 +483,7 @@ jobs:
|
||||
|
||||
install_methods:
|
||||
name: Install method smoke tests
|
||||
runs-on: omp-kata
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/ensure-rust-toolchain
|
||||
|
||||
Reference in New Issue
Block a user