diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 65f85c3..0710b94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,13 +6,41 @@ on: push: branches: - main - release: - types: - - published + tags: + - 'v*' + +permissions: {} jobs: + goreleaser-check: + name: Check GoReleaser + if: github.ref_type != 'tag' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: stable + cache: false + + - name: Check GoReleaser + uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 + with: + distribution: goreleaser + version: latest + args: release --snapshot --clean --skip=publish + goreleaser: - if: github.event_name == 'release' && github.event.action == 'published' + name: Release with GoReleaser + if: github.event_name == 'push' && github.ref_type == 'tag' runs-on: ubuntu-latest environment: release permissions: @@ -24,6 +52,23 @@ jobs: fetch-depth: 0 persist-credentials: false + # On a tag push, actions/checkout replaces the annotated tag with a + # lightweight tag. Fetch the tags again to get the tag message. + - name: Fetch annotated tags + run: git fetch --force --tags + + - name: Get release notes from the tag + run: | + if [ "$(git cat-file -t "refs/tags/$GITHUB_REF_NAME")" != tag ]; then + echo "Tag $GITHUB_REF_NAME is not an annotated tag. Create it with dev-bin/release.sh." + exit 1 + fi + git tag -l --format='%(contents:body)' "$GITHUB_REF_NAME" > "$RUNNER_TEMP/release-notes.md" + if ! grep -q '[^[:space:]]' "$RUNNER_TEMP/release-notes.md"; then + echo "Tag $GITHUB_REF_NAME has no release notes. Create it with dev-bin/release.sh." + exit 1 + fi + - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: @@ -35,6 +80,7 @@ jobs: with: distribution: goreleaser version: latest - args: release --clean + args: release --clean --release-notes ${{ runner.temp }}/release-notes.md env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GORELEASER_CURRENT_TAG: ${{ github.ref_name }} diff --git a/.goreleaser.yml b/.goreleaser.yml index dc0ffcd..b3136e6 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -41,9 +41,6 @@ checksum: snapshot: version_template: "{{ .Tag }}-next" -changelog: - disable: true - nfpms: - id: 'mmdbinspect' builds: @@ -68,4 +65,4 @@ nfpms: dst: '/usr/share/doc/mmdbinspect/README.md' release: - target_commitish: "{{ .FullCommit }}" + name_template: "{{.Version}}" diff --git a/README.dev.md b/README.dev.md index c5e2689..9db8fa6 100644 --- a/README.dev.md +++ b/README.dev.md @@ -1,8 +1,7 @@ # Prereqs - You must have the [GitHub CLI tool (gh)](https://cli.github.com/) installed, - in your path, and logged into an account that can make GitHub releases on the - repo. + in your path, and logged into an account that can push to the repo. - Your environment also must have `bash`, `git` and `sed` available. # Releasing @@ -18,9 +17,13 @@ - Run `dev-bin/release.sh`. - You might need to initialize/update submodules to successfully run tests, eg. `git submodule update --init --recursive`. + - The script pushes the branch. Then it pushes an annotated tag, for example + `v2.0.1`. The tag message contains the release notes from `CHANGELOG.md`. +- The tag push starts the Release workflow. The authorized releasers receive an + email to review the pending deployment. If you are an authorized releaser, + approve the deployment. If you are not, wait for an authorized releaser to do + so. +- After the approval, GoReleaser creates the GitHub release with the notes from + the tag. It uploads the binaries and packages, then publishes the release. - Verify the release on the GitHub Releases page. -- If everything goes well, the authorized releasers will receive an email to - review the pending deployment. If you are an authorized releaser, you will - need to approve the release deployment run. If you are not, you will have to - wait for an authorized releaser to do so. - Make a PR and get it merged. diff --git a/dev-bin/release.sh b/dev-bin/release.sh index 2eb2327..a639756 100755 --- a/dev-bin/release.sh +++ b/dev-bin/release.sh @@ -69,6 +69,11 @@ date="${BASH_REMATCH[3]}" notes="$(echo "${BASH_REMATCH[4]}" | sed -n -E '/^## [0-9]+\.[0-9]+\.[0-9]+(-[^ ]+)?/,$!p')" tag="v$version" +if ! grep -q '[^[:space:]]' <<<"$notes"; then + echo "Release notes for $tag are empty. Add notes to CHANGELOG.md." >&2 + exit 1 +fi + if [[ "$date" != "$(date +"%Y-%m-%d")" ]]; then echo "$date is not today!" exit 1 @@ -94,4 +99,10 @@ fi git push -gh release create --target "$(git branch --show-current)" -t "$version" -n "$notes" "$tag" +# The tag message is the version, a blank line, and the release notes. +# "whitespace" keeps Markdown headings and adds a newline before a signature. +git tag -a --cleanup=whitespace -m "$version + +$notes" "$tag" + +git push origin "refs/tags/$tag"