77 branches : [main]
88 schedule :
99 # Saturday 11:07 UTC = Sat 21:07 AEST / 22:07 AEDT (Sydney night, year-round).
10- # Weekly cadence: deep fuzz at 1h/target × 16 targets is ~16 runner-hours, which
11- # drains in a few hours overnight instead of monopolising the shared ARC pool for
12- # ~32h. The full 8h/target run is opt-in via workflow_dispatch (run_deep_fuzz).
13- # PR-time coverage (cargo audit/deny, Cargo Vet, Quick Fuzz, CodeQL) catches
14- # regressions promptly; deep fuzz is for finding bugs, not gating merges.
15- # Off-minute (:07) avoids the cron pile-up that GitHub schedules at :00.
10+ # Weekly cadence: deep fuzz at 1h/target × 16 targets. Each matrix target is a
11+ # separate GitHub-hosted job, so they run in parallel (bounded by GitHub's
12+ # concurrency limit) rather than serialising on shared runners — and hosted minutes
13+ # are free for public repos. The longer opt-in run is via workflow_dispatch
14+ # (run_deep_fuzz). PR-time coverage (cargo audit/deny, Cargo Vet, Quick Fuzz,
15+ # CodeQL) catches regressions promptly; deep fuzz is for finding bugs, not
16+ # gating merges. Off-minute (:07) avoids the cron pile-up GitHub schedules at :00.
1617 - cron : ' 7 11 * * 6'
1718 # Deliberately no `release:` trigger. It existed only for an SBOM job that
1819 # attached a release asset, and that can never work here: immutable releases
2930 workflow_dispatch :
3031 inputs :
3132 run_deep_fuzz :
32- description : " Run the full deep-fuzz matrix (heavy — occupies the ARC pool )"
33+ description : " Run the full deep-fuzz matrix (heavy — one hosted job per target )"
3334 type : boolean
3435 default : false
3536 fuzz_seconds :
36- description : " Seconds per target for an on-demand deep fuzz (default 8h )"
37+ description : " Seconds per target for an on-demand deep fuzz (default 5h; hard cap 18000s to fit GitHub's 6h job limit )"
3738 type : string
38- default : " 28800 "
39+ default : " 18000 "
3940
4041concurrency :
4142 group : ${{ github.workflow }}-${{ github.ref }}
@@ -44,16 +45,11 @@ concurrency:
4445env :
4546 CARGO_TERM_COLOR : always
4647 RUST_BACKTRACE : 1
47- # Cap cargo parallelism so cold builds (incl. ASAN fuzz-target builds) don't
48- # OOM-kill the linker in the 5Gi cachekit runner — see cachekit-rs #25/#26.
49- # NOTE: -j bounds parallel codegen, not ASAN's absolute footprint; it's a
50- # strong mitigation for the fuzz builds, a full fix for normal cargo builds.
51- CARGO_BUILD_JOBS : " 4"
5248
5349jobs :
5450 fast-security :
5551 name : Fast Security Checks
56- runs-on : cachekit
52+ runs-on : ubuntu-latest
5753 if : github.event_name == 'push' || github.event_name == 'pull_request'
5854 steps :
5955 - name : Checkout code
9894
9995 quick-fuzz :
10096 name : Quick Fuzz (Corpus Only)
101- runs-on : cachekit
97+ runs-on : ubuntu-latest
10298 if : github.event_name == 'push' || github.event_name == 'pull_request'
10399 strategy :
104100 fail-fast : false
@@ -160,13 +156,13 @@ jobs:
160156
161157 deep-fuzz :
162158 name : Deep Fuzzing
163- runs-on : cachekit
164- # Scheduled weekly run is light (1h/target) so it can't monopolise the shared
165- # ARC pool. The full 8h/target run is opt-in via workflow_dispatch (run_deep_fuzz) .
159+ runs-on : ubuntu-latest
160+ # Scheduled weekly run is light (1h/target). The longer on-demand run is opt-in
161+ # via workflow_dispatch (run_deep_fuzz) and clamped to fit the hosted 6h cap .
166162 if : github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.run_deep_fuzz)
167- # 540min cap accommodates the on-demand 8h path; the inner timeout governs the
168- # actual scheduled (1h) vs dispatched (configurable ) duration.
169- timeout-minutes : 540
163+ # 360min = GitHub's hosted job cap. The inner timeout governs the actual
164+ # scheduled (1h) vs dispatched (<=5h, clamped below ) duration.
165+ timeout-minutes : 360
170166 strategy :
171167 fail-fast : false
172168 matrix :
@@ -214,18 +210,20 @@ jobs:
214210 run : cargo install cargo-fuzz
215211
216212 - name : Run deep fuzz
217- # Scheduled runs use 1h/target (keeps the ARC pool free for PR CI); a manual
218- # workflow_dispatch can request the full 8h (or any duration ) via fuzz_seconds.
213+ # Scheduled runs use 1h/target; a manual workflow_dispatch can request a
214+ # longer duration (up to the 5h clamp below ) via fuzz_seconds.
219215 env :
220216 FUZZ_SECONDS : ${{ (github.event_name == 'workflow_dispatch' && inputs.fuzz_seconds) || '3600' }}
221217 run : |
222218 # Validate the dispatch-supplied duration before it reaches shell arithmetic
223- # and the fuzzer. Must be a positive integer and within the 540min job cap.
219+ # and the fuzzer. Must be a positive integer within the hosted 6h job cap.
220+ # Ceiling is 18000s (5h): +180s hang slack (below) still leaves headroom
221+ # under timeout-minutes 360 (21600s), so a dispatched job cannot exceed 6h.
224222 case "$FUZZ_SECONDS" in
225223 ''|*[!0-9]*) echo "::error::fuzz_seconds must be a positive integer (got '$FUZZ_SECONDS')"; exit 1 ;;
226224 esac
227- if [ "$FUZZ_SECONDS" -lt 1 ] || [ "$FUZZ_SECONDS" -gt 32400 ]; then
228- echo "::error::fuzz_seconds must be 1..32400 (<= 540min job cap), got $FUZZ_SECONDS"; exit 1
225+ if [ "$FUZZ_SECONDS" -lt 1 ] || [ "$FUZZ_SECONDS" -gt 18000 ]; then
226+ echo "::error::fuzz_seconds must be 1..18000 (<= 6h hosted job cap), got $FUZZ_SECONDS"; exit 1
229227 fi
230228 cd fuzz
231229 # Build first - fail fast on compile errors
@@ -249,7 +247,7 @@ jobs:
249247
250248 kani :
251249 name : Kani Formal Verification
252- runs-on : cachekit
250+ runs-on : ubuntu-latest
253251 if : github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
254252 permissions :
255253 contents : read # least-privilege: the job only checks out and verifies
@@ -293,7 +291,7 @@ jobs:
293291
294292 cargo-vet :
295293 name : Cargo Vet (Supply Chain)
296- runs-on : cachekit
294+ runs-on : ubuntu-latest
297295 if : github.event_name == 'schedule' || github.event_name == 'pull_request'
298296 steps :
299297 - name : Checkout code
0 commit comments