From af730b7a1f808e0fc37959c29047de354005cde1 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Fri, 24 Apr 2026 11:32:06 -0400 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20v0.3.0=20=E2=80=94=20publish=20work?= =?UTF-8?q?flow-migrate=20Docker=20image=20to=20GHCR=20on=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a `docker` job to the release workflow that builds and pushes ghcr.io/gocodealone/workflow-migrate on every tag: - Multi-arch: linux/amd64 + linux/arm64 (single build-push-action step) - Versioned tag (e.g. :v0.3.0) always pushed - :latest pushed only for stable releases (no hyphen in tag) - Uses existing cmd/workflow-migrate/Dockerfile unchanged (distroless/static, nonroot user, no shell) - OCI labels: source, version, revision - Runs after goreleaser release job (needs: release) - GITHUB_TOKEN only, packages: write permission scoped to docker job Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 50 +++++++++++++++++++++++++++++++++++ CHANGELOG.md | 31 ++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 CHANGELOG.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21a4ea3..04dbe7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,3 +28,53 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + docker: + name: Build & Push workflow-migrate image + runs-on: ubuntu-latest + needs: release + permissions: + contents: read + packages: write + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Compute image tags + id: meta + run: | + VERSION="${{ github.ref_name }}" + TAGS="ghcr.io/gocodealone/workflow-migrate:${VERSION}" + # Append :latest only for stable releases (no pre-release component) + if [[ "${VERSION}" != *-* ]]; then + TAGS="${TAGS}"$'\n'"ghcr.io/gocodealone/workflow-migrate:latest" + fi + { + echo "tags<> "$GITHUB_OUTPUT" + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: cmd/workflow-migrate/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: | + org.opencontainers.image.source=https://github.com/GoCodeAlone/workflow-plugin-migrations + org.opencontainers.image.version=${{ github.ref_name }} + org.opencontainers.image.revision=${{ github.sha }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5e7ca7d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,31 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.3.0] - 2026-04-24 + +### Added + +- **Official `workflow-migrate` Docker image published to GHCR** — each release now builds and pushes `ghcr.io/gocodealone/workflow-migrate:{version}` (multi-arch: linux/amd64 + linux/arm64). Pre-release tags (containing `-`) are versioned only; stable releases also push `:latest`. Image uses the existing distroless/static base with a non-root user and no shell. BMW and other consumers can reference the image directly without cloning and building from source. + +## [0.2.0] - 2026-04-15 + +### Added + +- Atlas driver (`workflow-plugin-atlas-migrate`) for schema-as-code migrations +- `workflow-atlas-migrate` lint tool standalone binary +- Atlas plugin binary and release artifacts +- `cmd/workflow-migrate/Dockerfile` for building standalone migration runner image + +## [0.1.0] - 2026-04-01 + +### Added + +- Initial release: `workflow-plugin-migrations` plugin binary +- golang-migrate and goose drivers +- Module types and pipeline steps +- Conformance test suite +- `workflow-migrate` standalone binary for pre-deploy jobs From fa3eff0e6f71320c9d018377a927024848999467 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Fri, 24 Apr 2026 11:47:39 -0400 Subject: [PATCH 2/3] fix(release): scope packages:write to docker job + dynamic image.source label - Remove packages: write from workflow-level permissions (already explicitly scoped to the docker job that pushes to GHCR) - Replace hardcoded org.opencontainers.image.source URL with ${{ github.server_url }}/${{ github.repository }} for fork-safety Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/release.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 04dbe7c..554ee33 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,6 @@ on: permissions: contents: write - packages: write id-token: write # for OIDC/cosign keyless signing (future) jobs: @@ -75,6 +74,6 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: | - org.opencontainers.image.source=https://github.com/GoCodeAlone/workflow-plugin-migrations + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} org.opencontainers.image.version=${{ github.ref_name }} org.opencontainers.image.revision=${{ github.sha }} From 10d54fe11e0b0a659b67b274988a10ba8c10831a Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Fri, 24 Apr 2026 11:49:15 -0400 Subject: [PATCH 3/3] fix(docker): pin Dockerfile Go version to match go.mod exactly Prevents binary drift between the goreleaser-built release binary (pinned to go 1.26.0 via go-version-file: go.mod) and the Dockerfile- built image binary. If go.mod's Go version is bumped, this line must be bumped to match. Co-Authored-By: Claude Sonnet 4.6 --- cmd/workflow-migrate/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/workflow-migrate/Dockerfile b/cmd/workflow-migrate/Dockerfile index df0c7ab..2d44686 100644 --- a/cmd/workflow-migrate/Dockerfile +++ b/cmd/workflow-migrate/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -# Build stage -FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS builder +# Build stage — Go version pinned to match go.mod exactly; bump here if go.mod is updated +FROM --platform=$BUILDPLATFORM golang:1.26.0-alpine AS builder ARG TARGETARCH WORKDIR /src COPY go.mod go.sum ./