name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
publish:
name: Publish to crates.io
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Verify tag matches Cargo.toml version
shell: bash
run: |
CARGO_VER=$(awk -F'"' '/^version[[:space:]]*=/ {print $2; exit}' Cargo.toml)
if [ "v$CARGO_VER" != "$GITHUB_REF_NAME" ]; then
echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml version v$CARGO_VER"
exit 1
fi
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Publish to crates.io (idempotent)
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
shell: bash
run: |
set -euo pipefail
CRATE=$(awk -F'"' '/^name[[:space:]]*=/ {print $2; exit}' Cargo.toml)
VERSION=$(awk -F'"' '/^version[[:space:]]*=/ {print $2; exit}' Cargo.toml)
URL="https://crates.io/api/v1/crates/${CRATE}/${VERSION}"
if curl -fsS -A "${CRATE}-release-ci" -o /dev/null "$URL"; then
echo "::notice::${CRATE}@${VERSION} already on crates.io, skipping"
exit 0
fi
cargo publish