ci: route own-PR checks to an opt-in self-hosted runner - #6277
Open
pedrofrxncx wants to merge 1 commit into
Open
ci: route own-PR checks to an opt-in self-hosted runner#6277pedrofrxncx wants to merge 1 commit into
pedrofrxncx wants to merge 1 commit into
Conversation
The five bun-only check jobs (format, lint, typecheck, test, build) execute in 0.4-1.8 min but wait 4.9-6.5 min at queue p90 — measured across 146 runs, the hosted concurrency ceiling rather than slow execution. Resolve the runner once in the `changes` gate and read it as `needs.changes.outputs.runner`, so the routing policy lives in one auditable place instead of five copy-pasted `runs-on:` keys. Both CI_LOCAL_RUNNER and CI_LOCAL_RUNNER_ACTOR unset => always ubuntu-latest, so this is inert until someone opts in, and unsetting either falls back on the next run with no PR. `changes` stays hosted because it elects the runner; web-component-tests stays hosted because its apt-mirror-fallback deps step is Linux-only.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the five bun-only check jobs resolve their runner from repo variables, defaulting to the hosted runner used today. Both variables unset = no-op, so merging this changes nothing.
Complements #5828 rather than replacing it: that PR targets an ephemeral Linux ARC pool for the whole repo; this one routes one person's own PRs to a machine they own. Different trust model, hence the extra gate. If both land, the expressions want a trivial reconcile.
What moves
format,lint,typecheck,test,buildneeds.changes.outputs.runnerchangesweb-component-testsapt-mirror-fallbackdeps step is Linux-onlye2e.ymlThe choice is resolved once in
changesand read asneeds.changes.outputs.runner. Five copy-pastedruns-on:expressions would be five places for the gate to drift out of sync; one is auditable.Why these jobs
Measured across 146 runs (the same dataset as #5828):
formatlinttypechecktestbuildQueue p50 across the repo is healthy (6s). The tail is not: 15% of runs exceed 20 min and ~59% of that wall clock is queue, p99 ~90 min. These jobs spend 3-10× longer waiting than working. A runner that is always idle turns that into ~0.
Why not e2e
e2e-shardneeds Postgres + NATS + MinIO + 4 bun processes + 4 chromium workers per shard, and there are 2 shards. That fits a Linux VM at roughly hosted parity (ubuntu-latestis 4 vCPU / 16 GB), but two shards concurrently need ~24 GB, so on a 16 GB box they serialize:A loss at the median, a win only in the tail. Not worth the Docker-in-VM build-out, so e2e stays hosted where it is free and genuinely parallel. Revisit if a runner with >32 GB shows up.
Security
The same-repo condition is a load guard, not a security boundary, and the comment in the workflow says so.
pull_requestevaluates the workflow file from the merge ref, so a fork PR can rewriteruns-onand target the runner regardless of what this file says. The gate exists to keep teammates' runs off a personal machine, not to stop an attacker.The control that actually holds is the repo setting Settings → Actions → General → Fork pull request workflows from outside collaborators → "Require approval for all outside collaborators." That must be on before any variable here is set. With it on, the trust set is people with write access to this repo.
Two properties that reduce the blast radius either way:
secrets.GITHUB_TOKENnor any other secret is referenced by the five routed jobs —secrets.GITHUB_TOKENappears only inchanges, which stays hosted.--ephemeral, so nothing persists between jobs.Toggling
Effective on the next run. No PR, no merge queue.
Known trade-off while the variables are on
There is no fallback when a self-hosted runner is unavailable.
timeout-minutesbounds execution, not queue wait, so a job pointed at an offline runner sits queued until GitHub's 24h timeout — on exactly the PRs the opted-in person cares most about. Same failure mode #5828 documents for spot reclaims, and the mitigation is the same: unset the variable. Only opt in with a machine that is genuinely always on.Test notes
changesoutputs verified.ubuntu-latest.Summary by cubic
Routes five bun‑only CI checks to an opt‑in self‑hosted runner for the PR author; defaults to
ubuntu-latestso behavior is unchanged until enabled. This reduces queue time for format/lint/typecheck/test/build while leaving e2e and Linux-only steps on hosted runners.Scope
format,lint,typecheck,test,buildnow useneeds.changes.outputs.runner.changesstays hosted;web-component-testsand everything ine2e.ymlare unchanged.changesand reused to keep policy in one place.Rollout and risks
CI_LOCAL_RUNNER= andCI_LOCAL_RUNNER_ACTOR=; unset either to revert on the next run.secrets.GITHUB_TOKEN; prefer registering the runner with--ephemeral.Written for commit 40da68e. Summary will update on new commits.