Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 42 additions & 24 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Cut a release from GitHub: Actions → Release → Run workflow (no local git required).
# Reads VERSION from the Makefile on master, bumps per dropdown, commits bump, then publishes.
# Requires a "release" environment (see README) when using deployment protection.
# Bumps from the latest published release tag; works with protected master (no direct push).
# Opens a PR to sync the Makefile after publishing.
name: Release

on:
workflow_dispatch:
inputs:
bump:
description: "Bump from Makefile VERSION on master (e.g. 1.3.0 + patch → 1.3.1)"
description: "Bump from latest release (e.g. v1.3.0 + patch → v1.3.1)"
required: true
type: choice
default: patch
Expand All @@ -18,6 +18,7 @@ on:

permissions:
contents: write
pull-requests: write

jobs:
release:
Expand All @@ -38,15 +39,23 @@ jobs:
id: meta
env:
BUMP: ${{ inputs.bump }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
CURRENT=$(sed -n 's/^VERSION ?=[[:space:]]*//p' Makefile | head -1)
LATEST_TAG=$(gh release list --limit 1 --json tagName --jq '.[0].tagName // empty')
if [ -n "${LATEST_TAG}" ]; then
CURRENT="${LATEST_TAG#v}"
echo "Latest published release: ${LATEST_TAG}"
else
CURRENT=$(sed -n 's/^VERSION ?=[[:space:]]*//p' Makefile | head -1)
echo "No releases yet; using Makefile VERSION=${CURRENT}"
fi
if [ -z "${CURRENT}" ]; then
echo "Could not read VERSION from Makefile"
echo "Could not determine current version"
exit 1
fi
if ! [[ "${CURRENT}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
echo "Makefile VERSION must be X.Y.Z (got: ${CURRENT})"
echo "Current version must be X.Y.Z (got: ${CURRENT})"
exit 1
fi
MAJOR="${BASH_REMATCH[1]}"
Expand All @@ -63,7 +72,6 @@ jobs:
esac
VERSION="${MAJOR}.${MINOR}.${PATCH}"
TAG="v${VERSION}"
echo "Current Makefile VERSION: ${CURRENT}"
echo "Bump: ${BUMP} → releasing ${VERSION}"
if git ls-remote --exit-code origin "refs/tags/${TAG}" >/dev/null 2>&1; then
echo "Tag ${TAG} already exists on remote"
Expand All @@ -84,23 +92,6 @@ jobs:
exit 1
fi

- name: Bump Makefile on master
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.meta.outputs.version }}
run: |
set -euo pipefail
sed -i "s/^VERSION ?=.*/VERSION ?= ${VERSION}/" Makefile
if ! grep -q "^VERSION ?= ${VERSION}$" Makefile; then
echo "Failed to update Makefile VERSION"
exit 1
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Makefile
git commit -m "chore: bump VERSION to ${VERSION}"
git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" HEAD:master

- name: Run tests
run: |
go test ./... -count=1
Expand Down Expand Up @@ -139,3 +130,30 @@ jobs:
files: dist/*
generate_release_notes: true
overwrite_files: false

- name: Open Makefile sync pull request
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.meta.outputs.version }}
TAG: ${{ steps.meta.outputs.tag }}
run: |
set -euo pipefail
CURRENT=$(sed -n 's/^VERSION ?=[[:space:]]*//p' Makefile | head -1)
if [ "${CURRENT}" = "${VERSION}" ]; then
echo "Makefile already at ${VERSION}; no PR needed"
exit 0
fi
BRANCH="chore/bump-version-${VERSION}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "${BRANCH}"
sed -i "s/^VERSION ?=.*/VERSION ?= ${VERSION}/" Makefile
git add Makefile
git commit -m "chore: bump VERSION to ${VERSION}"
git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${BRANCH}"
gh pr create \
--base master \
--head "${BRANCH}" \
--title "chore: bump VERSION to ${VERSION}" \
--body "Automated after ${TAG}. Merge to keep the Makefile in sync with the latest release."
gh pr merge --auto --squash || echo "Enable auto-merge on the PR or merge manually"
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ Ensure **Settings** → **Actions** → **General** → **Workflow permissions**

### Cut a release

1. Ensure `VERSION` in the **Makefile** on `master` matches the **last published** release (e.g. `1.3.0` after v1.3.0 is out)
2. **Actions** → **Release** → **Run workflow** — choose **patch** (default), **minor**, or **major**; CI bumps the Makefile (e.g. `1.3.0` + patch → `1.3.1`), commits to `master`, then builds and publishes
1. **Actions** → **Release** → **Run workflow** — choose **patch** (default), **minor**, or **major**
2. CI reads the **latest published release** (e.g. `v1.3.0`), computes the next version (`1.3.1` for patch), runs tests, and publishes binaries
3. Approve the **release** environment deployment if reviewers are configured
4. Merge the automated **Makefile bump PR** when it appears (required for protected `master`; keeps `make build` in sync)

The workflow refuses to publish if that tag or GitHub Release already exists.

Expand Down
Loading