name: Release
on:
push:
tags:
- "v*"
jobs:
verify:
name: Verify release inputs and crate
runs-on: ubuntu-latest
steps:
- name: Check out source code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Validate tag version matches Cargo.toml
shell: bash
run: |
set -euo pipefail
TAG_VERSION="${GITHUB_REF_NAME#v}"
CARGO_VERSION=$(grep -m 1 '^version = ' Cargo.toml | cut -d '"' -f 2)
if [[ -z "${TAG_VERSION}" || "${TAG_VERSION}" == "${GITHUB_REF_NAME}" ]]; then
echo "Expected a tag prefixed with 'v', got: ${GITHUB_REF_NAME}"
exit 1
fi
if [[ "${TAG_VERSION}" != "${CARGO_VERSION}" ]]; then
echo "Version mismatch between tag (${TAG_VERSION}) and Cargo.toml (${CARGO_VERSION})"
exit 1
fi
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Run tests
run: cargo test --workspace --all-targets
- name: Verify publishability (dry run)
run: cargo publish --locked --dry-run
publish:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: verify
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
steps:
- name: Check out source code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Publish crate
run: cargo publish --locked
github-release:
name: Create GitHub release
runs-on: ubuntu-latest
needs: publish
permissions:
contents: write
steps:
- name: Create release from tag
uses: softprops/action-gh-release@v3
with:
generate_release_notes: true