Publish the Image on push to main #7

Closed
opened 2026-09-30 13:14:53 +00:00 by piscis · 3 comments
Owner

What to build

Extend CI so a push to main (and manual dispatch) builds, smoke-tests and publishes the multi-arch Image to code.vicoli.de/vicoli-oss/forgejo-mcp (ADR 0004). Log in with username: dockhand and password: ${{ secrets.PACKAGE_TOKEN }}, not github.actor.

Tags follow ADR 0003, given Upstream Version vX.Y.Z and Rebuild N from the Pin. Take the tag from the Makefile (#16) rather than working out N again in the workflow:

  • X.Y.Z-rN: immutable. If it already exists in the registry, skip publishing without failing. That's the normal case for pushes that don't change the Pin.
  • X.Y.Z, X.Y, X: moving, always pointing to the newest Rebuild.
  • latest: only if this Upstream Version is the highest one published so far.

Attach buildx SBOM and provenance attestations. Set OCI labels: org.opencontainers.image.source (this repo), org.opencontainers.image.licenses=GPL-3.0 (the Image redistributes Upstream's GPL-3.0 binary), and org.opencontainers.image.version. A Rebuild is triggered by raising the Rebuild number in the Pin and merging, or by manual dispatch after doing so.

Acceptance criteria

  • Merging the initial Pin publishes 3.2.0-r1, 3.2.0, 3.2, 3 and latest as a multi-arch manifest (amd64 + arm64)
  • docker pull code.vicoli.de/vicoli-oss/forgejo-mcp:3.2.0 works without login on an arm64 Mac and on an amd64 host
  • A push to main that doesn't change the Pin publishes nothing and the run is green
  • A push that changes the Pin but resolves to an X.Y.Z-rN tag that already exists fails instead of skipping. That catches a Rebuild where REBUILD was raised but REBUILD_OF wasn't updated.
  • Re-running a publish for an existing -rN tag never overwrites it
  • The published Image has SBOM and provenance attestations and the OCI source and license labels
  • Publishing only happens after the smoke test passed in the same run

Blocked by

Context: see GLOSSARY.md (Upstream, Upstream Version, Image, Rebuild, Consumer, Pin) and docs/adr/ (0001 build from Upstream source for multi-arch, 0002 canonical Upstream not the Codeberg mirror, 0003 tag scheme and immutable Rebuild tags, 0004 public org vicoli-oss).

## What to build Extend CI so a push to `main` (and manual dispatch) builds, smoke-tests and **publishes** the multi-arch Image to `code.vicoli.de/vicoli-oss/forgejo-mcp` (ADR 0004). Log in with `username: dockhand` and `password: ${{ secrets.PACKAGE_TOKEN }}`, not `github.actor`. Tags follow ADR 0003, given Upstream Version `vX.Y.Z` and Rebuild `N` from the Pin. Take the tag from the Makefile (#16) rather than working out `N` again in the workflow: - `X.Y.Z-rN`: immutable. If it already exists in the registry, skip publishing without failing. That's the normal case for pushes that don't change the Pin. - `X.Y.Z`, `X.Y`, `X`: moving, always pointing to the newest Rebuild. - `latest`: only if this Upstream Version is the highest one published so far. Attach buildx SBOM and provenance attestations. Set OCI labels: `org.opencontainers.image.source` (this repo), `org.opencontainers.image.licenses=GPL-3.0` (the Image redistributes Upstream's GPL-3.0 binary), and `org.opencontainers.image.version`. A Rebuild is triggered by raising the Rebuild number in the Pin and merging, or by manual dispatch after doing so. ## Acceptance criteria - [ ] Merging the initial Pin publishes `3.2.0-r1`, `3.2.0`, `3.2`, `3` and `latest` as a multi-arch manifest (amd64 + arm64) - [ ] `docker pull code.vicoli.de/vicoli-oss/forgejo-mcp:3.2.0` works **without login** on an arm64 Mac and on an amd64 host - [ ] A push to `main` that doesn't change the Pin publishes nothing and the run is green - [ ] A push that **changes** the Pin but resolves to an `X.Y.Z-rN` tag that already exists **fails** instead of skipping. That catches a Rebuild where `REBUILD` was raised but `REBUILD_OF` wasn't updated. - [ ] Re-running a publish for an existing `-rN` tag never overwrites it - [ ] The published Image has SBOM and provenance attestations and the OCI source and license labels - [ ] Publishing only happens after the smoke test passed in the same run ## Blocked by - #6 - #5 - #16 Context: see `GLOSSARY.md` (Upstream, Upstream Version, Image, Rebuild, Consumer, Pin) and `docs/adr/` (0001 build from Upstream source for multi-arch, 0002 canonical Upstream not the Codeberg mirror, 0003 tag scheme and immutable Rebuild tags, 0004 public org `vicoli-oss`).
piscis self-assigned this 2026-09-30 15:20:10 +00:00
Author
Owner

Once #26 lands (fixes #25), the publish workflow should run make verify-pin before it builds. It checks on Upstream that the tag of the Upstream Version still points at the Pin's commit, and doesn't depend on the build cache.

Once #26 lands (fixes #25), the publish workflow should run `make verify-pin` before it builds. It checks on Upstream that the tag of the Upstream Version still points at the Pin's commit, and doesn't depend on the build cache.
Author
Owner

Published by #28, in the push run for its merge (run #51): 3.2.0-r1 was pushed after both smoke tests passed, and 3.2.0, 3.2, 3 and latest were moved to it.

Acceptance criteria:

  • Initial Pin publishes all five tags as one multi-arch manifest. All five have digest sha256:319936feba60…: linux/amd64 + linux/arm64 + 2 attestation manifests.
  • docker pull …:3.2.0 without login. With an empty DOCKER_CONFIG, on an arm64 Mac: arm64 natively and amd64 with --platform, and both ran forgejo-mcp 3.2.0. On the x86_64 runner: an anonymous check that both platforms are there runs on every publish, and a real anonymous pull was tested before the merge (run #33).
  • Push that doesn't change the Pin publishes nothing and stays green. Run #33 (a comment-only Pin edit counts as unchanged).
  • Pin changed but the -rN tag already exists → the run fails. Runs #34 and #39.
  • Re-running never overwrites an -rN tag. Dispatch #38 and push #39. The digests of all tags were identical before and after.
  • SBOM, provenance, OCI labels. SPDX-2.3 SBOM and SLSA provenance on both platforms. Labels: source=https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp, licenses=GPL-3.0, version=3.2.0-r1, and revision set to this repo's commit.
  • Publishing only after the smoke test passed in the same run. Run #40 had a smoke test broken on purpose: the publish step never ran, and its tag never reached the registry.

Runs #31–#48 ran on throwaway branches against a test package. Both are deleted.

Also added: publish runs queue in a workflow-level concurrency group. Forgejo ignores concurrency set on a job (runs #43–48).

Known edge case, not fixed: if a dispatch runs before the push for the same Pin change, the push run goes red with "already exists", even though the Image is correct.

Published by #28, in the push run for its merge (run #51): `3.2.0-r1` was pushed after both smoke tests passed, and `3.2.0`, `3.2`, `3` and `latest` were moved to it. Acceptance criteria: - [x] **Initial Pin publishes all five tags as one multi-arch manifest.** All five have digest `sha256:319936feba60…`: linux/amd64 + linux/arm64 + 2 attestation manifests. - [x] **`docker pull …:3.2.0` without login.** With an empty `DOCKER_CONFIG`, on an arm64 Mac: arm64 natively and amd64 with `--platform`, and both ran `forgejo-mcp 3.2.0`. On the x86_64 runner: an anonymous check that both platforms are there runs on every publish, and a real anonymous pull was tested before the merge (run #33). - [x] **Push that doesn't change the Pin publishes nothing and stays green.** Run #33 (a comment-only Pin edit counts as unchanged). - [x] **Pin changed but the `-rN` tag already exists → the run fails.** Runs #34 and #39. - [x] **Re-running never overwrites an `-rN` tag.** Dispatch #38 and push #39. The digests of all tags were identical before and after. - [x] **SBOM, provenance, OCI labels.** SPDX-2.3 SBOM and SLSA provenance on both platforms. Labels: `source=https://code.vicoli.de/vicoli-oss/docker-forgejo-mcp`, `licenses=GPL-3.0`, `version=3.2.0-r1`, and `revision` set to this repo's commit. - [x] **Publishing only after the smoke test passed in the same run.** Run #40 had a smoke test broken on purpose: the publish step never ran, and its tag never reached the registry. Runs #31–#48 ran on throwaway branches against a test package. Both are deleted. Also added: publish runs queue in a workflow-level `concurrency` group. Forgejo ignores `concurrency` set on a job (runs #43–48). Known edge case, not fixed: if a dispatch runs before the push for the same Pin change, the push run goes red with "already exists", even though the Image is correct.
Author
Owner

Follow-up #33 fixes the edge case above. When X.Y.Z-rN already exists, publish.sh now compares this run's Pin with the Pin the existing Image was built from (read through its revision label). The same Pin skips and stays green, a different one fails, whichever run goes first. Verified on main: run #62 says "3.2.0-r1 already exists, built from the same Pin (commit 7f2e214): nothing to publish" and is green.

Follow-up #33 fixes the edge case above. When X.Y.Z-rN already exists, publish.sh now compares this run's Pin with the Pin the existing Image was built from (read through its revision label). The same Pin skips and stays green, a different one fails, whichever run goes first. Verified on main: run #62 says "3.2.0-r1 already exists, built from the same Pin (commit 7f2e214): nothing to publish" and is green.
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.

Reference
vicoli-oss/docker-forgejo-mcp#7
No description provided.