Skip to content

Commit 6952215

Browse files
authored
Merge pull request #46 from netresearch/feat/retro-on-demand-image-provenance
docs(ci-testing): on-demand image tag race + explicit version bake
2 parents cece0f2 + 0156d4d commit 6952215

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

skills/docker-development/references/ci-testing.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,27 @@ docker buildx bake --print
149149
docker buildx bake -f docker-bake.hcl -f /tmp/metadata-bake.json --print
150150
```
151151

152+
## Pattern 6: On-demand image tags — build on ONE trigger, and bake the version explicitly
153+
154+
A prod-like *variant* image (a profiler build, a debug build) is often published under a content-addressed tag like `:profiling-<sha>` so operators can switch to it on demand. Two traps appear when that image also surfaces its own build provenance (commit, ref, version) on a status page.
155+
156+
**Trap A — the tag race.** If the variant builds on *both* `push: main` and `push: tags`, both runs write the SAME `:profiling-<sha>` tag (same commit → same sha), and last-writer-wins decides which run's baked git-ref survives. A release deploy can then read `ref=main` instead of `ref=v1.2.3`. Fix: build the on-demand variant on ONE trigger that carries the right provenance — tags (plus manual dispatch), not `main`:
157+
158+
```yaml
159+
- name: Build and push profiling image
160+
# Tag/dispatch only: a main-push build would race the tag build for :profiling-<sha>
161+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
162+
```
163+
164+
**Trap B — no version in a `.git`-less build.** A Docker build has no `.git`, so anything that derives the version from git or the package's own metadata reads a placeholder — e.g. Composer's `InstalledVersions::getPrettyVersion(<root-package>)` returns `1.0.0+no-version-set`. Bake the version in explicitly: pass a build arg before the dependency install (`COMPOSER_ROOT_VERSION=1.2.3`, or the language's equivalent) so the metadata records it, or have the app read a baked env (`APP_BUILD_REF`) that the Dockerfile declares and the workflow sets from `github.ref_name`:
165+
166+
```dockerfile
167+
ARG APP_BUILD_REF
168+
ENV APP_BUILD_REF=$APP_BUILD_REF
169+
```
170+
171+
With Trap A fixed, that ref is deterministically the release tag.
172+
152173
## Local boot-test pitfalls
153174

154175
When smoke/boot-testing an image by hand (not in the CI matrix):

0 commit comments

Comments
 (0)