From 0820085890f2c54ac3fb7edc49668aae5f2a1241 Mon Sep 17 00:00:00 2001 From: can1357 Date: Tue, 28 Jul 2026 11:55:57 +0200 Subject: [PATCH] ci: restructured workflow pipelines and introduced bazel cache actions - Updated bazel cache key generation with v2 schema version and streamlined remote cache usage. - Added native-inputs composite action to centralize change detection and artifact caching. - Added a scheduled workflow to warm the hosted bazel disk cache. - Split the rust validation job and integrated prebuilt native addon caching into the CI pipeline. --- .github/actions/bazel-cache/action.yml | 67 ++----- .github/actions/native-inputs/action.yml | 72 +++++++ .github/workflows/bazel-cache-warm.yml | 43 +++++ .github/workflows/ci.yml | 229 +++++++++++++++++------ 4 files changed, 308 insertions(+), 103 deletions(-) create mode 100644 .github/actions/native-inputs/action.yml create mode 100644 .github/workflows/bazel-cache-warm.yml diff --git a/.github/actions/bazel-cache/action.yml b/.github/actions/bazel-cache/action.yml index 23bdab8a0..de54e3a7a 100644 --- a/.github/actions/bazel-cache/action.yml +++ b/.github/actions/bazel-cache/action.yml @@ -1,24 +1,20 @@ name: "Compose bazel cache config" description: > Selects the CI cache backend and emits a bazelrc fragment. A shell probe - exposes the backend through step outputs before any action condition uses it. + exposes the backend through step outputs before any action condition + uses it. - omp-kata jobs use the cluster remote cache. An exporting main job first - performs an exact GitHub cache lookup without downloading the archive. A - genuine miss switches that job to a local disk cache for one build. The - workflow saves that populated cache explicitly after the build. - - GitHub-hosted jobs restore the exported disk cache and never contact the - cluster. Build callers can save a new exact-key archive after a miss. + omp-kata jobs use the cluster remote cache. GitHub-hosted jobs use an + actions/cache-backed disk cache seeded by the bazel-cache-warm workflow + on the same runner image — cross-host action keys never hit, so the disk + cache is hosted-only and its key carries a schema version (v2; v1 was + poisoned by a kata-produced export that silently missed every action). + Consumers save a new exact-key archive after a miss. inputs: scope: description: Disk-cache key discriminator shared by compatible consumers required: true - export: - description: Prepare a portable disk cache after an exact lookup miss - required: false - default: "false" outputs: rc: @@ -27,9 +23,6 @@ outputs: cache-key: description: Exact GitHub cache key for a later explicit save value: ${{ steps.backend.outputs.cache-key }} - export-needed: - description: Whether the remote exporter switched to a portable disk cache - value: ${{ steps.compose.outputs.export-needed }} save-needed: description: Whether a disk-cache build can save a new exact-key archive value: ${{ steps.compose.outputs.save-needed }} @@ -44,7 +37,7 @@ runs: id: backend shell: bash env: - CACHE_KEY: bazel-disk-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.Bazel.lock', 'MODULE.bazel', 'rust-toolchain.toml') }} + CACHE_KEY: bazel-disk-v2-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.Bazel.lock', 'MODULE.bazel', 'MODULE.bazel.lock', 'rust-toolchain.toml', '.bazelrc', '.bazelversion', 'bazel/**') }} run: | set -euo pipefail remote=false @@ -68,32 +61,17 @@ runs: path: ~/.cache/omp-bazel-disk key: ${{ steps.backend.outputs.cache-key }} restore-keys: | - bazel-disk-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}- - - - name: Look up bazel disk cache export - if: steps.backend.outputs.remote == 'true' && inputs.export == 'true' - id: export - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: ~/.cache/omp-bazel-disk - key: ${{ steps.backend.outputs.cache-key }} - lookup-only: true + bazel-disk-v2-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}- - name: Compose cache config id: compose shell: bash env: REMOTE: ${{ steps.backend.outputs.remote }} - EXPORT_REQUESTED: ${{ inputs.export }} - EXPORT_HIT: ${{ steps.export.outputs.cache-hit }} RESTORE_HIT: ${{ steps.restore.outputs.cache-hit }} run: | set -euo pipefail - export_needed=false - if [ "$REMOTE" = "true" ] && [ "$EXPORT_REQUESTED" = "true" ] && [ "$EXPORT_HIT" != "true" ]; then - export_needed=true - fi - save_needed=$export_needed + save_needed=false if [ "$REMOTE" != "true" ] && [ "$RESTORE_HIT" != "true" ]; then save_needed=true fi @@ -107,26 +85,16 @@ runs: echo "common --config=ci" echo "common --repository_cache=/opt/bazel-repo-cache" echo "common --repo_env=OMP_XWIN_CACHE_DIR=/opt/bazel-repo-cache/xwin" - } > "$rc" - - if [ "$export_needed" = "true" ]; then - # Do not combine remote and disk caches. Remote hits do not - # materialize a portable disk cache for hosted runners. - mkdir -p "$HOME/.cache/omp-bazel-disk" - echo "common --disk_cache=$HOME/.cache/omp-bazel-disk" >> "$rc" - else raw_auth="${BAZEL_REMOTE_USER}:${BAZEL_REMOTE_PASSWORD}" auth="$(printf %s "$raw_auth" | base64 | tr -d '\n')" echo "::add-mask::$raw_auth" echo "::add-mask::$auth" - { - echo "common --config=cache-rw" - echo "common --remote_cache=grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092" - echo "common --tls_certificate=infra/bazel-remote/ca.crt" - echo "common --remote_header='authorization=Basic ${auth}'" - echo "common --remote_download_toplevel" - } >> "$rc" - fi + echo "common --config=cache-rw" + echo "common --remote_cache=grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092" + echo "common --tls_certificate=infra/bazel-remote/ca.crt" + echo "common --remote_header='authorization=Basic ${auth}'" + echo "common --remote_download_toplevel" + } > "$rc" else mkdir -p "$HOME/.cache/omp-bazel-disk" "$HOME/.cache/omp-bazel-repo" { @@ -138,6 +106,5 @@ runs: { echo "rc=$rc" - echo "export-needed=$export_needed" echo "save-needed=$save_needed" } >> "$GITHUB_OUTPUT" diff --git a/.github/actions/native-inputs/action.yml b/.github/actions/native-inputs/action.yml new file mode 100644 index 000000000..cc7c5b9b6 --- /dev/null +++ b/.github/actions/native-inputs/action.yml @@ -0,0 +1,72 @@ +name: "Native inputs: change detection + artifact cache key" +description: > + Single source of truth for what counts as a native-affecting change. + + `rust` gates Rust validation (tests, clippy, rustfmt); `cache-key` + addresses the prebuilt Linux x64 addon pair published by trusted main + builds. The detector pathspec and the hashed file set MUST cover the same + inputs — drift means a native change could ship without validation or be + tested against stale addons. The key embeds a schema version, OS, arch, + target pair, and build profile so a future target/profile change can + never resolve valid-but-wrong .node files under the same source hash. + +outputs: + rust: + description: Whether the event touches native inputs (always true off pull_request) + value: ${{ steps.changes.outputs.rust }} + source-hash: + description: 16-hex fingerprint over every native build input + value: ${{ steps.hash.outputs.source-hash }} + cache-key: + description: Exact actions/cache key for the prebuilt Linux x64 addon pair + value: ${{ steps.hash.outputs.cache-key }} + +runs: + using: composite + steps: + - name: Detect native-affecting changes + id: changes + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + if [ "${{ github.event_name }}" != "pull_request" ]; then + echo "rust=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + if gh pr diff ${{ github.event.pull_request.number }} --name-only \ + | grep -qE '^(crates/|bazel/|Cargo\.(toml|lock)|Cargo\.Bazel\.lock|MODULE\.bazel(\.lock)?|BUILD\.bazel|\.bazelrc|\.bazelignore|\.bazelversion|rust-toolchain\.toml|rustfmt\.toml|scripts/bazel-natives\.ts|\.github/actions/(bazel-cache|bazel-natives|native-artifacts|native-inputs)/|\.github/workflows/ci\.yml)'; then + echo "rust=true" >> "$GITHUB_OUTPUT" + else + echo "No native-affecting changes; skipping Rust validation." + echo "rust=false" >> "$GITHUB_OUTPUT" + fi + + # Content-addresses the addon bytes. `git ls-files` covers path + + # content + mode of every tracked input; a listed path that disappears + # fails the step loudly instead of silently narrowing the key. + - name: Compute native source hash + id: hash + shell: bash + run: | + set -euo pipefail + source_hash=$(git ls-files -z -- \ + crates bazel \ + Cargo.toml Cargo.lock Cargo.Bazel.lock \ + MODULE.bazel MODULE.bazel.lock BUILD.bazel \ + .bazelrc .bazelignore .bazelversion \ + rust-toolchain.toml rustfmt.toml \ + scripts/bazel-natives.ts \ + .github/actions/bazel-cache .github/actions/bazel-natives \ + .github/actions/native-artifacts .github/actions/native-inputs \ + .github/workflows/ci.yml \ + | sort -z \ + | xargs -0 sha256sum \ + | sha256sum \ + | cut -c1-16) + { + echo "source-hash=$source_hash" + echo "cache-key=native-addons-v1-linux-x64-baseline+modern-opt-$source_hash" + } >> "$GITHUB_OUTPUT" + echo "Native source hash: $source_hash" diff --git a/.github/workflows/bazel-cache-warm.yml b/.github/workflows/bazel-cache-warm.yml new file mode 100644 index 000000000..ddcf3204e --- /dev/null +++ b/.github/workflows/bazel-cache-warm.yml @@ -0,0 +1,43 @@ +name: Warm bazel disk cache + +# GitHub-hosted PR runners cannot use the cluster remote cache and only see +# actions/cache entries created on the default branch. Bazel action keys do +# not transfer across runner environments (a kata-produced disk cache misses +# every action on ubuntu-22.04), so seed the disk cache from the same image +# PR jobs run on. A warm run restores the exact-key archive, builds +# incrementally, and saves nothing; a lockfile/config change misses, rebuilds, +# and saves the new key. + +on: + schedule: + - cron: "23 */6 * * *" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: bazel-cache-warm + cancel-in-progress: true + +jobs: + warm: + name: Seed hosted bazel disk cache + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - id: cache + uses: ./.github/actions/bazel-cache + with: + scope: linux + - name: Build native addons + run: | + set -euo pipefail + if [ "$(ulimit -Sn)" != unlimited ] && [ "$(ulimit -Sn)" -lt 65536 ]; then ulimit -Sn 65536 || true; fi + bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build //:natives-linux-x64-baseline //:natives-linux-x64-modern + - name: Save bazel disk cache + if: steps.cache.outputs.save-needed == 'true' + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.cache/omp-bazel-disk + key: ${{ steps.cache.outputs.cache-key }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 812b3ba03..fc4501b9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,44 +118,26 @@ jobs: - name: Build collab web run: bun run collab:web:build - # One Bazel job validates Rust changes and builds native addons for every - # downstream job. Main builds all Linux-hosted targets. Pull requests build - # only the Linux x64 pair required by tests. - rust: + # Rust validation (tests, clippy, rustfmt) and native addon production are + # separate jobs: TS test shards wait only on the addons, and on + # native-changing PRs validation no longer delays artifact production. + rust_validate: name: Validate Rust workspace (bazel) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} steps: - uses: actions/checkout@v4 - # TS-only PRs skip Rust validation. They still materialize the Linux - # x64 addons once from the main-exported disk cache. - - name: Detect Rust-affecting changes - id: changes - shell: bash - env: - GH_TOKEN: ${{ github.token }} - run: | - if [ "${{ github.event_name }}" != "pull_request" ]; then - echo "rust=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - if gh pr diff ${{ github.event.pull_request.number }} --name-only \ - | grep -qE '^(crates/|Cargo\.(toml|lock)|Cargo\.Bazel\.lock|MODULE\.bazel|BUILD\.bazel|\.bazelrc|\.bazelversion|bazel/|rust-toolchain\.toml|rustfmt\.toml|scripts/bazel-natives|\.github/actions/bazel-|\.github/workflows/ci\.yml)'; then - echo "rust=true" >> "$GITHUB_OUTPUT" - else - echo "No Rust-affecting changes; skipping validation." - echo "rust=false" >> "$GITHUB_OUTPUT" - fi - - if: steps.changes.outputs.rust == 'true' + - id: inputs + uses: ./.github/actions/native-inputs + # TS-only PRs skip Rust validation entirely. + - if: steps.inputs.outputs.rust == 'true' uses: ./.github/actions/bun-install - id: cache + if: steps.inputs.outputs.rust == 'true' uses: ./.github/actions/bazel-cache with: scope: linux - # Main pushes export the disk cache PRs restore (once per - # lockfile change; no-op otherwise). - export: ${{ github.event_name != 'pull_request' }} - name: Rust tests - if: steps.changes.outputs.rust == 'true' + if: steps.inputs.outputs.rust == 'true' # The ulimit guard runs in the step that launches the bazel server # (limits are per-process and the server persists across steps). run: | @@ -166,35 +148,175 @@ jobs: # `[lints] workspace = true` get the workspace policy, the vendored # brush fork is exempt (same as run-rs-task.ts's cargo excludes). - name: Clippy (workspace lint policy on opted-in crates) - if: steps.changes.outputs.rust == 'true' + if: steps.inputs.outputs.rust == 'true' run: | bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...)" \ | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy-strict -- - name: Clippy (default lints elsewhere) - if: steps.changes.outputs.rust == 'true' + if: steps.inputs.outputs.rust == 'true' run: | bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (//crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \ | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy -- - name: Rustfmt - if: steps.changes.outputs.rust == 'true' + if: steps.inputs.outputs.rust == 'true' run: bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=rustfmt //crates/... + + # Builds the native addons every downstream job installs. TS-only PRs + # restore the prebuilt Linux x64 pair published by trusted main builds + # (exact content-addressed key, smoke-loaded before use) and skip Bazel + # entirely; anything else builds with bazel. Main builds all Linux-hosted + # targets, pull requests only the x64 pair tests require. + native_addons: + name: Build native addons (bazel) + runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} + steps: + - uses: actions/checkout@v4 + - id: inputs + uses: ./.github/actions/native-inputs + # Trusted fast path. Exact-key restores only — a prefix fallback + # could resolve valid-but-wrong .node files under a changed + # target/profile (the key embeds schema + os/arch + target pair + + # build profile + input hash; see native-inputs action). + - name: Restore prebuilt native addons + id: prebuilt + if: github.event_name == 'pull_request' + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.cache/omp-native-addons + key: ${{ steps.inputs.outputs.cache-key }} + - name: Stage cached addons + if: steps.prebuilt.outputs.cache-hit == 'true' + shell: bash + # Canonical filenames come from the target map in + # scripts/bazel-natives.ts; staging reproduces the bazel-bin + # layout the artifact upload below globs. + run: | + set -euo pipefail + mkdir -p bazel-bin/natives-linux-x64-baseline bazel-bin/natives-linux-x64-modern + cp ~/.cache/omp-native-addons/pi_natives.linux-x64-baseline.node bazel-bin/natives-linux-x64-baseline/ + cp ~/.cache/omp-native-addons/pi_natives.linux-x64-modern.node bazel-bin/natives-linux-x64-modern/ + # A poisoned cache entry must not ship: load both addons before + # trusting them. Failure falls back to a full build (loudly) rather + # than failing the PR. + - name: Smoke cached addons + id: smoke + if: steps.prebuilt.outputs.cache-hit == 'true' + shell: bash + run: | + set -uo pipefail + # NOTE: `bun -e 'require("./x.node")'` swallows dlopen failures + # (exit 0 on a bogus addon); a script file enforces them in + # both bun and node. Verified against a corrupt .node fixture. + cat > "$RUNNER_TEMP/smoke-addons.js" <<'EOF' + for (const f of process.argv.slice(2)) { + const m = require(f); + if (!m || Object.keys(m).length === 0) { + console.error(`addon failed to load: ${f}`); + process.exit(1); + } + } + EOF + loader=node + if command -v bun >/dev/null 2>&1; then loader=bun; fi + if "$loader" "$RUNNER_TEMP/smoke-addons.js" \ + "$PWD/bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node" \ + "$PWD/bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node"; then + echo "ok=true" >> "$GITHUB_OUTPUT" + else + echo "::warning::cached native addons failed to load; falling back to a full bazel build" + rm -rf bazel-bin + echo "ok=false" >> "$GITHUB_OUTPUT" + fi + - name: Decide build path + id: decide + shell: bash + env: + HIT: ${{ steps.prebuilt.outputs.cache-hit }} + SMOKE: ${{ steps.smoke.outputs.ok }} + run: | + if [ "$HIT" = "true" ] && [ "$SMOKE" = "true" ]; then + echo "Prebuilt addons restored and verified; skipping bazel." + echo "needed=false" >> "$GITHUB_OUTPUT" + else + echo "needed=true" >> "$GITHUB_OUTPUT" + fi + - id: cache + if: steps.decide.outputs.needed == 'true' + uses: ./.github/actions/bazel-cache + with: + scope: linux - name: Build native addons once + if: steps.decide.outputs.needed == 'true' env: EVENT_NAME: ${{ github.event_name }} run: | - set -euo pipefail + set -eo pipefail if [ "$(ulimit -Sn)" != unlimited ] && [ "$(ulimit -Sn)" -lt 65536 ]; then ulimit -Sn 65536 || true; fi targets=(//:natives-linux-x64-baseline //:natives-linux-x64-modern) if [ "$EVENT_NAME" != "pull_request" ]; then targets=(//:natives-linux-all) fi - bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build "${targets[@]}" + bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build "${targets[@]}" 2>&1 | tee "$RUNNER_TEMP/bazel-build.log" + # Cache-hit visibility: a supposedly warm build that executes + # thousands of actions is the failure mode that made CI slow — make + # it visible in the run summary instead of discovering it weeks in. + - name: Report bazel cache stats + if: steps.decide.outputs.needed == 'true' + shell: bash + run: | + summary=$(grep -E "INFO: [0-9]+ processes:" "$RUNNER_TEMP/bazel-build.log" | tail -1 || true) + echo "::notice title=Bazel build summary::${summary:-no process summary found}" - name: Save Bazel disk cache if: steps.cache.outputs.save-needed == 'true' uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ~/.cache/omp-bazel-disk key: ${{ steps.cache.outputs.cache-key }} + # Producer side of the fast path: trusted main builds publish the + # x64 pair under the content-addressed key. Smoke-load before save — + # an exact-key archive is never overwritten, so bad bytes would + # poison every TS-only PR until manual eviction. + - name: Stage built addons for cache + if: github.event_name != 'pull_request' + shell: bash + run: | + set -euo pipefail + mkdir -p ~/.cache/omp-native-addons + cp bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node \ + bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node \ + ~/.cache/omp-native-addons/ + - name: Smoke addons before caching + if: github.event_name != 'pull_request' + shell: bash + run: | + set -euo pipefail + cd ~/.cache/omp-native-addons + cat > "$RUNNER_TEMP/smoke-addons.js" <<'EOF' + for (const f of process.argv.slice(2)) { + const m = require(f); + if (!m || Object.keys(m).length === 0) { + console.error(`addon failed to load: ${f}`); + process.exit(1); + } + } + EOF + bun "$RUNNER_TEMP/smoke-addons.js" \ + "$PWD/pi_natives.linux-x64-baseline.node" \ + "$PWD/pi_natives.linux-x64-modern.node" + - name: Look up native addon cache + id: addon-cache + if: github.event_name != 'pull_request' + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.cache/omp-native-addons + key: ${{ steps.inputs.outputs.cache-key }} + lookup-only: true + - name: Save native addon cache + if: github.event_name != 'pull_request' && steps.addon-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.cache/omp-native-addons + key: ${{ steps.inputs.outputs.cache-key }} - name: Upload native addon artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: @@ -206,8 +328,8 @@ jobs: test_workspace: name: Test TS workspace fast runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 20 steps: - uses: actions/checkout@v4 @@ -224,8 +346,8 @@ jobs: test_coding_agent_singleton: name: Test coding-agent singleton/global-state (TS) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 20 steps: - uses: actions/checkout@v4 @@ -242,8 +364,8 @@ jobs: test_ts_native: name: Test TS native/integration packages runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 25 steps: - uses: actions/checkout@v4 @@ -260,8 +382,8 @@ jobs: test_coding_agent_ui: name: Test coding-agent UI/TUI (TS) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 25 steps: - uses: actions/checkout@v4 @@ -278,8 +400,8 @@ jobs: test_coding_agent_runtime: name: Test coding-agent runtime/session (TS) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 25 steps: - uses: actions/checkout@v4 @@ -298,8 +420,8 @@ jobs: test_coding_agent_native: name: Test coding-agent native/unit (TS) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 25 steps: - uses: actions/checkout@v4 @@ -316,8 +438,8 @@ jobs: test_smoke: name: Test CLI smoke (TS) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} timeout-minutes: 15 steps: - uses: actions/checkout@v4 @@ -332,8 +454,8 @@ jobs: install_methods: name: Install method smoke tests runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} - needs: [rust] - if: ${{ !cancelled() && needs.rust.result == 'success' }} + needs: [native_addons] + if: ${{ !cancelled() && needs.native_addons.result == 'success' }} steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup-system-deps @@ -349,7 +471,8 @@ jobs: release_binary: name: "Release binary: ${{ matrix.target_id }}" if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && - needs.rust.result == 'success' && + needs.rust_validate.result == 'success' && + needs.native_addons.result == 'success' && needs.test_workspace.result == 'success' && needs.test_coding_agent_singleton.result == 'success' && needs.test_ts_native.result == 'success' && @@ -358,7 +481,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, rust, 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] + needs: [release_metadata, check, rust_validate, native_addons, 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] strategy: fail-fast: false matrix: @@ -447,7 +570,7 @@ jobs: path: ~/.bun/install/cache key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - run: bun install --frozen-lockfile - # Linux and Windows addons come from the Rust job. Darwin runners + # Linux and Windows addons come from the native_addons job. Darwin runners # build only their own architecture because cross-hosted artifacts do # not exist for macOS. - name: Install prebuilt native addon(s) @@ -621,7 +744,7 @@ jobs: key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - run: bun install --frozen-lockfile # The prepack executes workspace code which loads the Linux x64 - # addon, so install the Rust job's artifact before publishing. + # addon, so install the native_addons job's artifact before publishing. - name: Install prebuilt native addons uses: ./.github/actions/native-artifacts with: