name: Release on: push: branches: - main paths: - Cargo.toml - CHANGELOG.md - bench/Cargo.toml - .github/workflows/release.yml workflow_dispatch: permissions: contents: write id-token: write concurrency: group: release-main cancel-in-progress: false jobs: release: runs-on: ubuntu-latest environment: release steps: - uses: actions/checkout@v7 with: fetch-depth: 0 - uses: dtolnay/rust-toolchain@1.88.0 - uses: Swatinem/rust-cache@v2.9.1 - name: Read version and tag id: meta shell: bash run: | version="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" if [[ -z "$version" ]]; then echo "Unable to parse version from Cargo.toml" exit 1 fi echo "version=$version" >> "$GITHUB_OUTPUT" echo "tag=v$version" >> "$GITHUB_OUTPUT" - name: Check whether tag already exists id: tag shell: bash run: | if git rev-parse -q --verify "refs/tags/${{ steps.meta.outputs.tag }}" >/dev/null; then echo "exists=true" >> "$GITHUB_OUTPUT" elif git ls-remote --exit-code --tags origin "refs/tags/${{ steps.meta.outputs.tag }}" >/dev/null 2>&1; then echo "exists=true" >> "$GITHUB_OUTPUT" else echo "exists=false" >> "$GITHUB_OUTPUT" fi - name: Skip when already released if: steps.tag.outputs.exists == 'true' run: echo "Tag ${{ steps.meta.outputs.tag }} already exists. Nothing to release." - name: Verify package if: steps.tag.outputs.exists == 'false' run: | cargo package --locked cargo test --locked - name: Authenticate with crates.io if: steps.tag.outputs.exists == 'false' id: auth uses: rust-lang/crates-io-auth-action@v1 - name: Publish to crates.io if: steps.tag.outputs.exists == 'false' env: CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} run: cargo publish --locked - name: Create and push tag if: steps.tag.outputs.exists == 'false' shell: bash run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git tag -a "${{ steps.meta.outputs.tag }}" -m "${{ steps.meta.outputs.tag }}" git push origin "${{ steps.meta.outputs.tag }}" - name: Extract changelog entry if: steps.tag.outputs.exists == 'false' shell: bash run: | awk 'index($0, "## [${{ steps.meta.outputs.version }}]") == 1 {found=1; next} found && /^## \[/{exit} found{print}' CHANGELOG.md > release-notes.md if [[ ! -s release-notes.md ]]; then echo "No changelog entry found for ${{ steps.meta.outputs.version }}" exit 1 fi - name: Create GitHub release if: steps.tag.outputs.exists == 'false' env: GH_TOKEN: ${{ github.token }} run: | gh release create "${{ steps.meta.outputs.tag }}" \ --repo "${{ github.repository }}" \ --verify-tag \ --notes-file release-notes.md