Skip to content

GitHub Actions config hardening across the five GPU-CI lecture repos #347

Description

@mmcky

Audit of GitHub Actions settings across the five repositories that run GPU CI on RunsOn, done 2026-07-30 while planning compute capability. Four config items came out of it — all hardening, none urgent.

Item 1 as originally written was wrong and has been corrected in place — it recommended reverting the on-demand decision from #330. See the correction comment for detail.

Repos in scope: lecture-jax, lecture-python.myst, lecture-python-programming, lecture-stats, iuj_feb_2026.

1. Spot pricing is switched off where most of the GPU volume is — CORRECTED, do not action

This item was wrong. See the correction comment below. spot=false is a deliberate org-wide reliability decision from #330 (spot reclamation was killing GPU builds mid-run), not an oversight. The correct action is the opposite: finish the #330 rollout by adding spot=false to the 7 GPU workflows that still lack it — all four in lecture-stats, both in iuj_feb_2026, and publish.yml in lecture-python-programming. The measurements below are accurate; the recommendation drawn from them was not.

Original text, kept for the record

spot=false is set in 10 of 17 GPU workflow files, across lecture-jax (4 of 4), lecture-python.myst (4 of 4) and lecture-python-programming (2 of 3 — publish.yml doesn't set it). lecture-stats and iuj_feb_2026 never set spot, and RunsOn defaults to spot, so those already get it.

Measured over 2026-01-31 → 2026-07-30, 98% of GPU CI wall-clock runs on spot=false — 245.9 of 251.3 hours. Flipping those 10 files to spot=true cuts that portion of the bill by roughly 58–61% at zero cost and with no downside I can see: RunsOn tries spot first and falls back to on-demand automatically when spot capacity is unavailable, at a 2–3 second launch penalty.

The single largest consumer is lecture-python.myst/ci.yml at 123.9 hours — about half of all GPU CI.

2. Fork-PR workflow approval is on GitHub's default rather than the strict setting

All five repos are set to first_time_contributors. The stricter option is all_external_contributors, which requires maintainer approval before any outside contributor's workflow runs rather than only a first-time one.

This is hardening rather than a live problem — it would start to matter if we ever attached a self-hosted runner to these repos, which we haven't. It's a five-click change and worth doing ahead of that rather than as part of it.

3. Actions can approve pull requests on four of five repos

can_approve_pull_request_reviews is true on all but iuj_feb_2026. We have no workflow that uses this, and we're planning triage and maintenance agents whose design says explicitly that a bot never approves or merges — so leaving the capability enabled makes that a convention rather than something actually enforced. Suggest turning it off so the guardrail is real.

4. Default workflow token permissions are write on four of five

default_workflow_permissions is write on all but iuj_feb_2026, which uses read. Broader than anything currently needs, and iuj_feb_2026 demonstrates read is workable. Per-workflow permissions: blocks can grant more where a workflow genuinely needs it.

Suggested order

Item Effort Why now
1 Finish the #330 rollout — add spot=false to the 7 workflows still missing it One PR Closes a known reliability gap. Replaces the original item 1, which was wrong
2 Set approval policy to all_external_contributors Five settings Free, and cheaper before a runner exists than after
3 Disable Actions approving PRs Four settings Makes a planned agent guardrail enforceable
4 Default token permissions to read Four settings Needs a check that nothing breaks

Not established

The organisation-level Actions policy hasn't been read — that needs admin:org, which I don't have. It could constrain or override any of the repo-level settings above, so worth checking before acting on 2–4.

Also worth a sanity check by someone who knows the repos: whether runs-on accepts expressions and which contexts are available at job level isn't documented in GitHub's workflow-syntax reference, which matters if we later want conditional runner selection.

Context and working are in the private project-compute planning repo (research/2026-07-30-gpu-ci-settings-audit.md).

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions