Repository navigation
AgentENV as a first-class VM substrate (default on KVM) #169
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: supply-chain | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_HOME: /home/runner/.cargo | |
| RUSTUP_HOME: /home/runner/.rustup | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| schedule: | |
| - cron: "0 3 * * 1" | |
| workflow_dispatch: | |
| jobs: | |
| cargo: | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Drop PR-shipped cargo config | |
| run: rm -f .cargo/config .cargo/config.toml | |
| - name: Guard policy files | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| set -euo pipefail | |
| base="${{ github.event.pull_request.base.sha }}" | |
| # Ensure base is fetched for diff (fail closed on network/fetch error) | |
| git fetch --no-tags --depth=1 origin "$base" | |
| diff_files="$(git diff --name-only "$base...HEAD")" | |
| policy_files="$(echo "$diff_files" | grep -E '^(Cargo\.lock|deny\.toml|\.cargo/audit\.toml|supply-chain/|\.github/workflows/supply-chain\.yml)' || true)" | |
| non_policy_files="$(echo "$diff_files" | grep -vE '^(Cargo\.lock|deny\.toml|\.cargo/audit\.toml|supply-chain/|\.github/workflows/supply-chain\.yml)' | grep -v '^$' || true)" | |
| if [[ -n "$policy_files" && -n "$non_policy_files" ]]; then | |
| echo "ERROR: PR touches both supply-chain policy files and non-policy files." >&2 | |
| echo "Policy updates (Cargo.lock, deny.toml, .cargo/audit.toml, supply-chain/*) must be isolated in a dedicated PR." >&2 | |
| echo "Modified policy files:" >&2 | |
| echo "$policy_files" >&2 | |
| echo "Modified non-policy files:" >&2 | |
| echo "$non_policy_files" >&2 | |
| exit 1 | |
| fi | |
| if [[ -n "$policy_files" ]]; then | |
| echo "Dedicated supply-chain policy PR detected: OK" | |
| else | |
| echo "Policy file guard: OK (no policy files modified)" | |
| fi | |
| - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable | |
| with: | |
| toolchain: "1.97" | |
| - uses: taiki-e/install-action@6c6fd71fe4fb72c3697d269963d0e15df8adedad # v2.85.10 | |
| with: | |
| tool: cargo-vet@0.10.1,cargo-audit@0.22.2,cargo-deny@0.20.2 | |
| - name: cargo vet | |
| run: cargo vet --locked | |
| - name: cargo audit | |
| run: cargo audit | |
| - name: cargo deny check all | |
| run: cargo deny check all | |
| node-externals: | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Audit Node externals (OSV + SBOM) | |
| run: bash scripts/audit-node-externals.sh | |
| - name: Upload SBOM artifact | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: sbom-node-externals | |
| path: sbom-node-externals.cdx.json | |
| if-no-files-found: ignore | |
| check-node-pin-parity: | |
| runs-on: [self-hosted, preloop-cpane] | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Check Node pin parity against upstream externals.sh | |
| run: | | |
| set -euo pipefail | |
| runner_version="$(grep -E '^runner_version[[:space:]]*=' versions.toml | head -n1 | sed -E 's/.*"[[:space:]]*([^"]+)[[:space:]]*".*/\1/')" | |
| if [[ -z "$runner_version" ]]; then | |
| echo "failed to parse runner_version from versions.toml" >&2 | |
| exit 1 | |
| fi | |
| echo "runner_version from versions.toml: $runner_version" | |
| node20_local="$(grep -E '^node20_externals_version[[:space:]]*=' versions.toml | head -n1 | sed -E 's/.*"[[:space:]]*([^"]+)[[:space:]]*".*/\1/')" | |
| node24_local="$(grep -E '^node24_externals_version[[:space:]]*=' versions.toml | head -n1 | sed -E 's/.*"[[:space:]]*([^"]+)[[:space:]]*".*/\1/')" | |
| echo "Local pins: node20=$node20_local node24=$node24_local" | |
| url="https://raw.githubusercontent.com/actions/runner/v${runner_version}/src/Misc/externals.sh" | |
| echo "Fetching $url" | |
| curl -fsSL --retry 3 --retry-all-errors "$url" -o /tmp/externals.sh || true | |
| node20_upstream="$(grep -E 'NODE20_VERSION=' /tmp/externals.sh | head -n1 | sed -E 's/.*"([^"]+)".*/\1/' || true)" | |
| node24_upstream="$(grep -E 'NODE24_VERSION=' /tmp/externals.sh | head -n1 | sed -E 's/.*"([^"]+)".*/\1/' || true)" | |
| echo "Upstream externals.sh: NODE20_VERSION=$node20_upstream NODE24_VERSION=$node24_upstream" | |
| # Also check v2.337.0 upstream externals (documented forward-port in docs/fidelity-gap.md) | |
| curl -fsSL --retry 3 --retry-all-errors "https://raw.githubusercontent.com/actions/runner/v2.337.0/src/Misc/externals.sh" -o /tmp/externals_337.sh || true | |
| node20_337="$(grep -E 'NODE20_VERSION=' /tmp/externals_337.sh | head -n1 | sed -E 's/.*"([^"]+)".*/\1/' || true)" | |
| node24_337="$(grep -E 'NODE24_VERSION=' /tmp/externals_337.sh | head -n1 | sed -E 's/.*"([^"]+)".*/\1/' || true)" | |
| echo "v2.337.0 externals.sh: NODE20_VERSION=$node20_337 NODE24_VERSION=$node24_337" | |
| drift=0 | |
| if [[ "$node20_local" != "$node20_upstream" && "$node20_local" != "$node20_337" ]]; then | |
| echo "::error::node20_externals_version drift: versions.toml=$node20_local upstream externals.sh NODE20_VERSION=$node20_upstream (runner $runner_version)" | |
| drift=1 | |
| fi | |
| if [[ "$node24_local" != "$node24_upstream" && "$node24_local" != "$node24_337" ]]; then | |
| echo "::error::node24_externals_version drift: versions.toml=$node24_local upstream externals.sh NODE24_VERSION=$node24_upstream (runner $runner_version)" | |
| drift=1 | |
| fi | |
| # Also validate crates/preloop-runner/src/configure.rs pins if present | |
| if [[ -f "crates/preloop-runner/src/configure.rs" ]]; then | |
| configure_node20="$(grep -E '"node20",[[:space:]]*"v[0-9.]+"' crates/preloop-runner/src/configure.rs | head -n1 | sed -E 's/.*"v([^"]+)".*/\1/' || true)" | |
| configure_node24="$(grep -E '"node24",[[:space:]]*"v[0-9.]+"' crates/preloop-runner/src/configure.rs | head -n1 | sed -E 's/.*"v([^"]+)".*/\1/' || true)" | |
| if [[ -n "$configure_node20" && "$configure_node20" != "$node20_local" ]]; then | |
| echo "::error::configure.rs node20 drift: configure.rs=v$configure_node20 vs versions.toml=$node20_local" | |
| drift=1 | |
| fi | |
| if [[ -n "$configure_node24" && "$configure_node24" != "$node24_local" ]]; then | |
| echo "::error::configure.rs node24 drift: configure.rs=v$configure_node24 vs versions.toml=$node24_local" | |
| drift=1 | |
| fi | |
| fi | |
| if [[ "$drift" -ne 0 ]]; then | |
| echo "FAIL: Node pins have drifted from upstream actions/runner externals.sh" >&2 | |
| echo "Update versions.toml to match upstream, then refresh externals handling (see crates/preloop-runner/src/configure.rs and docs)." >&2 | |
| exit 1 | |
| fi | |
| echo "Node pin parity: OK (node20=$node20_local node24=$node24_local matches runner $runner_version)" |