Skip to content

build: migrate image publishing to dockers_v2 - #101

Draft
MPV wants to merge 1 commit into
masterfrom
claude/kir-security-hardening-i0yujo-dockers-v2
Draft

build: migrate image publishing to dockers_v2#101
MPV wants to merge 1 commit into
masterfrom
claude/kir-security-hardening-i0yujo-dockers-v2

Conversation

@MPV

@MPV MPV commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Draft deliberately — I could not exercise the build. See "Why this is a draft" before merging; it's the whole point of the PR.

What it does

goreleaser check on master reports:

dockers and docker_manifests are being phased out and will eventually be replaced by dockers_v2

This migrates. Two per-arch dockers entries plus two docker_manifests become one dockers_v2 entry: a single docker buildx build --platform linux/amd64,linux/arm64 --push publishes the multi-arch index directly, instead of building two single-arch images and stitching them together afterwards. Net −36/+34 lines.

Dockerfile.goreleaser changes because the build context changes. dockers_v2 stages each platform's binary under <platform>/<name>, so:

ARG TARGETPLATFORM
COPY ${TARGETPLATFORM}/kir /kir

Copying through TARGETPLATFORM rather than naming an architecture is what keeps each image in the index holding its own binary — a hardcoded path would build fine and silently ship one architecture everywhere.

Behavioural changes

Per-arch tags stop being pushed. ghcr.io/mpv/kir:X.Y.Z-amd64 and -arm64 existed only as inputs to docker_manifests; dockers_v2 has no equivalent intermediate. If anyone pulls those directly it breaks for them, so you may want a stronger commit type than the build: I used.

sbom: true adds a BuildKit SBOM attestation to the image index (--attest=type=sbom). That's GoReleaser's default — if docker.SBOM == "" { docker.SBOM = "true" } — set explicitly here so it can't change under us. Note this is a different artifact from #92's cosign attestation: BuildKit's own scanner, stored in the index, unsigned. It doesn't replace #92, and the two can coexist; the table in #92 lays out the difference.

Signing is unaffected, which was the thing I most wanted to confirm before proposing this. docker_signs with artifacts: manifests maps to ByTypes(DockerManifest, DockerImageV2), so dockers_v2 artifacts are still signed and every pushed tag keeps its keyless signature.

Verified

Everything below is against the GoReleaser the release workflow would resolve (~> v2 → v2.17.1), read from source rather than the docs — goreleaser.com is unreachable from where I work:

  • goreleaser check passes and the deprecation warning is gone.
  • Config parses to the intended shape: dockers and docker_manifests absent, images × tags = the four refs, sboms: [{artifacts: archive}] untouched.
  • sbom: true--attest=type=sbom (internal/pipe/docker/v2/docker.go, extraArgs).
  • docker_signs covers DockerImageV2 (internal/pipe/sign/sign_docker.go:60-77).
  • The context layout my COPY depends on: toPlatform returns path.Join("linux","amd64"), and upstream's own test asserts linux/amd64/mybin and linux/arm/v7/mybin exist in the context dir. So ${TARGETPLATFORM}/kir is correct for both platforms here.
  • dockers_v2 warns unless buildx uses the docker-container driver; docker/setup-buildx-action defaults to exactly that (checked its action.yml at the pinned SHA), so the workflow already satisfies it.

Why this is a draft

I never ran the build. dockers_v2 is a publisher and always passes --push, so there is no --snapshot path that builds images without pushing them. I tried to verify locally against a throwaway registry: a Docker daemon starts in my environment, but image pulls are blocked by its egress proxy, so buildkit can't bootstrap.

That matters more here than on the other PRs in this series. This is the only code path that publishes signed release artifacts, it runs only on a real release, and a failure lands after release-please has already cut the tag and GitHub Release — so a bad merge means a released version with no image, discovered at the worst moment.

So I'd want one of these before it's merged, not after:

  1. A one-off dry run. Run GoReleaser from this branch against a throwaway tag — dockers_v2.images: ghcr.io/mpv/kir-dryrun, say — and confirm: the index lists exactly linux/amd64 and linux/arm64; the binary inside each is that architecture (docker run --platform=linux/arm64 … kir --version, or pull each and file it); the four OCI labels are present; docker buildx imagetools inspect --format '{{json .SBOM}}' returns something; and cosign verify still passes on the pushed tags.
  2. Or a temporary workflow_dispatch job doing the same inside CI, which has the driver and credentials already. Happy to write either — say which and I'll raise it.

The architecture check is the one I'd least want skipped. It's the failure this change makes possible that nothing else in the pipeline would catch.

Sequencing

After #92. That one is small, additive and verified; this one deliberately isn't yet.


Generated by Claude Code

goreleaser check reports that dockers and docker_manifests are being phased out
in favour of dockers_v2. This migrates to it: one buildx build with both
platforms publishes the multi-arch index directly, replacing the two per-arch
dockers entries and the two docker_manifests that stitched them together.

dockers_v2 stages each platform's binary under <platform>/<name> in the build
context, so Dockerfile.goreleaser copies through ${TARGETPLATFORM} rather than
from the context root.

Two behavioural changes. The per-arch tags (:X.Y.Z-amd64, :X.Y.Z-arm64) are no
longer pushed — they existed only so docker_manifests could combine them. And
sbom: true adds a BuildKit SBOM attestation to the index; that is GoReleaser's
default, set explicitly here so it cannot change silently.

Image signing is unaffected: docker_signs with artifacts: manifests selects
dockers_v2 artifacts as well, so every pushed tag is still signed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants