diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1cbc276..da6d7f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,9 @@ on: push: tags: - 'v*' + # Invoked by the Tag Release workflow at the freshly pushed tag; tags + # created with the default GITHUB_TOKEN do not fire the push trigger. + workflow_dispatch: {} permissions: contents: write @@ -30,7 +33,7 @@ jobs: - name: Run GoReleaser uses: goreleaser/goreleaser-action@v5 with: - version: latest + version: "~> v2" args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml new file mode 100644 index 0000000..5b63ee3 --- /dev/null +++ b/.github/workflows/tag-release.yml @@ -0,0 +1,55 @@ +name: Tag Release + +# One-click release: run this from the Actions tab with a version like +# v1.2.0. It tags main and kicks off the existing Release workflow, which +# re-runs tests and publishes binaries via GoReleaser. + +on: + workflow_dispatch: + inputs: + version: + description: "Version to release (vX.Y.Z)" + required: true + type: string + +permissions: + contents: write + actions: write + +jobs: + tag: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + - name: Validate version + env: + VERSION: ${{ inputs.version }} + run: | + if ! echo "$VERSION" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Version must look like vX.Y.Z, got '$VERSION'" + exit 1 + fi + if git rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then + echo "::error::Tag $VERSION already exists" + exit 1 + fi + - name: Create and push tag + env: + VERSION: ${{ inputs.version }} + run: | + git config user.name "${{ github.actor }}" + git config user.email "${{ github.actor }}@users.noreply.github.com" + git tag -a "$VERSION" -m "Release $VERSION" + git push origin "$VERSION" + - name: Start release workflow + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ inputs.version }} + run: | + # Tags pushed with the default GITHUB_TOKEN do not fire + # push-triggered workflows, so start the release explicitly at + # the new tag. + gh workflow run release.yml --ref "$VERSION" diff --git a/README.md b/README.md index 1af5e0b..0d98657 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,9 @@ platform-specific improvements before diving in. - CI (`.github/workflows/ci.yml`) runs `golangci-lint`, unit tests with race detection, integration tests, and validates startup performance (<80ms p95). +- To cut a release, run the **Tag Release** workflow from the Actions tab + with a `vX.Y.Z` version (or push a `v*` tag manually). It tags `main` and + hands off to the Release workflow. - Releases use GoReleaser (`.goreleaser.yml`) to ship signed binaries for Linux/macOS (amd64/arm64) and Windows (amd64), plus checksums. - `go install github.com/veteranbv/sysgreet@VERSION` is validated during the