From 40eb966299991ee0d1efa3a893c8e13ca5221e20 Mon Sep 17 00:00:00 2001 From: moltenhub-bot Date: Tue, 19 May 2026 19:00:09 +0000 Subject: [PATCH] Fix prod release tag automation --- .github/workflows/deploy-prod.yml | 112 ++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index a0ae4d5..30dbc79 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -4,10 +4,24 @@ on: workflow_dispatch: inputs: source_tag: - description: Docker tag to promote to latest-* release tags + description: Docker tag to promote to the latest release tag required: true default: vnext type: string + bump: + description: Semver version bump for the release tag + required: true + default: patch + type: choice + options: + - patch + - minor + - major + first_release: + description: First release tag to use when no vX.Y.Z tags exist + required: true + default: v1.0.0 + type: string permissions: contents: read @@ -34,6 +48,12 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 + fetch-tags: true + + - name: Configure Git author + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - name: Setup Go uses: actions/setup-go@v6 @@ -51,12 +71,23 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Promote existing image + env: + SOURCE_TAG: ${{ github.event.inputs.source_tag }} run: | + set -euo pipefail + + case "${SOURCE_TAG}" in + ''|*[!A-Za-z0-9_.-]*) + echo "Invalid source_tag: ${SOURCE_TAG}" >&2 + exit 1 + ;; + esac + TAG_ARGS="--tag moltenai/moltenhub-dispatch:latest" docker buildx imagetools create \ ${TAG_ARGS} \ - moltenai/moltenhub-dispatch:${{ github.event.inputs.source_tag }}${{ matrix.source_suffix }} + "moltenai/moltenhub-dispatch:${SOURCE_TAG}" - name: Resolve promoted image digest id: digest @@ -74,9 +105,70 @@ jobs: - name: Compute GitHub Release tag id: release + env: + BUMP: ${{ github.event.inputs.bump }} + FIRST_RELEASE: ${{ github.event.inputs.first_release }} run: | - RELEASE_TAG="$(date -u +'v%Y.%-m.%-d')+${GITHUB_RUN_NUMBER}.${GITHUB_RUN_ATTEMPT}" - echo "tag=${RELEASE_TAG}" >> "$GITHUB_OUTPUT" + set -euo pipefail + + case "${BUMP}" in + patch|minor|major) ;; + *) echo "Invalid bump: ${BUMP}" >&2; exit 1 ;; + esac + + if [[ ! "${FIRST_RELEASE}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid first_release: ${FIRST_RELEASE}" >&2 + exit 1 + fi + + LATEST_TAG="" + while IFS= read -r tag; do + if [[ "${tag}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + LATEST_TAG="${tag}" + break + fi + done < <(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname) + + if [ -z "${LATEST_TAG}" ]; then + RELEASE_TAG="${FIRST_RELEASE}" + else + VERSION="${LATEST_TAG#v}" + IFS=. read -r MAJOR MINOR PATCH <<< "${VERSION}" + + case "${BUMP}" in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + esac + + RELEASE_TAG="v${MAJOR}.${MINOR}.${PATCH}" + fi + + if git rev-parse -q --verify "refs/tags/${RELEASE_TAG}" >/dev/null; then + echo "Release tag already exists: ${RELEASE_TAG}" >&2 + exit 1 + fi + + echo "tag=${RELEASE_TAG}" >> "${GITHUB_OUTPUT}" + echo "bump=${BUMP}" >> "${GITHUB_OUTPUT}" + + - name: Create GitHub Release tag + env: + RELEASE_TAG: ${{ steps.release.outputs.tag }} + run: | + set -euo pipefail + git tag -a "$RELEASE_TAG" -m "Release $RELEASE_TAG" + git push origin "refs/tags/$RELEASE_TAG" + git checkout --detach "$RELEASE_TAG" - name: Publish GitHub Release artifacts uses: goreleaser/goreleaser-action@v7 @@ -86,5 +178,15 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GORELEASER_CURRENT_TAG: ${{ steps.release.outputs.tag }} SOURCE_TAG: ${{ github.event.inputs.source_tag }} + + - name: Summarize release + run: | + { + echo "## Production release" + echo + echo "- Release tag: \`${{ steps.release.outputs.tag }}\`" + echo "- Bump type: \`${{ steps.release.outputs.bump }}\`" + echo "- Promoted source image tag: \`${{ github.event.inputs.source_tag }}\`" + echo "- Latest image tag: \`latest\`" + } >> "$GITHUB_STEP_SUMMARY"