2.0 KiB
DEVX-173: Resolve container digest via registry v2 API
Problem
resolve_container_digest returns the sha256 of the manifest.json
blob listed by the Gitea packages API (/packages/<owner>/container/ <name>/<tag>/files). That blob digest is NOT the OCI manifest digest —
docker pull repo@sha256:<blob> fails with "not found." Production
deploy run 6251 died pulling sso-bridge@sha256:5ca9... which the dep
PR had recorded in deploy/sso-bridge-release.json. The registry serves
0.4.1 as sha256:c0212ed1... — different digest entirely.
Approach
REQ-1: Keep the packages-API call as the existence check (it has the
404-retry semantics needed for the publish race) but resolve the
pullable digest via the registry v2 API: GET /v2/token with
scope=repository:<owner>/<name>:pull (basic-auth with the Gitea
token), then GET /v2/<owner>/<name>/manifests/<tag> with OCI/Docker
manifest Accept headers and read Docker-Content-Digest. Registry base
URL is derived from GITEA_API_URL (strip /api/v1).
REQ-2: If the v2 digest lookup fails (non-2xx, missing header), fail closed with a ClickException — never record a blob sha256 as a pullable digest.
Test Plan
- Mocked v2 token + manifest endpoints return digest; recorded value is
the
Docker-Content-Digestheader. - 404 retry semantics on the packages-API existence check unchanged.
- Missing digest header / non-2xx manifest response → ClickException.
- Unit tests cover token request scope and Accept headers.
Deploy Plan
devx release tag; the sso-bridge dep-PR pin bump follows in its own PR. The wrong digest already recorded in infra's manifest is corrected by re-running the dep-PR with the fixed version.
Rollback Plan
Revert; dep-PR records the (unpullable) blob digest again — deploys must then use tag pulls until a corrected manifest lands.
Acceptance Criteria
- REQ-1: Digest resolved from
Docker-Content-Digestvia v2 API. - REQ-2: Lookup failures fail closed; no blob-sha256 fallback.