Ad-hoc image build workflow for feature branches #108

Closed
opened 2026-06-18 12:34:17 +00:00 by james · 0 comments
Owner

Deploying / poking at a feature branch in a real container today requires either pushing a temporary vX.Y.Z-rc.N tag (which triggers the full release pipeline — wrong tool, runs cosign + Rekor + creates a release page) or hand-rolling docker build && docker push locally. Neither is right.

A dedicated workflow_dispatch workflow that builds and (optionally) pushes an unsigned image tagged from the branch makes this a one-click operation in the Forgejo Actions UI, without polluting the release pipeline or the Rekor log.

Design

  • Trigger: workflow_dispatch only. Pick a branch in the Run UI; nothing fires automatically. Keeps registry noise to "what was deliberately built", which matters for both storage and :latest-style mistakes.
  • Single boolean inputpush (default true). Set to false to dry-run a build without uploading; useful for "does this branch even build" without consuming registry storage.
  • Tag shape: branch-<slugified-branch>-<sha7> (e.g. branch-foo-bar-abc1234). Slugify lowercases and replaces non-[a-z0-9._-] runs with -. Always prefixed branch- so a self-hoster's docker pull or registry listing immediately distinguishes ad-hoc tags from release tags (vX.Y.Z). The :latest pointer never moves.
  • Registry: same forge.int.wynning.tech push target as the release pipeline (#76); same REGISTRY_USERNAME / REGISTRY_TOKEN secrets; image lives at forge.wynning.tech/james/carol:branch-… (same registry backend, two URLs).
  • No cosign signing, no SLSA attestation, no Rekor upload, no Forgejo release page. Ad-hoc images are dev-loop artifacts; they aren't something a self-hoster pulls in trust. Skipping these saves ~30s per build and keeps the cosign private key + Rekor entries reserved for actual releases.
  • OCI image labels: stamp org.opencontainers.image.source, revision, version (with the ad-hoc tag), plus a tech.wynning.carol.build-type=feature-branch label so docker inspect makes the image's nature obvious.

Acceptance criteria

  • A new .forgejo/workflows/build-feature-image.yml workflow appears in the Actions UI under "Build feature image".
  • Running it against a branch produces forge.wynning.tech/james/carol:branch-<slug>-<sha7> in the registry.
  • The push input toggles whether the push step runs; false builds and stops with a log line naming the tag.
  • :latest is not touched.
  • actionlint .forgejo/workflows/*.yml passes.
  • docs/ci.md gains a short "Ad-hoc feature-branch image builds" section explaining what the workflow produces and what it deliberately doesn't (no signing, no Rekor, no release page).

Out of scope

  • Registry retention / GC of accumulated branch-* tags. File a follow-up when the registry starts feeling full.
  • Auto-triggered builds (per-push, per-PR). Explicitly rejected — the manual gate is the value.
  • Auto-deploy of the built image anywhere. The workflow stops at "image in registry".
  • Adding the image reference as a sticky PR comment. Possible follow-up; for v1 the workflow run page's log line is the source of truth.

Part of epic #2.

Deploying / poking at a feature branch in a real container today requires either pushing a temporary `vX.Y.Z-rc.N` tag (which triggers the full release pipeline — wrong tool, runs cosign + Rekor + creates a release page) or hand-rolling `docker build && docker push` locally. Neither is right. A dedicated `workflow_dispatch` workflow that builds and (optionally) pushes an unsigned image tagged from the branch makes this a one-click operation in the Forgejo Actions UI, without polluting the release pipeline or the Rekor log. ## Design - **Trigger:** `workflow_dispatch` only. Pick a branch in the Run UI; nothing fires automatically. Keeps registry noise to "what was deliberately built", which matters for both storage and `:latest`-style mistakes. - **Single boolean input** — `push` (default `true`). Set to `false` to dry-run a build without uploading; useful for "does this branch even build" without consuming registry storage. - **Tag shape:** `branch-<slugified-branch>-<sha7>` (e.g. `branch-foo-bar-abc1234`). Slugify lowercases and replaces non-`[a-z0-9._-]` runs with `-`. Always prefixed `branch-` so a self-hoster's `docker pull` or registry listing immediately distinguishes ad-hoc tags from release tags (`vX.Y.Z`). The `:latest` pointer never moves. - **Registry:** same `forge.int.wynning.tech` push target as the release pipeline (#76); same `REGISTRY_USERNAME` / `REGISTRY_TOKEN` secrets; image lives at `forge.wynning.tech/james/carol:branch-…` (same registry backend, two URLs). - **No cosign signing, no SLSA attestation, no Rekor upload, no Forgejo release page.** Ad-hoc images are dev-loop artifacts; they aren't something a self-hoster pulls in trust. Skipping these saves ~30s per build and keeps the cosign private key + Rekor entries reserved for actual releases. - **OCI image labels:** stamp `org.opencontainers.image.source`, `revision`, `version` (with the ad-hoc tag), plus a `tech.wynning.carol.build-type=feature-branch` label so `docker inspect` makes the image's nature obvious. ## Acceptance criteria - [ ] A new `.forgejo/workflows/build-feature-image.yml` workflow appears in the Actions UI under "Build feature image". - [ ] Running it against a branch produces `forge.wynning.tech/james/carol:branch-<slug>-<sha7>` in the registry. - [ ] The `push` input toggles whether the push step runs; `false` builds and stops with a log line naming the tag. - [ ] `:latest` is not touched. - [ ] `actionlint .forgejo/workflows/*.yml` passes. - [ ] `docs/ci.md` gains a short "Ad-hoc feature-branch image builds" section explaining what the workflow produces and what it deliberately doesn't (no signing, no Rekor, no release page). ## Out of scope - Registry retention / GC of accumulated `branch-*` tags. File a follow-up when the registry starts feeling full. - Auto-triggered builds (per-push, per-PR). Explicitly rejected — the manual gate is the value. - Auto-deploy of the built image anywhere. The workflow stops at "image in registry". - Adding the image reference as a sticky PR comment. Possible follow-up; for v1 the workflow run page's log line is the source of truth. Part of epic #2.
james closed this issue 2026-06-18 12:46:42 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#108
No description provided.