name: Release
on:
push:
branches: [main]
workflow_run:
workflows: [CI]
branches: [dev]
types: [completed]
jobs:
release:
name: Publish release
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
checks: read
id-token: write
concurrency:
group: release-publish-main
cancel-in-progress: false
steps:
- name: Checkout the pushed main commit
uses: actions/checkout@v6
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false
- name: Wait for this commit's checks
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SHA: ${{ github.sha }}
run: |
set -euo pipefail
# Outside the checkout: `cargo publish` refuses to package a dirty
# working tree, and this file would be the dirt.
checks="${RUNNER_TEMP}/checks.tsv"
deadline=$(( $(date +%s) + 3300 ))
while :; do
gh api "repos/${GITHUB_REPOSITORY}/commits/${SHA}/check-runs?per_page=100" \
--jq '.check_runs[] | [.name, (.conclusion // "pending")] | @tsv' \
| grep -v '^Publish release ' > "${checks}" || true
if grep -E '\t(failure|cancelled|timed_out|action_required|startup_failure|stale)$' "${checks}"; then
echo "::error::a check on ${SHA} did not pass (see list above); not publishing"
exit 1
fi
pending=$(grep -c $'\tpending$' "${checks}" || true)
started=$(wc -l < "${checks}")
if [ "${pending}" -eq 0 ] && [ "${started}" -gt 0 ]; then
echo "every check on ${SHA} passed"
exit 0
fi
if [ "$(date +%s)" -gt "${deadline}" ]; then
echo "::error::timed out after 55 minutes waiting for checks on ${SHA}"
cat "${checks}"
exit 1
fi
sleep 30
done
- &rust-toolchain
name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: rust-lang/crates-io-auth-action@v1
id: crates-io-auth
- name: Publish unpublished crate version
uses: release-plz/action@v0.5
with:
command: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.crates-io-auth.outputs.token }}
release-pr:
name: Prepare next release
if: >-
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
concurrency:
group: release-plz-dev
cancel-in-progress: false
steps:
- name: Checkout tested dev commit
uses: actions/checkout@v6
with:
ref: dev
fetch-depth: 0
persist-credentials: false
- name: Verify tested commit
env:
EXPECTED_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
actual_sha="$(git rev-parse HEAD)"
if [[ "$actual_sha" != "$EXPECTED_SHA" ]]; then
echo "::error::dev moved after CI: expected $EXPECTED_SHA, checked out $actual_sha"
exit 1
fi
- *rust-toolchain
- name: Create or update release PR
uses: release-plz/action@v0.5
with:
command: release-pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}