name: Publish to crates.io
on:
push:
tags:
- "v*.*.*"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Verify tag matches Cargo.toml version
env:
TAG_NAME: ${{ github.ref_name }}
run: |
tag="${TAG_NAME#v}"
crate="$(cargo metadata --no-deps --format-version 1 \
| grep -m1 '"version":' | sed -E 's/.*"version": *"([^"]+)".*/\1/')"
if [ "$tag" != "$crate" ]; then
echo "Tag v$tag does not match Cargo.toml version $crate" >&2
exit 1
fi
- name: Publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
# Capture output so we can treat an already-published version as
# success (re-runs of the same tag shouldn't fail the workflow).
if output="$(cargo publish 2>&1)"; then
echo "$output"
else
echo "$output"
if echo "$output" | grep -q "already exists on crates.io"; then
echo "Version already published; treating as success."
else
exit 1
fi
fi