name: Release
on:
push:
branches: [main]
paths: ["Cargo.toml"]
permissions: {}
env:
CARGO_TERM_COLOR: always
jobs:
guard:
name: detect version bump
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
release: ${{ steps.check.outputs.release }}
version: ${{ steps.check.outputs.version }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with:
fetch-depth: 0 - name: Release only when Cargo.toml's version has no tag yet
id: check
run: |
# Read the [package] version straight from the manifest (no cargo
# toolchain needed just to publish a string).
version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"(.*)".*/\1/')
echo "version=${version}" >> "$GITHUB_OUTPUT"
if git rev-parse -q --verify "refs/tags/v${version}" >/dev/null; then
echo "v${version} already tagged — Cargo.toml changed but version did not; nothing to release."
echo "release=false" >> "$GITHUB_OUTPUT"
else
echo "New version v${version} — releasing."
echo "release=true" >> "$GITHUB_OUTPUT"
fi
test:
name: build + test
needs: guard
if: needs.guard.outputs.release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 - name: cargo build
run: cargo build --release --verbose
- name: cargo test
run: cargo test --verbose
publish:
name: publish to crates.io
needs: [guard, test]
if: needs.guard.outputs.release == 'true'
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write contents: write steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Authenticate with crates.io (OIDC)
id: auth
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 - name: cargo publish
run: cargo publish --locked
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
- name: Tag and create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ needs.guard.outputs.version }}
run: |
gh release create "v${VERSION}" --title "v${VERSION}" --generate-notes