From 86b376ae7bc127c3b4bd9563cc46bdbe78d247a6 Mon Sep 17 00:00:00 2001 From: d6e Date: Sun, 4 Oct 2026 20:25:31 -0700 Subject: [PATCH] Create a release when a tag is pushed on main The release workflow ran only after someone created a GitHub release by hand. It now runs when a tag that starts with v is pushed: - It stops if the tagged commit is not on main. - For a tag without a hyphen, the tag must match the version in Cargo.toml. A tag with a hyphen (for example v0.6.1-rc.2) becomes a pre-release and skips that check. - It runs the tests, creates the release with generated notes (or uses a release that already exists for the tag), and attaches the three builds. One workflow creates the release and builds the assets, because GitHub does not start other workflows for a release that a workflow creates with its own token. ARCHITECTURE.md describes the steps. --- .github/workflows/release.yml | 77 ++++++++++++++++++++++++++++++++--- ARCHITECTURE.md | 12 ++++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6caa9dd..8983678 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,10 @@ name: Release +# Push a tag such as v0.6.1 or v0.6.1-rc.1 on a commit of main to publish a +# release. A tag with a hyphen (for example -rc.1) becomes a pre-release. on: - release: - types: [created] + push: + tags: ["v*"] permissions: contents: write @@ -11,7 +13,71 @@ env: CARGO_TERM_COLOR: always jobs: + verify: + runs-on: ubuntu-latest + outputs: + prerelease: ${{ steps.kind.outputs.prerelease }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check that the tag is on main + run: | + git fetch origin main + if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then + echo "::error::Tag $GITHUB_REF_NAME is not on main" + exit 1 + fi + + - name: Check the tag against Cargo.toml + id: kind + run: | + tag="${GITHUB_REF_NAME#v}" + version="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -n 1)" + if [[ "$tag" == *-* ]]; then + echo "prerelease=true" >> "$GITHUB_OUTPUT" + else + if [[ "$tag" != "$version" ]]; then + echo "::error::Tag $GITHUB_REF_NAME does not match version $version in Cargo.toml" + exit 1 + fi + echo "prerelease=false" >> "$GITHUB_OUTPUT" + fi + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y libasound2-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Run tests + run: cargo test + + create-release: + needs: verify + runs-on: ubuntu-latest + steps: + - name: Create the release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PRERELEASE: ${{ needs.verify.outputs.prerelease }} + run: | + if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then + echo "Release $GITHUB_REF_NAME exists already" + exit 0 + fi + flags=() + if [[ "$PRERELEASE" == "true" ]]; then + flags+=(--prerelease) + fi + gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" \ + --verify-tag --title "$GITHUB_REF_NAME" --generate-notes "${flags[@]}" + build: + needs: create-release strategy: matrix: include: @@ -53,8 +119,7 @@ jobs: cp "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}" "${{ matrix.asset_name }}" - name: Upload release asset - uses: softprops/action-gh-release@v2 - with: - files: ${{ matrix.asset_name }} + shell: bash env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release upload "$GITHUB_REF_NAME" "${{ matrix.asset_name }}" --repo "$GITHUB_REPOSITORY" --clobber diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index fa77a09..d749879 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -71,3 +71,15 @@ Some tests and helpers are built only on Unix or Linux, so also run `cargo clipp ## Where files live at run time BabbleBoop keeps `config.toml`, `total_cost.txt`, and the `recordings` folder in one data folder chosen at startup; see [Where BabbleBoop keeps its files](README.md#where-babbleboop-keeps-its-files) in the README for the lookup order. + +## Releasing + +Push a tag that starts with `v` on a commit of `main`. The Release workflow then checks that the tag is on `main`, runs the tests, creates the GitHub release with generated notes, and attaches the Windows, Linux and macOS builds. + +- A tag with a hyphen, such as `v0.6.1-rc.1`, becomes a pre-release, so it does not replace the latest release. +- For a tag without a hyphen, such as `v0.6.1`, the version in `Cargo.toml` must match, or the workflow stops before it creates the release. + +``` +git tag v0.6.1-rc.2 origin/main +git push origin v0.6.1-rc.2 +```