diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3550d25 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,38 @@ +name: Release + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + release: + types: + - published + +jobs: + goreleaser: + if: github.event_name == 'release' && github.event.action == 'published' + runs-on: ubuntu-latest + environment: release + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.dev.md b/README.dev.md index 235f0a8..0517e58 100644 --- a/README.dev.md +++ b/README.dev.md @@ -1,13 +1,26 @@ +# 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. +* Your environment also must have `bash`, `git` and `sed` available. + # Releasing -* Install `goreleaser`. Refer to its docs. -* Set a `GITHUB_TOKEN` environment variable. Refer to `goreleaser` docs for - information. -* Update `CHANGELOG.md`. - * Mention recent changes. - * Set a version if there is not one. - * Set a release date. -* Commit `CHANGELOG.md`. -* Tag the release: `git tag -a v1.2.3 -m 'Tag v1.2.3'`. -* Push the tag: `git push origin v1.2.3`. -* Run `goreleaser`. +* Review open issues and PRs to see if anything needs to be addressed + before release. +* Create a branch e.g. `horgh/release` and switch to it. + * `main` is protected. +* Set the release version and release date in `CHANGELOG.md`. Be sure + the version follows [Semantic Versionsing](https://semver.org/). + * Mention recent changes if needed. +* Commit these changes. +* Run `dev-bin/release.sh`. + * You might need to initialize/update submodules to successfully run tests, + eg. `git submodule update --init --recursive`. +* 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 new file mode 100755 index 0000000..f8c771d --- /dev/null +++ b/dev-bin/release.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -eu -o pipefail + +changelog=$(cat CHANGELOG.md) + +regex=' +## ([0-9]+\.[0-9]+\.[0-9]+) \(([0-9]{4}-[0-9]{2}-[0-9]{2})\) + +((.| +)*) +' + +if [[ ! $changelog =~ $regex ]]; then + echo "Could not find date line in change log!" + exit 1 +fi + +version="${BASH_REMATCH[1]}" +date="${BASH_REMATCH[2]}" +notes="$(echo "${BASH_REMATCH[3]}" | sed -n -E '/^## [0-9]+\.[0-9]+\.[0-9]+/,$!p')" +tag="v$version" + +if [[ "$date" != "$(date +"%Y-%m-%d")" ]]; then + echo "$date is not today!" + exit 1 +fi + +if [ -n "$(git status --porcelain)" ]; then + echo ". is not clean." >&2 + exit 1 +fi + +echo $'\nVersion:' +echo "$version" + +echo $'\nRelease notes:' +echo "$notes" + +read -e -p "Push to origin? " should_push + +if [ "$should_push" != "y" ]; then + echo "Aborting" + exit 1 +fi + +git push + +gh release create --target "$(git branch --show-current)" -t "$version" -n "$notes" "$tag"