Repository navigation
Commit ce78ff7
ci: pull the Temporal Conformance service images from mirror.gcr.io, off Docker Hub's anonymous pull quota (#22545)
Fixes #22541
Clause-②: no
## What
The required `Temporal Conformance (live PG + MySQL)` job now pulls its
two service images from `mirror.gcr.io`, Google's cache of Docker Hub,
instead of from Docker Hub anonymously:
- `postgres:16` becomes `mirror.gcr.io/library/postgres:16`
- `mysql:8.0` becomes `mirror.gcr.io/library/mysql:8.0`
The diff is two `image:` values plus a six-line comment, all in
`.github/workflows/ci.yml`. The job name, `env`, `ports` and both health
checks (`pg_isready -U postgres`, `mysqladmin ping -h 127.0.0.1`) are
unchanged. `scripts/check-required-contexts.mjs` pins the job name, and
that name is untouched.
## Why
Since 20:53Z on 2026-10-09, every run of this job failed at `Initialize
containers` (three `Docker pull failed with exit code 1`, then failure),
before checkout or any test body ran. Docker Hub answered
`toomanyrequests` for the anonymous per-IP quota. The job is a required
context, so the merge queue ejected every entry. The newest failures,
read through the jobs API at 21:31Z, are the same: jobs `114034494503`
(21:30:40Z), `114033905117`, `114031741661`, `114030793729`,
`114029405989` and `114028399482`. Each has `Initialize containers` as
its only failing step.
A Docker Hub login is not the fix. It needs a maintainer-held secret,
and secrets never reach fork pull requests, so those runs would stay on
the anonymous quota.
## Measured: same image, same tag, same digest
Anonymous registry probe from this session at 2026-10-09T21:32:53Z,
`HEAD /v2/REPO/manifests/TAG` with each registry's anonymous token flow,
accepting the OCI index and Docker manifest-list types:
| image | Docker Hub | mirror.gcr.io | ECR Public
(`public.ecr.aws/docker/library`) |
|:---|:---|:---|:---|
| `postgres:16` |
`sha256:ca0bd484cb98bf4b24eb1010e73fb3fcbd6714d240fbc1a10eea5b7dbecb641d`
| 200, same digest | 200, same digest |
| `mysql:8.0` |
`sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b`
| 200, same digest | 200, same digest |
- The registry probe to Docker Hub itself answered **429** for both
repositories, even for `HEAD`, with `ratelimit-limit: 100;w=3600`,
`ratelimit-remaining: 0;w=3600` and a `docker-ratelimit-source` naming
the egress IP. That is the anonymous per-IP quota this PR moves off. So
the Docker Hub column was read from the Hub tag API
(`hub.docker.com/v2/repositories/library/IMAGE/tags/TAG`, HTTP 200). It
gives `postgres:16` last pushed 2026-10-07T19:07:56Z and `mysql:8.0`
last pushed 2026-05-05T02:02:21Z.
- Both mirrors returned an OCI image index
(`application/vnd.oci.image.index.v1+json`), and neither response
carried a rate-limit header.
- Why `mirror.gcr.io` and not ECR Public: both serve both tags
anonymously with identical digests. `mirror.gcr.io` is a cache of Docker
Hub itself, so the bytes are Docker Hub's. ECR Public stays the measured
fallback: if this mirror ever misbehaves, the swap is the same two lines
to `public.ecr.aws/docker/library/...`.
## Proof
There is no Docker daemon in the authoring container, so this PR's own
CI run is the measurement. The `Temporal Conformance (live PG + MySQL)`
job on this PR must pass `Initialize containers` with the mirror named
in its pull lines, then run its suites. The job id and conclusion go in
the dispatch report on #22541.
## Acceptance notes
- `Scaffold E2E` (`.github/workflows/scaffold-e2e.yml`, on
`pull_request`) builds `docker/Dockerfile`, which is `FROM
node:22-slim`, and so also pulls from Docker Hub anonymously. It is not
one of the seven required contexts, so it does not block the queue, and
this PR does not change it. No other required job pulls a container
image.
- No changeset: a CI-only path publishes nothing.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VZqqwTj2wsihZEbfT6yyYN)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent faf6348 commit ce78ff7
1 file changed
Lines changed: 8 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1521 | 1521 | | |
1522 | 1522 | | |
1523 | 1523 | | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
| 1527 | + | |
| 1528 | + | |
| 1529 | + | |
1524 | 1530 | | |
1525 | 1531 | | |
1526 | | - | |
| 1532 | + | |
1527 | 1533 | | |
1528 | 1534 | | |
1529 | 1535 | | |
| |||
1539 | 1545 | | |
1540 | 1546 | | |
1541 | 1547 | | |
1542 | | - | |
| 1548 | + | |
1543 | 1549 | | |
1544 | 1550 | | |
1545 | 1551 | | |
| |||
0 commit comments