From 8a664478e301073d55401cdc7d51e7ee1c276554 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 02:39:31 -0300 Subject: [PATCH 01/20] docker hub publish --- .dockerignore | 9 ++++ .github/workflows/docker-publish.yml | 77 ++++++++++++++++++++++++++++ Dockerfile | 43 ++++++++++++++++ README.md | 16 ++++++ 4 files changed, 145 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/docker-publish.yml create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e51df67 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.git +.github +.idea +.vscode +bin +dist +coverage.out +galaxio +*.test diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..abb8e45 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,77 @@ +name: docker-publish + +on: + push: + branches: + - main + tags: + - "v*" + workflow_dispatch: + +permissions: + contents: read + +env: + IMAGE_NAME: galax-io/galaxio-cli + +jobs: + publish: + name: publish image + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=semver,pattern={{major}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + version="${GITHUB_REF_NAME}" + else + version="dev" + fi + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: false diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3e772e6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +# syntax=docker/dockerfile:1.7 + +ARG GO_VERSION=1.25.0 +ARG DISTROLESS_BASE_IMAGE=gcr.io/distroless/static-debian12:nonroot + +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build + +WORKDIR /src + +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/go/pkg/mod go mod download + +COPY . . + +ARG TARGETOS +ARG TARGETARCH +ARG TARGETVARIANT +ARG VERSION=dev +ARG COMMIT=none +ARG DATE=unknown + +RUN --mount=type=cache,target=/root/.cache/go-build \ + mkdir -p /out && \ + CGO_ENABLED=0 \ + GOOS=${TARGETOS} \ + GOARCH=${TARGETARCH} \ + GOARM=${TARGETVARIANT#v} \ + go build -trimpath -ldflags="-s -w \ + -X github.com/galax-io/galaxio-cli/internal/buildinfo.Version=${VERSION} \ + -X github.com/galax-io/galaxio-cli/internal/buildinfo.Commit=${COMMIT} \ + -X github.com/galax-io/galaxio-cli/internal/buildinfo.Date=${DATE}" \ + -o /out/galaxio ./cmd/galaxio + +FROM ${DISTROLESS_BASE_IMAGE} + +LABEL org.opencontainers.image.title="galaxio-cli" +LABEL org.opencontainers.image.description="CLI for Gatling performance testing workflows." +LABEL org.opencontainers.image.source="https://github.com/galax-io/galaxio-cli" +LABEL org.opencontainers.image.licenses="GPL-2.0-only" + +COPY --from=build /out/galaxio /usr/local/bin/galaxio + +ENTRYPOINT ["/usr/local/bin/galaxio"] diff --git a/README.md b/README.md index 34f4e7f..5493bfd 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,22 @@ Archives are named `galaxio___.tar.gz` (`.zip` on Windows). 3. Extract the `galaxio` binary (or `galaxio.exe` on Windows). 4. Move it to a directory on your `PATH`. +### Option 4 — Docker image + +The image is published to Docker Hub as `galax-io/galaxio-cli`. + +```sh +docker pull galax-io/galaxio-cli:latest +docker run --rm galax-io/galaxio-cli --help +``` + +For commands that create files, mount a working directory and set it as the +container workdir: + +```sh +docker run --rm -v "$PWD":/work -w /work galax-io/galaxio-cli template list +``` + ### Windows Windows does not ship with a POSIX shell, so use one of: From 8d114901c8dfb45e8bc1cceddca4a6e8bd14227b Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 02:44:06 -0300 Subject: [PATCH 02/20] ci: split pr validation and publish --- .github/workflows/docker-publish.yml | 48 +++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index abb8e45..6a3dfe4 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,12 +1,12 @@ name: docker-publish on: + pull_request: push: branches: - main tags: - "v*" - workflow_dispatch: permissions: contents: read @@ -15,8 +15,54 @@ env: IMAGE_NAME: galax-io/galaxio-cli jobs: + build-and-validate: + name: build and validate image + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + version="dev" + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + image_tag="${IMAGE_NAME}:pr-${{ github.event.pull_request.number }}-${GITHUB_SHA::12}" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build image locally + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + load: true + push: false + tags: ${{ steps.buildmeta.outputs.image_tag }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: false + + - name: Validate image with utility command + run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version + publish: name: publish image + if: github.event_name != 'pull_request' runs-on: ubuntu-latest steps: - name: Checkout From 7b6940b70e29bd8e2d013f8360e5b4e53bfaad11 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 02:45:44 -0300 Subject: [PATCH 03/20] ci: rename image to galaxio --- .github/workflows/docker-publish.yml | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 6a3dfe4..c4b3e19 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -12,7 +12,7 @@ permissions: contents: read env: - IMAGE_NAME: galax-io/galaxio-cli + IMAGE_NAME: ${{ secrets.DOCKER_USERNAME }}/galaxio jobs: build-and-validate: diff --git a/README.md b/README.md index 5493bfd..d644e9c 100644 --- a/README.md +++ b/README.md @@ -79,18 +79,18 @@ Archives are named `galaxio___.tar.gz` (`.zip` on Windows). ### Option 4 — Docker image -The image is published to Docker Hub as `galax-io/galaxio-cli`. +The image is published to Docker Hub as `/galaxio`. ```sh -docker pull galax-io/galaxio-cli:latest -docker run --rm galax-io/galaxio-cli --help +docker pull /galaxio:latest +docker run --rm /galaxio --help ``` For commands that create files, mount a working directory and set it as the container workdir: ```sh -docker run --rm -v "$PWD":/work -w /work galax-io/galaxio-cli template list +docker run --rm -v "$PWD":/work -w /work /galaxio template list ``` ### Windows From 1716cf6c3a675309f57adf71cbb42566502d2867 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 02:47:27 -0300 Subject: [PATCH 04/20] fix: make docker workflow self-contained --- .github/workflows/docker-publish.yml | 6 +----- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index c4b3e19..7d802f1 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -12,7 +12,7 @@ permissions: contents: read env: - IMAGE_NAME: ${{ secrets.DOCKER_USERNAME }}/galaxio + IMAGE_NAME: galax-io/galaxio jobs: build-and-validate: @@ -53,8 +53,6 @@ jobs: push: false tags: ${{ steps.buildmeta.outputs.image_tag }} build-args: ${{ steps.buildmeta.outputs.build_args }} - cache-from: type=gha - cache-to: type=gha,mode=max provenance: false - name: Validate image with utility command @@ -118,6 +116,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: ${{ steps.buildmeta.outputs.build_args }} - cache-from: type=gha - cache-to: type=gha,mode=max provenance: false diff --git a/README.md b/README.md index d644e9c..5f3834b 100644 --- a/README.md +++ b/README.md @@ -79,18 +79,18 @@ Archives are named `galaxio___.tar.gz` (`.zip` on Windows). ### Option 4 — Docker image -The image is published to Docker Hub as `/galaxio`. +The image is published to Docker Hub as `galax-io/galaxio`. ```sh -docker pull /galaxio:latest -docker run --rm /galaxio --help +docker pull galax-io/galaxio:latest +docker run --rm galax-io/galaxio --help ``` For commands that create files, mount a working directory and set it as the container workdir: ```sh -docker run --rm -v "$PWD":/work -w /work /galaxio template list +docker run --rm -v "$PWD":/work -w /work galax-io/galaxio template list ``` ### Windows From 3431721e9fb7c661d5709fa4f183a35bf5b61420 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 02:58:20 -0300 Subject: [PATCH 05/20] ci: move docker publish to release --- .github/workflows/docker-publish.yml | 66 +-------------------------- .github/workflows/release.yml | 68 ++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 65 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 7d802f1..35fe29d 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -2,11 +2,7 @@ name: docker-publish on: pull_request: - push: - branches: - - main - tags: - - "v*" + workflow_dispatch: permissions: contents: read @@ -57,63 +53,3 @@ jobs: - name: Validate image with utility command run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version - - publish: - name: publish image - if: github.event_name != 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_NAME }} - tags: | - type=raw,value=latest,enable={{is_default_branch}} - type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} - type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} - type=semver,pattern={{major}},enable=${{ startsWith(github.ref, 'refs/tags/v') }} - - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - if [[ "${GITHUB_REF}" == refs/tags/* ]]; then - version="${GITHUB_REF_NAME}" - else - version="dev" - fi - - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Build and push image - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: ${{ steps.buildmeta.outputs.build_args }} - provenance: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a96995..af8a43b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,3 +32,71 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + docker-publish: + name: docker publish + needs: goreleaser + runs-on: ubuntu-latest + permissions: + contents: read + env: + IMAGE_NAME: galax-io/galaxio + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + version="${GITHUB_REF_NAME}" + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Prepare image tags + id: tags + shell: bash + run: | + set -euo pipefail + + version="${GITHUB_REF_NAME#v}" + major="${version%%.*}" + minor_patch="${version#*.}" + minor="${minor_patch%%.*}" + + { + echo "tags<> "${GITHUB_OUTPUT}" + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.tags.outputs.tags }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + provenance: false From 67b86c6ae8f8edc7e726f2d2a5be86cda5aefd9f Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:03:53 -0300 Subject: [PATCH 06/20] ci: validate before docker publish --- .github/workflows/release.yml | 48 ++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index af8a43b..a49ac8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,9 +33,55 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + docker-build: + name: build and validate image + needs: goreleaser + runs-on: ubuntu-latest + permissions: + contents: read + env: + IMAGE_NAME: galax-io/galaxio + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + version="${GITHUB_REF_NAME}" + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + image_tag="${IMAGE_NAME}:release-${GITHUB_SHA::12}" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build image locally + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + load: true + push: false + tags: ${{ steps.buildmeta.outputs.image_tag }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + provenance: false + + - name: Validate image with utility command + run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version + docker-publish: name: docker publish - needs: goreleaser + needs: docker-build runs-on: ubuntu-latest permissions: contents: read From c8633b2d90c0f5f99963e505a261dd99d5c410d3 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:07:03 -0300 Subject: [PATCH 07/20] ci: retrigger pr checks From 1abe274aa99a19a39c4f82dbcb6a55122c58c6fa Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:08:05 -0300 Subject: [PATCH 08/20] ci: add docker check to pr workflow --- .github/workflows/ci.yml | 40 ++++++++++++++++++++ .github/workflows/docker-publish.yml | 55 ---------------------------- 2 files changed, 40 insertions(+), 55 deletions(-) delete mode 100644 .github/workflows/docker-publish.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 453ad35..d88b01a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,46 @@ jobs: - name: Build run: go build -trimpath -o dist/galaxio ./cmd/galaxio + docker-image: + name: docker image + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + needs: test + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + image_tag="galax-io/galaxio:pr-${{ github.event.pull_request.number }}-${GITHUB_SHA::12}" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build image locally + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + load: true + push: false + tags: ${{ steps.buildmeta.outputs.image_tag }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + provenance: false + + - name: Validate image with utility command + run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version + integration: name: integration tests runs-on: ubuntu-latest diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index 35fe29d..0000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: docker-publish - -on: - pull_request: - workflow_dispatch: - -permissions: - contents: read - -env: - IMAGE_NAME: galax-io/galaxio - -jobs: - build-and-validate: - name: build and validate image - if: github.event_name == 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - version="dev" - - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - image_tag="${IMAGE_NAME}:pr-${{ github.event.pull_request.number }}-${GITHUB_SHA::12}" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Build image locally - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - load: true - push: false - tags: ${{ steps.buildmeta.outputs.image_tag }} - build-args: ${{ steps.buildmeta.outputs.build_args }} - provenance: false - - - name: Validate image with utility command - run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version From 5616549a2e9093512c1b3197d29dc07f0798932f Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:11:43 -0300 Subject: [PATCH 09/20] ci: wait for integration before docker image --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d88b01a..976815f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,9 @@ jobs: name: docker image runs-on: ubuntu-latest if: github.event_name == 'pull_request' - needs: test + needs: + - test + - integration steps: - name: Checkout uses: actions/checkout@v4 From 5b9020094290ce03a6e2a2569b60ee16608b3030 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:13:39 -0300 Subject: [PATCH 10/20] ci: publish docker image after ci on main --- .github/workflows/docker-publish.yml | 117 +++++++++++++++++++++++++++ .github/workflows/release.yml | 114 -------------------------- 2 files changed, 117 insertions(+), 114 deletions(-) create mode 100644 .github/workflows/docker-publish.yml diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..022b22f --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,117 @@ +name: docker-publish + +on: + workflow_run: + workflows: + - ci + types: + - completed + branches: + - main + +permissions: + contents: read + +env: + IMAGE_NAME: galax-io/galaxio + +jobs: + build-and-validate: + name: build and validate image + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_sha }} + fetch-depth: 0 + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + image_tag="${IMAGE_NAME}:main-${GITHUB_SHA::12}" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build image locally + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + load: true + push: false + tags: ${{ steps.buildmeta.outputs.image_tag }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + provenance: false + + - name: Validate image with utility command + run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version + + publish: + name: publish image + needs: build-and-validate + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_sha }} + fetch-depth: 0 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Prepare image tags + id: tags + shell: bash + run: | + set -euo pipefail + + { + echo "tags<> "${GITHUB_OUTPUT}" + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.tags.outputs.tags }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + provenance: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a49ac8c..9a96995 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,117 +32,3 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - docker-build: - name: build and validate image - needs: goreleaser - runs-on: ubuntu-latest - permissions: - contents: read - env: - IMAGE_NAME: galax-io/galaxio - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - version="${GITHUB_REF_NAME}" - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - image_tag="${IMAGE_NAME}:release-${GITHUB_SHA::12}" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Build image locally - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - load: true - push: false - tags: ${{ steps.buildmeta.outputs.image_tag }} - build-args: ${{ steps.buildmeta.outputs.build_args }} - provenance: false - - - name: Validate image with utility command - run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version - - docker-publish: - name: docker publish - needs: docker-build - runs-on: ubuntu-latest - permissions: - contents: read - env: - IMAGE_NAME: galax-io/galaxio - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - version="${GITHUB_REF_NAME}" - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Prepare image tags - id: tags - shell: bash - run: | - set -euo pipefail - - version="${GITHUB_REF_NAME#v}" - major="${version%%.*}" - minor_patch="${version#*.}" - minor="${minor_patch%%.*}" - - { - echo "tags<> "${GITHUB_OUTPUT}" - - - name: Build and push image - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.tags.outputs.tags }} - build-args: ${{ steps.buildmeta.outputs.build_args }} - provenance: false From 957680b4637ccfba40d7901d09a3a84e94a31a2e Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:29:53 -0300 Subject: [PATCH 11/20] ci: tag docker image from release tag --- .github/workflows/docker-publish.yml | 20 ++++++++++++-------- README.md | 4 +++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 022b22f..86d3349 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -3,11 +3,9 @@ name: docker-publish on: workflow_run: workflows: - - ci + - release types: - completed - branches: - - main permissions: contents: read @@ -26,6 +24,7 @@ jobs: with: ref: ${{ github.event.workflow_run.head_sha }} fetch-depth: 0 + fetch-tags: true - name: Prepare build metadata id: buildmeta @@ -33,13 +32,14 @@ jobs: run: | set -euo pipefail + version="$(git describe --tags --exact-match HEAD)" commit="$(git rev-parse --short=12 HEAD)" date="$(git log -1 --format=%cI HEAD)" - image_tag="${IMAGE_NAME}:main-${GITHUB_SHA::12}" + image_tag="${IMAGE_NAME}:${version}" { echo "build_args<> "${GITHUB_OUTPUT}" @@ -69,6 +69,7 @@ jobs: with: ref: ${{ github.event.workflow_run.head_sha }} fetch-depth: 0 + fetch-tags: true - name: Log in to Docker Hub uses: docker/login-action@v3 @@ -82,12 +83,13 @@ jobs: run: | set -euo pipefail + version="$(git describe --tags --exact-match HEAD)" commit="$(git rev-parse --short=12 HEAD)" date="$(git log -1 --format=%cI HEAD)" { echo "build_args<> "${GITHUB_OUTPUT}" @@ -97,11 +99,13 @@ jobs: run: | set -euo pipefail + version="$(git describe --tags --exact-match HEAD)" + { echo "tags<> "${GITHUB_OUTPUT}" diff --git a/README.md b/README.md index 5f3834b..768db61 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,11 @@ Archives are named `galaxio___.tar.gz` (`.zip` on Windows). ### Option 4 — Docker image -The image is published to Docker Hub as `galax-io/galaxio`. +The image is published to Docker Hub as `galax-io/galaxio:` and +`galax-io/galaxio:latest`. ```sh +docker pull galax-io/galaxio:v0.1.1 docker pull galax-io/galaxio:latest docker run --rm galax-io/galaxio --help ``` From 614d3c3e7b4b68964c354dfe554ecf6cb2f1114d Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:31:56 -0300 Subject: [PATCH 12/20] ci: publish release semver docker tags --- .github/workflows/docker-publish.yml | 22 ++++++++++++++++++---- README.md | 9 ++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 86d3349..73d568a 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -33,15 +33,22 @@ jobs: set -euo pipefail version="$(git describe --tags --exact-match HEAD)" + semver="${version#v}" + major="${semver%%.*}" + remainder="${semver#*.}" + minor="${semver%%.*}.${remainder%%.*}" commit="$(git rev-parse --short=12 HEAD)" date="$(git log -1 --format=%cI HEAD)" - image_tag="${IMAGE_NAME}:${version}" + image_tag="${IMAGE_NAME}:${semver}" { echo "build_args<> "${GITHUB_OUTPUT}" - name: Build image locally @@ -84,12 +91,13 @@ jobs: set -euo pipefail version="$(git describe --tags --exact-match HEAD)" + semver="${version#v}" commit="$(git rev-parse --short=12 HEAD)" date="$(git log -1 --format=%cI HEAD)" { echo "build_args<> "${GITHUB_OUTPUT}" @@ -100,11 +108,17 @@ jobs: set -euo pipefail version="$(git describe --tags --exact-match HEAD)" + semver="${version#v}" + major="${semver%%.*}" + remainder="${semver#*.}" + minor="${semver%%.*}.${remainder%%.*}" { echo "tags<> "${GITHUB_OUTPUT}" diff --git a/README.md b/README.md index 768db61..e4266f2 100644 --- a/README.md +++ b/README.md @@ -79,11 +79,14 @@ Archives are named `galaxio___.tar.gz` (`.zip` on Windows). ### Option 4 — Docker image -The image is published to Docker Hub as `galax-io/galaxio:` and -`galax-io/galaxio:latest`. +The image is published to Docker Hub as `galax-io/galaxio:`, +plus the aliases `galax-io/galaxio:`, `galax-io/galaxio:`, +and `galax-io/galaxio:latest`. ```sh -docker pull galax-io/galaxio:v0.1.1 +docker pull galax-io/galaxio:0.1.1 +docker pull galax-io/galaxio:0.1 +docker pull galax-io/galaxio:0 docker pull galax-io/galaxio:latest docker run --rm galax-io/galaxio --help ``` From 72db680699afefb05d8fc015772b2d0936031703 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:33:06 -0300 Subject: [PATCH 13/20] ci: drop docker major tag alias --- .github/workflows/docker-publish.yml | 6 ------ README.md | 4 +--- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 73d568a..36d5560 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -34,7 +34,6 @@ jobs: version="$(git describe --tags --exact-match HEAD)" semver="${version#v}" - major="${semver%%.*}" remainder="${semver#*.}" minor="${semver%%.*}.${remainder%%.*}" commit="$(git rev-parse --short=12 HEAD)" @@ -46,9 +45,6 @@ jobs: printf 'VERSION=%s\nCOMMIT=%s\nDATE=%s\n' "${semver}" "${commit}" "${date}" echo "EOF" echo "image_tag=${image_tag}" - echo "image_version=${semver}" - echo "image_major=${major}" - echo "image_minor=${minor}" } >> "${GITHUB_OUTPUT}" - name: Build image locally @@ -109,7 +105,6 @@ jobs: version="$(git describe --tags --exact-match HEAD)" semver="${version#v}" - major="${semver%%.*}" remainder="${semver#*.}" minor="${semver%%.*}.${remainder%%.*}" @@ -118,7 +113,6 @@ jobs: printf '%s\n' \ "${IMAGE_NAME}:${semver}" \ "${IMAGE_NAME}:${minor}" \ - "${IMAGE_NAME}:${major}" \ "${IMAGE_NAME}:latest" echo "EOF" } >> "${GITHUB_OUTPUT}" diff --git a/README.md b/README.md index e4266f2..2470983 100644 --- a/README.md +++ b/README.md @@ -80,13 +80,11 @@ Archives are named `galaxio___.tar.gz` (`.zip` on Windows). ### Option 4 — Docker image The image is published to Docker Hub as `galax-io/galaxio:`, -plus the aliases `galax-io/galaxio:`, `galax-io/galaxio:`, -and `galax-io/galaxio:latest`. +plus the alias `galax-io/galaxio:` and `galax-io/galaxio:latest`. ```sh docker pull galax-io/galaxio:0.1.1 docker pull galax-io/galaxio:0.1 -docker pull galax-io/galaxio:0 docker pull galax-io/galaxio:latest docker run --rm galax-io/galaxio --help ``` From f7f48b6a24a3ff6c8feda83fcffb80e207d40464 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:39:43 -0300 Subject: [PATCH 14/20] ci: dedupe docker build and validate --- .../actions/docker-build-validate/action.yml | 77 +++++++++++++++++++ .github/workflows/ci.yml | 38 ++------- .github/workflows/docker-publish.yml | 48 +++--------- 3 files changed, 92 insertions(+), 71 deletions(-) create mode 100644 .github/actions/docker-build-validate/action.yml diff --git a/.github/actions/docker-build-validate/action.yml b/.github/actions/docker-build-validate/action.yml new file mode 100644 index 0000000..79fa8a8 --- /dev/null +++ b/.github/actions/docker-build-validate/action.yml @@ -0,0 +1,77 @@ +name: docker-build-validate +description: Build a Docker image locally and validate it with a command. + +inputs: + ref: + description: Git ref to check out before building. + required: true + image_name: + description: Docker image name without tag. + required: true + image_tag: + description: Local tag to assign to the built image. + required: false + default: "" + version: + description: Version string embedded into the binary. Defaults to the exact git tag. + required: false + default: "" + validate_command: + description: Command to run inside the built container. + required: false + default: version + +runs: + using: composite + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + fetch-depth: 0 + fetch-tags: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Prepare build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + version='${{ inputs.version }}' + if [[ -z "${version}" ]]; then + version="$(git describe --tags --exact-match HEAD)" + fi + + semver="${version#v}" + image_tag='${{ inputs.image_tag }}' + if [[ -z "${image_tag}" ]]; then + image_tag='${{ inputs.image_name }}:'"${semver}" + fi + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build image locally + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + load: true + push: false + tags: ${{ steps.buildmeta.outputs.image_tag }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + provenance: false + + - name: Validate image with utility command + shell: bash + run: docker run --rm "${{ steps.buildmeta.outputs.image_tag }}" ${{ inputs.validate_command }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 976815f..ac84573 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,39 +67,13 @@ jobs: - test - integration steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - image_tag="galax-io/galaxio:pr-${{ github.event.pull_request.number }}-${GITHUB_SHA::12}" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Build image locally - uses: docker/build-push-action@v6 + - name: Build and validate image + uses: ./.github/actions/docker-build-validate with: - context: . - file: ./Dockerfile - load: true - push: false - tags: ${{ steps.buildmeta.outputs.image_tag }} - build-args: ${{ steps.buildmeta.outputs.build_args }} - provenance: false - - - name: Validate image with utility command - run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version + ref: ${{ github.sha }} + image_name: galax-io/galaxio + version: dev + image_tag: galax-io/galaxio:pr-${{ github.event.pull_request.number }}-${{ github.sha }} integration: name: integration tests diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 36d5560..242aa14 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -19,47 +19,11 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - name: Build and validate image + uses: ./.github/actions/docker-build-validate with: ref: ${{ github.event.workflow_run.head_sha }} - fetch-depth: 0 - fetch-tags: true - - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - version="$(git describe --tags --exact-match HEAD)" - semver="${version#v}" - remainder="${semver#*.}" - minor="${semver%%.*}.${remainder%%.*}" - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - image_tag="${IMAGE_NAME}:${semver}" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Build image locally - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - load: true - push: false - tags: ${{ steps.buildmeta.outputs.image_tag }} - build-args: ${{ steps.buildmeta.outputs.build_args }} - provenance: false - - - name: Validate image with utility command - run: docker run --rm ${{ steps.buildmeta.outputs.image_tag }} version + image_name: galax-io/galaxio publish: name: publish image @@ -80,6 +44,12 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Prepare build metadata id: buildmeta shell: bash From 8b1e433a3f09a3c686b502274cd8ee633df045dc Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 03:52:01 -0300 Subject: [PATCH 15/20] ci: extract docker release metadata --- .../docker-release-metadata/action.yml | 47 +++++++++++++++++++ .github/workflows/docker-publish.yml | 45 +++--------------- 2 files changed, 54 insertions(+), 38 deletions(-) create mode 100644 .github/actions/docker-release-metadata/action.yml diff --git a/.github/actions/docker-release-metadata/action.yml b/.github/actions/docker-release-metadata/action.yml new file mode 100644 index 0000000..0585df4 --- /dev/null +++ b/.github/actions/docker-release-metadata/action.yml @@ -0,0 +1,47 @@ +name: docker-release-metadata +description: Compute Docker build args and release tags from the current git tag. + +inputs: + image_name: + description: Docker image name without tag. + required: true + +outputs: + build_args: + description: Multiline build arguments for docker/build-push-action. + value: ${{ steps.meta.outputs.build_args }} + tags: + description: Multiline list of image tags to push. + value: ${{ steps.meta.outputs.tags }} + version: + description: Normalized semver version without the v prefix. + value: ${{ steps.meta.outputs.version }} + +runs: + using: composite + steps: + - name: Prepare release metadata + id: meta + shell: bash + run: | + set -euo pipefail + + version="$(git describe --tags --exact-match HEAD)" + semver="${version#v}" + remainder="${semver#*.}" + minor="${semver%%.*}.${remainder%%.*}" + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + + { + echo "build_args<> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 242aa14..f998246 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -50,42 +50,11 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Prepare build metadata - id: buildmeta - shell: bash - run: | - set -euo pipefail - - version="$(git describe --tags --exact-match HEAD)" - semver="${version#v}" - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - - { - echo "build_args<> "${GITHUB_OUTPUT}" - - - name: Prepare image tags - id: tags - shell: bash - run: | - set -euo pipefail - - version="$(git describe --tags --exact-match HEAD)" - semver="${version#v}" - remainder="${semver#*.}" - minor="${semver%%.*}.${remainder%%.*}" - - { - echo "tags<> "${GITHUB_OUTPUT}" + - name: Prepare release metadata + id: meta + uses: ./.github/actions/docker-release-metadata + with: + image_name: ${{ env.IMAGE_NAME }} - name: Build and push image uses: docker/build-push-action@v6 @@ -94,6 +63,6 @@ jobs: file: ./Dockerfile platforms: linux/amd64,linux/arm64 push: true - tags: ${{ steps.tags.outputs.tags }} - build-args: ${{ steps.buildmeta.outputs.build_args }} + tags: ${{ steps.meta.outputs.tags }} + build-args: ${{ steps.meta.outputs.build_args }} provenance: false From a2c01322647942b5d8eeb3035db5f651e3bcd4a2 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 04:10:13 -0300 Subject: [PATCH 16/20] ci: checkout before local docker action --- .github/actions/docker-build-validate/action.yml | 10 ---------- .github/workflows/ci.yml | 7 ++++++- .github/workflows/docker-publish.yml | 8 +++++++- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/actions/docker-build-validate/action.yml b/.github/actions/docker-build-validate/action.yml index 79fa8a8..7cc9318 100644 --- a/.github/actions/docker-build-validate/action.yml +++ b/.github/actions/docker-build-validate/action.yml @@ -2,9 +2,6 @@ name: docker-build-validate description: Build a Docker image locally and validate it with a command. inputs: - ref: - description: Git ref to check out before building. - required: true image_name: description: Docker image name without tag. required: true @@ -24,13 +21,6 @@ inputs: runs: using: composite steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref }} - fetch-depth: 0 - fetch-tags: true - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac84573..d5c8b56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,10 +67,15 @@ jobs: - test - integration steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + - name: Build and validate image uses: ./.github/actions/docker-build-validate with: - ref: ${{ github.sha }} image_name: galax-io/galaxio version: dev image_tag: galax-io/galaxio:pr-${{ github.event.pull_request.number }}-${{ github.sha }} diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index f998246..e8a20bf 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -19,10 +19,16 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_sha }} + fetch-depth: 0 + fetch-tags: true + - name: Build and validate image uses: ./.github/actions/docker-build-validate with: - ref: ${{ github.event.workflow_run.head_sha }} image_name: galax-io/galaxio publish: From 14a75745276deefd03b96b679382654d9257ac3e Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 04:33:09 -0300 Subject: [PATCH 17/20] ci: make main drive releases and docker publish --- .../docker-release-metadata/action.yml | 47 ----- .github/actions/release-version/action.yml | 71 +++++++ .github/workflows/ci.yml | 178 +++++++++++++++++- .github/workflows/docker-publish.yml | 74 -------- .github/workflows/release.yml | 34 ---- 5 files changed, 243 insertions(+), 161 deletions(-) delete mode 100644 .github/actions/docker-release-metadata/action.yml create mode 100644 .github/actions/release-version/action.yml delete mode 100644 .github/workflows/docker-publish.yml delete mode 100644 .github/workflows/release.yml diff --git a/.github/actions/docker-release-metadata/action.yml b/.github/actions/docker-release-metadata/action.yml deleted file mode 100644 index 0585df4..0000000 --- a/.github/actions/docker-release-metadata/action.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: docker-release-metadata -description: Compute Docker build args and release tags from the current git tag. - -inputs: - image_name: - description: Docker image name without tag. - required: true - -outputs: - build_args: - description: Multiline build arguments for docker/build-push-action. - value: ${{ steps.meta.outputs.build_args }} - tags: - description: Multiline list of image tags to push. - value: ${{ steps.meta.outputs.tags }} - version: - description: Normalized semver version without the v prefix. - value: ${{ steps.meta.outputs.version }} - -runs: - using: composite - steps: - - name: Prepare release metadata - id: meta - shell: bash - run: | - set -euo pipefail - - version="$(git describe --tags --exact-match HEAD)" - semver="${version#v}" - remainder="${semver#*.}" - minor="${semver%%.*}.${remainder%%.*}" - commit="$(git rev-parse --short=12 HEAD)" - date="$(git log -1 --format=%cI HEAD)" - - { - echo "build_args<> "${GITHUB_OUTPUT}" diff --git a/.github/actions/release-version/action.yml b/.github/actions/release-version/action.yml new file mode 100644 index 0000000..7efa543 --- /dev/null +++ b/.github/actions/release-version/action.yml @@ -0,0 +1,71 @@ +name: release-version +description: Compute the next release version from conventional commits since the latest tag. + +outputs: + bump: + description: Version bump kind. + value: ${{ steps.version.outputs.bump }} + version: + description: Next semver without the v prefix. + value: ${{ steps.version.outputs.version }} + tag_name: + description: Next git tag with the v prefix. + value: ${{ steps.version.outputs.tag_name }} + minor_tag: + description: Major.minor Docker tag alias. + value: ${{ steps.version.outputs.minor_tag }} + previous_tag: + description: Previous git tag used as the release base. + value: ${{ steps.version.outputs.previous_tag }} + +runs: + using: composite + steps: + - name: Compute next version + id: version + shell: bash + run: | + set -euo pipefail + + previous_tag="$(git tag --list 'v*' --sort=-version:refname | head -n1)" + if [[ -z "${previous_tag}" ]]; then + previous_tag="v0.0.0" + range="HEAD" + else + range="${previous_tag}..HEAD" + fi + + bump="patch" + if git log --format='%s%n%b' "${range}" | grep -Eq 'BREAKING CHANGE|^[^[:space:]:]+(\([^)]+\))?!:'; then + bump="major" + elif git log --format='%s' "${range}" | grep -Eq '^feat(\([^)]+\))?: '; then + bump="minor" + fi + + version_core="${previous_tag#v}" + IFS='.' read -r major minor patch <<< "${version_core}" + + case "${bump}" in + major) + major=$((major + 1)) + minor=0 + patch=0 + ;; + minor) + minor=$((minor + 1)) + patch=0 + ;; + patch) + patch=$((patch + 1)) + ;; + esac + + version="${major}.${minor}.${patch}" + + { + echo "bump=${bump}" + echo "version=${version}" + echo "tag_name=v${version}" + echo "minor_tag=${major}.${minor}" + echo "previous_tag=${previous_tag}" + } >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5c8b56..a754456 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,48 @@ jobs: - name: Build run: go build -trimpath -o dist/galaxio ./cmd/galaxio - docker-image: + integration: + name: integration tests + runs-on: ubuntu-latest + needs: test + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Integration tests + run: go test -tags=integration -race -count=1 ./... + + release-version: + name: release version + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: + - test + - integration + outputs: + bump: ${{ steps.version.outputs.bump }} + version: ${{ steps.version.outputs.version }} + tag_name: ${{ steps.version.outputs.tag_name }} + minor_tag: ${{ steps.version.outputs.minor_tag }} + previous_tag: ${{ steps.version.outputs.previous_tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Compute release version + id: version + uses: ./.github/actions/release-version + + docker-image-pr: name: docker image runs-on: ubuntu-latest if: github.event_name == 'pull_request' @@ -80,13 +121,56 @@ jobs: version: dev image_tag: galax-io/galaxio:pr-${{ github.event.pull_request.number }}-${{ github.sha }} - integration: - name: integration tests + docker-image-main: + name: docker image runs-on: ubuntu-latest - needs: test + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: + - test + - integration + - release-version + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + fetch-tags: true + + - name: Build and validate image + uses: ./.github/actions/docker-build-validate + with: + image_name: galax-io/galaxio + version: ${{ needs.release-version.outputs.tag_name }} + image_tag: galax-io/galaxio:${{ needs.release-version.outputs.version }} + + - name: Export validated image artifact + run: docker save --output /tmp/galaxio-image.tar galax-io/galaxio:${{ needs.release-version.outputs.version }} + + - name: Upload validated image artifact + uses: actions/upload-artifact@v4 + with: + name: galaxio-image-${{ github.sha }} + path: /tmp/galaxio-image.tar + if-no-files-found: error + retention-days: 1 + + release: + name: release + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: + - docker-image-main + - release-version + permissions: + contents: write steps: - name: Checkout uses: actions/checkout@v4 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + fetch-tags: true - name: Set up Go uses: actions/setup-go@v5 @@ -94,5 +178,87 @@ jobs: go-version-file: go.mod cache: true - - name: Integration tests - run: go test -tags=integration -race -count=1 ./... + - name: Create and push git tag + env: + TAG_NAME: ${{ needs.release-version.outputs.tag_name }} + run: | + set -euo pipefail + + if git ls-remote --exit-code --tags origin "refs/tags/${TAG_NAME}" >/dev/null 2>&1; then + echo "Tag ${TAG_NAME} already exists on origin, skipping push." + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME}" + git push origin "${TAG_NAME}" + + - name: Check existing GitHub release + id: release_exists + env: + TAG_NAME: ${{ needs.release-version.outputs.tag_name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + if gh release view "${TAG_NAME}" >/dev/null 2>&1; then + echo "exists=true" >> "${GITHUB_OUTPUT}" + else + echo "exists=false" >> "${GITHUB_OUTPUT}" + fi + + - name: Run GoReleaser + if: steps.release_exists.outputs.exists != 'true' + uses: goreleaser/goreleaser-action@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + distribution: goreleaser + version: latest + args: release --clean + + publish-image: + name: publish image + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: + - docker-image-main + - release + - release-version + steps: + - name: Download validated image artifact + uses: actions/download-artifact@v4 + with: + name: galaxio-image-${{ github.sha }} + path: /tmp + + - name: Load validated image + run: docker load --input /tmp/galaxio-image.tar + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Tag image for Docker Hub + env: + VERSION: ${{ needs.release-version.outputs.version }} + MINOR_TAG: ${{ needs.release-version.outputs.minor_tag }} + run: | + set -euo pipefail + + docker tag "galax-io/galaxio:${VERSION}" "galax-io/galaxio:${MINOR_TAG}" + docker tag "galax-io/galaxio:${VERSION}" "galax-io/galaxio:latest" + + - name: Push image tags + env: + VERSION: ${{ needs.release-version.outputs.version }} + MINOR_TAG: ${{ needs.release-version.outputs.minor_tag }} + run: | + set -euo pipefail + + docker push "galax-io/galaxio:${VERSION}" + docker push "galax-io/galaxio:${MINOR_TAG}" + docker push "galax-io/galaxio:latest" diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index e8a20bf..0000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: docker-publish - -on: - workflow_run: - workflows: - - release - types: - - completed - -permissions: - contents: read - -env: - IMAGE_NAME: galax-io/galaxio - -jobs: - build-and-validate: - name: build and validate image - if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.workflow_run.head_sha }} - fetch-depth: 0 - fetch-tags: true - - - name: Build and validate image - uses: ./.github/actions/docker-build-validate - with: - image_name: galax-io/galaxio - - publish: - name: publish image - needs: build-and-validate - if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.workflow_run.head_sha }} - fetch-depth: 0 - fetch-tags: true - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Prepare release metadata - id: meta - uses: ./.github/actions/docker-release-metadata - with: - image_name: ${{ env.IMAGE_NAME }} - - - name: Build and push image - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.meta.outputs.tags }} - build-args: ${{ steps.meta.outputs.build_args }} - provenance: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 9a96995..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: release - -on: - push: - tags: - - "v*" - -permissions: - contents: write - -jobs: - goreleaser: - name: goreleaser - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - cache: true - - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6 - with: - distribution: goreleaser - version: latest - args: release --clean - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From fc821f5a9aecbb099590d727678a87586f923251 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 04:35:30 -0300 Subject: [PATCH 18/20] ci: compute release version after main image build --- .github/workflows/ci.yml | 55 ++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a754456..c2989a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,30 +76,6 @@ jobs: - name: Integration tests run: go test -tags=integration -race -count=1 ./... - release-version: - name: release version - runs-on: ubuntu-latest - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - needs: - - test - - integration - outputs: - bump: ${{ steps.version.outputs.bump }} - version: ${{ steps.version.outputs.version }} - tag_name: ${{ steps.version.outputs.tag_name }} - minor_tag: ${{ steps.version.outputs.minor_tag }} - previous_tag: ${{ steps.version.outputs.previous_tag }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - fetch-tags: true - - - name: Compute release version - id: version - uses: ./.github/actions/release-version - docker-image-pr: name: docker image runs-on: ubuntu-latest @@ -128,7 +104,12 @@ jobs: needs: - test - integration - - release-version + outputs: + bump: ${{ steps.version.outputs.bump }} + version: ${{ steps.version.outputs.version }} + tag_name: ${{ steps.version.outputs.tag_name }} + minor_tag: ${{ steps.version.outputs.minor_tag }} + previous_tag: ${{ steps.version.outputs.previous_tag }} steps: - name: Checkout uses: actions/checkout@v4 @@ -137,15 +118,19 @@ jobs: fetch-depth: 0 fetch-tags: true + - name: Compute release version + id: version + uses: ./.github/actions/release-version + - name: Build and validate image uses: ./.github/actions/docker-build-validate with: image_name: galax-io/galaxio - version: ${{ needs.release-version.outputs.tag_name }} - image_tag: galax-io/galaxio:${{ needs.release-version.outputs.version }} + version: ${{ steps.version.outputs.tag_name }} + image_tag: galax-io/galaxio:${{ steps.version.outputs.version }} - name: Export validated image artifact - run: docker save --output /tmp/galaxio-image.tar galax-io/galaxio:${{ needs.release-version.outputs.version }} + run: docker save --output /tmp/galaxio-image.tar galax-io/galaxio:${{ steps.version.outputs.version }} - name: Upload validated image artifact uses: actions/upload-artifact@v4 @@ -161,7 +146,6 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: - docker-image-main - - release-version permissions: contents: write steps: @@ -180,7 +164,7 @@ jobs: - name: Create and push git tag env: - TAG_NAME: ${{ needs.release-version.outputs.tag_name }} + TAG_NAME: ${{ needs.docker-image-main.outputs.tag_name }} run: | set -euo pipefail @@ -197,7 +181,7 @@ jobs: - name: Check existing GitHub release id: release_exists env: - TAG_NAME: ${{ needs.release-version.outputs.tag_name }} + TAG_NAME: ${{ needs.docker-image-main.outputs.tag_name }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail @@ -225,7 +209,6 @@ jobs: needs: - docker-image-main - release - - release-version steps: - name: Download validated image artifact uses: actions/download-artifact@v4 @@ -244,8 +227,8 @@ jobs: - name: Tag image for Docker Hub env: - VERSION: ${{ needs.release-version.outputs.version }} - MINOR_TAG: ${{ needs.release-version.outputs.minor_tag }} + VERSION: ${{ needs.docker-image-main.outputs.version }} + MINOR_TAG: ${{ needs.docker-image-main.outputs.minor_tag }} run: | set -euo pipefail @@ -254,8 +237,8 @@ jobs: - name: Push image tags env: - VERSION: ${{ needs.release-version.outputs.version }} - MINOR_TAG: ${{ needs.release-version.outputs.minor_tag }} + VERSION: ${{ needs.docker-image-main.outputs.version }} + MINOR_TAG: ${{ needs.docker-image-main.outputs.minor_tag }} run: | set -euo pipefail From a38a75cc2ac0e49c643b4e4f726c3db2b9e50546 Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 04:37:26 -0300 Subject: [PATCH 19/20] ci: publish docker image via buildkit cache --- .github/workflows/ci.yml | 107 +++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2989a4..64098bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,21 +122,44 @@ jobs: id: version uses: ./.github/actions/release-version - - name: Build and validate image - uses: ./.github/actions/docker-build-validate - with: - image_name: galax-io/galaxio - version: ${{ steps.version.outputs.tag_name }} - image_tag: galax-io/galaxio:${{ steps.version.outputs.version }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Prepare image build metadata + id: buildmeta + shell: bash + run: | + set -euo pipefail + + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" - - name: Export validated image artifact - run: docker save --output /tmp/galaxio-image.tar galax-io/galaxio:${{ steps.version.outputs.version }} + { + echo "build_args<> "${GITHUB_OUTPUT}" - - name: Upload validated image artifact + - name: Build image locally with BuildKit cache + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + load: true + push: false + tags: galax-io/galaxio:${{ steps.version.outputs.version }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + cache-to: type=local,dest=/tmp/buildx-cache,mode=max + provenance: false + + - name: Validate image with utility command + run: docker run --rm galax-io/galaxio:${{ steps.version.outputs.version }} version + + - name: Upload BuildKit cache artifact uses: actions/upload-artifact@v4 with: - name: galaxio-image-${{ github.sha }} - path: /tmp/galaxio-image.tar + name: buildx-cache-${{ github.sha }} + path: /tmp/buildx-cache if-no-files-found: error retention-days: 1 @@ -210,14 +233,24 @@ jobs: - docker-image-main - release steps: - - name: Download validated image artifact + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + fetch-tags: true + + - name: Download BuildKit cache artifact uses: actions/download-artifact@v4 with: - name: galaxio-image-${{ github.sha }} - path: /tmp + name: buildx-cache-${{ github.sha }} + path: /tmp/buildx-cache + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 - - name: Load validated image - run: docker load --input /tmp/galaxio-image.tar + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub uses: docker/login-action@v3 @@ -225,23 +258,35 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Tag image for Docker Hub - env: - VERSION: ${{ needs.docker-image-main.outputs.version }} - MINOR_TAG: ${{ needs.docker-image-main.outputs.minor_tag }} - run: | - set -euo pipefail - - docker tag "galax-io/galaxio:${VERSION}" "galax-io/galaxio:${MINOR_TAG}" - docker tag "galax-io/galaxio:${VERSION}" "galax-io/galaxio:latest" - - - name: Push image tags + - name: Prepare image build metadata + id: buildmeta env: VERSION: ${{ needs.docker-image-main.outputs.version }} - MINOR_TAG: ${{ needs.docker-image-main.outputs.minor_tag }} run: | set -euo pipefail - docker push "galax-io/galaxio:${VERSION}" - docker push "galax-io/galaxio:${MINOR_TAG}" - docker push "galax-io/galaxio:latest" + commit="$(git rev-parse --short=12 HEAD)" + date="$(git log -1 --format=%cI HEAD)" + + { + echo "build_args<> "${GITHUB_OUTPUT}" + + - name: Build and push image with BuildKit + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.buildmeta.outputs.tags }} + build-args: ${{ steps.buildmeta.outputs.build_args }} + cache-from: type=local,src=/tmp/buildx-cache + provenance: false From 1ac7a143a6feb0638de3f487ad56eb0a0d0b906a Mon Sep 17 00:00:00 2001 From: John Axe Date: Sun, 24 May 2026 04:58:54 -0300 Subject: [PATCH 20/20] ci: remove duplicate pr docker job --- .github/workflows/ci.yml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66181ef..64098bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,27 +59,6 @@ jobs: - name: Build run: go build -trimpath -o dist/galaxio ./cmd/galaxio - docker-image: - name: docker image - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' - needs: - - test - - integration - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.sha }} - fetch-depth: 0 - - - name: Build and validate image - uses: ./.github/actions/docker-build-validate - with: - image_name: galax-io/galaxio - version: dev - image_tag: galax-io/galaxio:pr-${{ github.event.pull_request.number }}-${{ github.sha }} - integration: name: integration tests runs-on: ubuntu-latest