diff --git a/.github/workflows/gust-targets.yml b/.github/workflows/gust-targets.yml index 1b0a33d..10ffb02 100644 --- a/.github/workflows/gust-targets.yml +++ b/.github/workflows/gust-targets.yml @@ -25,7 +25,7 @@ concurrency: jobs: gust-targets: name: "gust target model (generator + drift gate)" - runs-on: ubuntu-22.04 + runs-on: [self-hosted, linux, x64, rust-cpu] timeout-minutes: 15 steps: - uses: actions/checkout@v7 diff --git a/.github/workflows/kill-criteria.yml b/.github/workflows/kill-criteria.yml index 8524eb8..769ef46 100644 --- a/.github/workflows/kill-criteria.yml +++ b/.github/workflows/kill-criteria.yml @@ -30,7 +30,8 @@ concurrency: jobs: wcet-evt: name: "VER-OS-WCET-001 kill-criterion can still fail" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -71,7 +72,8 @@ jobs: proof-completeness: name: "a Rocq proof that is merely STATED cannot pass as proven" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -112,7 +114,8 @@ jobs: renode-targets: name: "every renode_test target defined is actually run" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -134,7 +137,12 @@ jobs: # this gate catches the pin going stale in the one way that breaks a build silently # later: the fork rebased or force-pushed away from the commit, so `west init --mr # ` would fail in every Zephyr job at once instead of here. + # HOSTED, not self-hosted: this job shells out to `gh api` for the ancestry + # query and its negative control, and the rust-cpu image has no `gh` + # (measured: exit 127, "gh: command not found"). Moves the day `gh` is in + # the image — see gale#419. runs-on: ubuntu-24.04 + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - name: Pin is a 40-hex revision, and an ancestor of gale/sem-replacement @@ -167,7 +175,8 @@ jobs: retry-loops: name: "no CI retry loop can swallow its own failure" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -208,7 +217,8 @@ jobs: data-overlap: name: "fused data segments are disjoint (gale#266)" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -267,7 +277,8 @@ jobs: fixture-freshness: name: "committed Renode ELF fixtures are not older than their sources" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 with: @@ -286,7 +297,8 @@ jobs: object-freshness: name: "committed objects are not older than their sources" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 with: @@ -337,7 +349,16 @@ jobs: # failure mode that had occurred. This is that check, made mechanical. required-contexts: name: "every required context can actually report" + # HOSTED, not self-hosted, for a subtler reason than zephyr-fork-pin's: this + # job DEGRADES rather than fails when `gh api` cannot read branch + # protection, so on a runner with no `gh` it PASSED while silently skipping + # the list-vs-protection drift check -- half its coverage, gone, green. + # The degradation is deliberate and right for a token that lacks the + # permission; it is wrong for an image that lacks the binary. Both are + # handled now (see the guard below), but the job stays hosted until `gh` is + # in the image (gale#419) so the full check actually runs. runs-on: ubuntu-24.04 + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -354,6 +375,17 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + # A MISSING BINARY IS NOT A PERMISSION STORY. Without this, `gh` not + # being installed takes the same branch as "the token may not read + # protection" and the gate passes having checked half of what it + # claims. The degradation below exists for the permission case only. + command -v gh >/dev/null 2>&1 || { + echo "::error::gh is not installed on this runner — this gate cannot" + echo "::error::perform its protection-drift check, and must not report" + echo "::error::success as though it had. Install gh (gale#419) or run" + echo "::error::this job on a hosted runner." + exit 1 + } if gh api "repos/${GITHUB_REPOSITORY}/branches/main/protection" > /tmp/protection.json 2>/tmp/protection.err; then echo "readable=true" >> "$GITHUB_OUTPUT" echo "GITHUB_TOKEN CAN read branch protection -- list/protection drift is checked." @@ -378,7 +410,8 @@ jobs: # composed/fused wasm imports from `env`. graph-env: name: "no raw env import survives in the composed graph" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 @@ -497,7 +530,8 @@ jobs: # it cannot bound DECLINES LOUDLY rather than being omitted. wcet-sidecar: name: "T4: synth emits sound per-function WCET bounds (REQ-OS-WCET-001)" - runs-on: ubuntu-24.04 + runs-on: [self-hosted, linux, x64, rust-cpu] + timeout-minutes: 30 steps: - uses: actions/checkout@v7 diff --git a/.github/workflows/rivet-v-closure.yml b/.github/workflows/rivet-v-closure.yml index a240a75..4f11810 100644 --- a/.github/workflows/rivet-v-closure.yml +++ b/.github/workflows/rivet-v-closure.yml @@ -40,7 +40,7 @@ jobs: # below still REPORTS its check on every PR (gale#294) while doing no work # when nothing relevant changed. name: "V-closure needed?" - runs-on: ubuntu-latest + runs-on: [self-hosted, linux, x64, rust-cpu] outputs: run: ${{ steps.q.outputs.run }} steps: @@ -63,7 +63,7 @@ jobs: v-closure: name: "no requirement lags its closed V" needs: guard - runs-on: ubuntu-22.04 + runs-on: [self-hosted, linux, x64, rust-cpu] timeout-minutes: 10 steps: - uses: actions/checkout@v7