fix(evergreen-tracks): authenticate Hub tag reads — anonymous pagination now blocked past offset 1000 - #37027
fix(evergreen-tracks): authenticate Hub tag reads — anonymous pagination now blocked past offset 1000#37027sfreudenthaler wants to merge 1 commit into
Conversation
Docker Hub now refuses ANONYMOUS pagination past offset 1000
("pagination offset too large for anonymous requests; sign in to page
further"). dotcms/dotcms has ~7.8k tags / 79 pages, so registry.list_tags()
— which read the Hub API with no auth at all — 403s on page 11 every time.
This broke the daily promote cron (first failure 2026-08-11, run
31481784007; the 2026-08-10 run still walked all 79 pages), and would also
have broken the `latest` promote in the release pipeline on the next GA cut,
since both call the same read path.
executor.hub_login() already minted a Hub JWT for deletes and every calling
workflow already had DOCKER_USERNAME/DOCKER_TOKEN for docker/login-action —
the read path just never used them. Reuse it, and export the secrets to the
promote (plan + apply) and release latest-promote steps. The admin workflow
already exported them.
Also stop discarding the engine's stderr in the promote steps. `2>/dev/null`
turned this 403 into a bare "Process completed with exit code 1" with no
cause in the log or the Slack alert. stderr now goes to a file (it must stay
off stdout, which is the plan text the apply job diffs) and is printed on
failure.
Closes: #37025
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PqQqV1iv96Db8AzBSWTXV4
|
Claude finished @sfreudenthaler's task in 1m 56s —— View job Code ReviewI reviewed the diff against New Issues
Notes (non-blocking, no action needed)
Nothing here blocks merge. The Medium test-isolation item is worth fixing so the suite stays deterministic across environments. |
What happened
The daily
evergreen-tracks-promotecron failed on 2026-08-11 (run 31481784007) and would have failed every morning from here on. It died in theplan(dry-run) job, beforegate/apply, so no tag was moved — the alert's "one track may have moved" caveat did not apply this time.Root cause
Docker Hub now refuses anonymous pagination past offset 1000:
registry.list_tags()read the Hub API with no auth at all ("Public repos need no auth") and walked every page.dotcms/dotcmshas 7,831 tags = 79 pages, so it 403s on page 11.This is a Docker-side change: the 2026-08-10 run walked all 79 pages in 44s, the 2026-08-11 run died after 6s, and no evergreen-tracks commit landed in between.
Also broken, same read path — the
latestpromote incicd_6-release.yml, which would have failed on the next GA cut, and the admin (hold/taint) workflow.The fix
executor.hub_login()already minted a Hub JWT for deletes, and every calling workflow already hadDOCKER_USERNAME/DOCKER_TOKENfordocker/login-action— the read path just never used them. Authenticated requests aren't subject to the offset cap.registry.py— one login per walk, JWT on every page request. Auth stays optional so tests and small repos need no creds; a creds-less 403 now raises a message naming the cause instead of a bareHTTPError.plan+apply) and releaselatest-promote — export the two secrets. The admin workflow already did, so it self-heals.docker/login-actiondoes not cover the Hub API, which is why being "logged in" wasn't enough.Secondary fix: the failure was undiagnosable
Both promote steps captured the engine with
2>/dev/null("drop uv's stderr chatter"), which discarded the whole traceback. CI showed a bareProcess completed with exit code 1and the Slack alert carried no cause — the root cause had to be re-derived by running the tool locally. stderr now goes to a file (it must stay off stdout, which is the plan textapplydiffs) and is printed on failure.Verification
uv run pytest— 68 passed, including two new tests: every tag request carries the JWT when creds are set, and a creds-less 403 explains itself.planjob walked all 79 pages authenticated in ~29s and produced a real plan —standard -> 26.07.28-01. Cancelled at the approval gate so nothing applied.Merging this makes tomorrow's 10:00 UTC cron pass and apply that pending
standardmove.Closes: #37025
🤖 Generated with Claude Code
https://claude.ai/code/session_01PqQqV1iv96Db8AzBSWTXV4