Files
devx/docs/specs/DEVX-173.md
T
kireto 9d0e4cf429
Post-merge / detect-and-configure (push) Successful in 9s
Post-merge / release-and-maintain (push) Successful in 1m7s
DEVX-173: fix(ci): resolve dep-PR container digest via registry v2 API
2026-09-19 20:19:22 +00:00

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-Digest header.
  • 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-Digest via v2 API.
  • REQ-2: Lookup failures fail closed; no blob-sha256 fallback.