name: Release extras
on:
push:
tags:
- "**[0-9]+.[0-9]+.[0-9]+*"
workflow_dispatch:
inputs:
tag:
description: "Tag to publish (defaults to the dispatched ref)"
required: false
type: string
permissions:
contents: read
concurrency:
group: release-extras-${{ github.ref }}
cancel-in-progress: false
jobs:
wait-checks:
name: Wait for CI and Release checks on the tag
runs-on: ubuntu-latest
env:
TAG_REF: ${{ inputs.tag || github.ref_name }}
steps:
- name: Block until every workflow run on the tag commit is green
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
repo="https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
# an annotated tag resolves to the tag object — peel to the commit
sha="$(git ls-remote "$repo" "refs/tags/${TAG_REF}^{}" | cut -f1)"
[ -n "$sha" ] || sha="$(git ls-remote "$repo" "${TAG_REF}" | cut -f1)"
echo "waiting on workflow runs for ${TAG_REF} (${sha})"
for i in $(seq 1 120); do
# poll workflow runs on the tag commit, ignoring this workflow —
# our own runs would never be "success" while we wait on them
out="$(gh api "repos/${GITHUB_REPOSITORY}/actions/runs?head_sha=${sha}" \
--jq '.workflow_runs[] | select(.name != "Release extras") |
"\(.name) \(.status)/\(.conclusion // "pending")"' | sort -u)"
echo "attempt ${i}:"
echo "$out"
case "$out" in
*"in_progress"*|*"queued"*|*"pending"*|*"waiting"*|*"requested"*) sleep 30; continue ;;
esac
echo "$out" | grep -q '^Release ' || { sleep 30; continue; }
echo "$out" | grep -q '^CI ' || { sleep 30; continue; }
if printf '%s\n' "$out" | grep -qv 'completed/success'; then
echo "a workflow run did not succeed:" "$out" >&2
exit 1
fi
exit 0
done
echo "workflow runs did not settle within 60 minutes" >&2
exit 1
publish-crates:
name: Publish to crates.io
needs: [wait-checks]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.tag || github.ref_name }}
- uses: dtolnay/rust-toolchain@stable
- name: Publish
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
if: ${{ env.CRATES_TOKEN != '' }}
run: cargo publish --locked --token "$CRATES_TOKEN"