name: Release
on:
push:
tags:
- "v*.*.*"
- "v*.*.*-dryrun"
jobs:
validate-release:
name: Validate release tag
runs-on: ubuntu-latest
outputs:
crate_version: ${{ steps.validate.outputs.crate_version }}
dry_run: ${{ steps.validate.outputs.dry_run }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- id: validate
shell: bash
run: |
tag="${GITHUB_REF_NAME}"
base_tag="${tag%-dryrun}"
if [[ "$tag" == *-dryrun ]]; then
dry_run=true
else
dry_run=false
fi
crate_version="$(cargo metadata --no-deps --format-version 1 | python3 -c 'import json, sys; print(json.load(sys.stdin)["packages"][0]["version"])')"
expected_tag="v${crate_version}"
if [[ "$base_tag" != "$expected_tag" ]]; then
echo "::error title=Version mismatch::Git tag ${tag} does not match crate version ${crate_version}. Expected ${expected_tag} or ${expected_tag}-dryrun."
exit 1
fi
echo "crate_version=${crate_version}" >> "$GITHUB_OUTPUT"
echo "dry_run=${dry_run}" >> "$GITHUB_OUTPUT"
create-release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: validate-release
if: ${{ needs.validate-release.outputs.dry_run != 'true' }}
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-dryrun:
name: Publish dry run
runs-on: ubuntu-latest
needs: validate-release
if: ${{ needs.validate-release.outputs.dry_run == 'true' }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Cargo publish (dry run)
run: cargo publish --dry-run
publish-crate:
name: Publish to crates.io
runs-on: ubuntu-latest
needs:
- validate-release
- create-release
if: ${{ needs.validate-release.outputs.dry_run != 'true' }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Cargo publish
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}