name: Release
on:
push:
tags:
- "v*"
env:
CARGO_TERM_COLOR: always
jobs:
release:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Nightly Rust + miri
run: |
rustup override set nightly
rustup toolchain install nightly --profile minimal
rustup +nightly component add miri
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- name: Install just
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest,just
- name: Run tests
run: just miri
- name: Extract version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Verify version matches Cargo.toml
run: |
CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
if [ "$CARGO_VERSION" != "${{ steps.version.outputs.VERSION }}" ]; then
echo "Version mismatch: tag v${{ steps.version.outputs.VERSION }} vs Cargo.toml $CARGO_VERSION"
exit 1
fi
- name: Generate release notes
id: release_notes
run: |
# Extract the latest release section from CHANGELOG.md
awk '
/^## \[/ {
if (in_section) {
exit
}
in_section = 1
}
in_section {
print
}
' CHANGELOG.md | tail -n +2 > CHANGES.md
- name: Create release
uses: softprops/action-gh-release@v2
with:
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
fail_on_unmatched_files: true
body_path: CHANGES.md
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
rm CHANGES.md
cargo publish