name: Release
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: write
concurrency:
group: release
cancel-in-progress: false
env:
CARGO_TERM_COLOR: always
jobs:
release:
name: Semantic release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: cargo-bins/cargo-binstall@main
- name: Install cocogitto and cargo-edit
run: cargo binstall -y --force cocogitto cargo-edit
- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Bump version, update changelog, and tag
id: bump
run: |
# Fail loudly if the tool is missing, rather than mistaking it for
# "no releasable changes" below and exiting green without releasing.
command -v cog >/dev/null || { echo "::error::cocogitto (cog) is not installed"; exit 1; }
before=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")
# `cog bump --auto` exits non-zero when there are no releasable commits.
if cog bump --auto; then
tag=$(git describe --tags --abbrev=0)
echo "released=true" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "Released $tag (previous: $before)"
else
echo "released=false" >> "$GITHUB_OUTPUT"
echo "No releasable changes since $before — skipping release."
fi
- name: Push commit and tag
if: steps.bump.outputs.released == 'true'
run: git push --follow-tags origin HEAD:main
- name: Extract release notes
if: steps.bump.outputs.released == 'true'
run: awk '/^## /{n++} n==1{print} n==2{exit}' CHANGELOG.md > "$RUNNER_TEMP/RELEASE_NOTES.md"
- name: Create GitHub Release
if: steps.bump.outputs.released == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.bump.outputs.tag }}
body_path: ${{ runner.temp }}/RELEASE_NOTES.md
- name: Check for crates.io token
if: steps.bump.outputs.released == 'true'
id: cratesio
env:
TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
if [ -n "$TOKEN" ]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "CARGO_REGISTRY_TOKEN not set — skipping crates.io publish."
fi
- name: Publish to crates.io
if: steps.bump.outputs.released == 'true' && steps.cratesio.outputs.enabled == 'true'
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish