Repository navigation
fix(coverage-floor): pull a service image only for a caller that asks - #295
Conversation
The measure job's postgres and redis services were unconditional, so every caller pulled postgres:16 and redis:7 from Docker Hub on every run; services_postgres and services_redis only gated the DATABASE_URL and REDIS_URL exports. Docker Hub's unauthenticated pull limit then failed the job before it measured anything (dotclaude#485, twice), and coverage-floor is a required check in nine repos. GitHub skips a service whose image is an empty string, so each image is now gated on its input. inbox_superpilot, the one caller that opts in, keeps both services and its pgvector image; the other sixteen stop pulling two images they never used. selftest/test_coverage_floor_services.py renders the image expressions the way Actions does for each input combination. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From review: #485 is a PR whose coverage-floor runs hit the pull limit, not an issue about this bug, and the test's caller counts were off (there are 18 callers, not 17) and would go stale anyway. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Risk class: This PR touches one of the blocked path categories from Auto-merge is refused by (This is a policy notice, not a code-quality failure. The classify job itself does not fail — required CI checks remain authoritative for "is the code green.") |
|
The logic is sound. Let me verify the expression evaluation trace for the key cases: Expression: Using
The YAML No issues found. The fix is targeted, the expression logic is correct, and the new test pins the behavior accurately. Claude Review · workflow run |
Both fixes target the same Docker Hub rate limit and compose: a service starts only when its services_* input asks (this branch), and once on, a bare image name is pulled from mirror.gcr.io/library (#296). Each image is #296's expression wrapped in the gate: inputs.services_x && (<#296's expression>) || '' test_job_images_off_docker_hub.py now switches a service on before asking where its image comes from (its scan and REQUIRED), since switched off the image is '' and nothing is pulled. test_coverage_floor_services.py uses that file's resolve() (the evaluator it used could not parse contains() or format()) and expects the mirror references once a service is on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I've reviewed the full diff — the workflow YAML expression changes, the new Image gating expressions (coverage-floor.yml)
Negative control mutations New test file No issues found. The diff is well-scoped and correctly tested. Claude Review · workflow run |
Summary
coverage-floor.yml'smeasurejob started its postgres and redis services on every run of every caller.services_postgresandservices_redis(both defaultfalse) gated only theDATABASE_URL/TEST_DATABASE_URL/REDIS_URLexports, never the containers.On 2026-10-09, Docker Hub's unauthenticated pull limit (
toomanyrequests) failed:Each run died starting a container that caller never uses. The check is required directly in 8 repos and through a
coverage-floor-gatejob in 2 more.#296 (merged first) fixed where the images come from: a bare name is pulled from
mirror.gcr.io/library/. This PR fixes whether they are pulled at all: a service starts only when its input asks. Both are kept, merged in5378307.Fix
GitHub skips a service whose image is an empty string (workflow syntax,
jobs.<job_id>.services.<service_id>.image). Each image is #296's expression wrapped in a gate on its input:''. No container starts, nothing is pulled, and the runner adds no "Initialize containers" step (actions/runnerJobExtension.cs).Each image input's description now also says it is pulled only when its
services_*input is true. The job name and required-check context are unchanged.Who this changes
There are 18 callers, all on
@main.topcoder1/inbox_superpilot(bothservices_*: true,pgvector/pgvector:pg16)wxa_vpn,webcrawl(pre-measured coverage: no tests run in this job)A hidden dependency was checked before landing, twice and independently. #296's "Not done" section names this exact change and the audit it needs. The risk was a non-opted-in caller whose tests reached the always-on containers without the env exports. Postgres would need hardcoded
postgres:postgres; redis has no auth, so a client defaulting tolocalhost:6379would connect silently. Both audits grepped the callers' code, withinbox_superpilotas the positive control: mine on shallow clones of each caller's default branch, the reviewer's on its local clones. Findings for the repos where the check is required:localhost:6379CacheLayerfor a private fakeredis, and no test opts out.localhost:6379, soTrafficTrackerused to switch on in two test files and now stays off.TECHRECON_TEST_PG, and its redis tests use their own listeners or dead addresses.testing.Short()skips and its own testcontainers postgres.WHOISXMLAPI_*is set.test-user:test-passstubs the container rejects, and its DB tests run in a separate required job.The non-required callers either mock, or read
DATABASE_URL/REDIS_URL, which only opted-in callers get. Their localhost DSNs use roles the container refuses. No caller injects those URLs viaextra_env.If a caller turns out to need a container after all, it adds
services_postgres: true/services_redis: true.Tests
selftest/test_coverage_floor_services.py(new) pins whether a service starts. It renders each image with fix(coverage-floor): pull the service images from mirror.gcr.io, not Docker Hub #296'sresolve, using the declared defaults with a caller's values on top. The cases:'';Expected images are hardcoded.
selftest/test_job_images_off_docker_hub.py(fix(coverage-floor): pull the service images from mirror.gcr.io, not Docker Hub #296) pins where an image comes from. It now switches a service on, both in its scan and inREQUIRED, before asking that, since a switched-off service pulls nothing. Its negative controls are unchanged and still fail for the reasons they name.TDD on the gating: 4 failed / 2 passed on the old workflow, then green.
Mutation check on the merged workflow (unmutated control: 6 and 55 passed):
|| ''(off rendersfalse)services_postgresdefaults totrueuv run pytest -q: 711 passed, 1 skipped, 0 failed before the merge.coverage-floor.yml(47 with them) pass. CI runs the full suite on5378307.actionlintaslint.ymlruns it (no shellcheck) is clean.ruff check,ruff format --check, prettier andgit diff --checkare clean.Review
Independent code review (code-reviewer agent, on
80cfbbe): APPROVE WITH NITS, no production defects.8d80995: the fleet counts, and a reference that made dotclaude#485 read like an issue about this bug.Codex pre-review: 2 rounds on
80cfbbe, both with no findings. The merge resolution (5378307) is covered by the mutation table above.Not in this PR
pgvector/pgvector:pg16from Docker Hub. This is fix(coverage-floor): pull the service images from mirror.gcr.io, not Docker Hub #296's documented follow-up: that caller should passmirror.gcr.io/pgvector/pgvector:pg16.postgres:16through testcontainers, which still uses Docker Hub. Both fail loudly on a pull error.After merge: a coverage-floor run of any non-opted-in caller should show no "Initialize containers" step.
Auto-merge rationale: manual click-merge. This changes
.github/workflows/**in topcoder1/ci-workflows (always manual), in a reusable that 18 repos call and 10 require.Codex rounds: 2 (native
codex review, gpt-5.6-sol, reasoning high, on80cfbbebefore the #296 merge; both clean and read by hand)🤖 Generated with Claude Code