name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
ci:
name: CI
uses: ./.github/workflows/ci.yml
validate-tag:
name: Validate tag matches crate version
needs: ci
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install protoc
run: sudo apt-get update -y && sudo apt-get install -y protobuf-compiler
- name: Compare tag vs package version
run: |
TAG="${GITHUB_REF#refs/tags/v}"
VERSION=$(cargo metadata --no-deps --format-version=1 \
| jq -r '.packages[] | select(.name == "peat-tak") | .version')
if [ "$TAG" != "$VERSION" ]; then
echo "::error::Tag v$TAG does not match crate version $VERSION"
exit 1
fi
echo "Tag v$TAG matches crate version $VERSION"
publish:
name: Publish to crates.io
needs: validate-tag
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install protoc
run: sudo apt-get update -y && sudo apt-get install -y protobuf-compiler
- name: Publish peat-tak (idempotent)
run: |
set -euo pipefail
VERSION="${GITHUB_REF_NAME#v}"
UA="peat-tak-release (github.com/defenseunicorns/peat-tak)"
INDEX_URL="https://index.crates.io/pe/at/peat-tak"
is_indexed() {
curl -sfL -H "User-Agent: $UA" "$INDEX_URL" 2>/dev/null \
| jq -e --arg v "$VERSION" 'select(.vers == $v)' > /dev/null 2>&1
}
if is_indexed; then
echo "peat-tak $VERSION already on crates.io, skipping publish"
else
cargo publish -p peat-tak --allow-dirty
for i in $(seq 1 60); do
if is_indexed; then
echo "peat-tak $VERSION is indexed after $((i * 5))s"
exit 0
fi
echo "Waiting for peat-tak $VERSION to be indexed... ($((i * 5))s elapsed)"
sleep 5
done
echo "::error::peat-tak $VERSION did not appear on the crates.io sparse index within 5 minutes"
exit 1
fi
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
release:
name: GitHub Release
needs: publish
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Create GitHub Release
run: |
set -euo pipefail
PRERELEASE_FLAG=""
case "$GITHUB_REF_NAME" in
*-rc.*|*-alpha.*|*-beta.*) PRERELEASE_FLAG="--prerelease" ;;
esac
if gh release view "$GITHUB_REF_NAME" > /dev/null 2>&1; then
echo "Release $GITHUB_REF_NAME already exists, updating..."
gh release edit "$GITHUB_REF_NAME" $PRERELEASE_FLAG
else
gh release create "$GITHUB_REF_NAME" --generate-notes $PRERELEASE_FLAG
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}