release-kit 0.2.10

A canonical release workflow: a technology-agnostic method, per-technology bindings, and the rk CLI that lands and serves them.
Documentation
# The release automation and the crates.io trusted publisher. This filename
# is registered at crates.io; cargo-dist's release.yml builds binaries and
# must never be registered there.
#
# Both halves run on every push to the trunk, and to a release/* line when a
# project keeps older lines. The pull-request half maintains the one release
# pull request against the pushed branch; the release half publishes and tags
# only on the push that lands the bot's own bump, which release_always = false
# recognizes by its release-plz-* head branch. The publish half runs free of
# any concurrency group — cancelling it could skip a release — while the
# pull-request half serializes per ref so racing pushes cannot fight over the
# release pull request.
name: release-plz

permissions: {}

on:
  push:
    branches: [master, 'release/**']

jobs:
  # Merging the release pull request is the release: the bump push lands here,
  # and this half publishes over OIDC and pushes the tag. The app token is what
  # makes the tag trigger release.yml; a tag pushed with GITHUB_TOKEN starts no
  # further workflow. On a release/* line the same job tags the line's patch.
  release-plz-release:
    if: github.repository_owner == 'OWNER'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with:
          fetch-depth: 0
          persist-credentials: false
      - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
        id: app-token
        with:
          app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
          private-key: ${{ secrets.RELEASE_BOT_APP_PRIVATE_KEY }}
      - uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
      - uses: release-plz/action@2eb1d8bcb770b4c48ccfaad919734b38b51958c9 # v0.5
        id: release
        with:
          command: release
        env:
          GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}

  release-plz-pr:
    if: github.repository_owner == 'OWNER'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    concurrency:
      group: release-plz-${{ github.ref }}
      cancel-in-progress: false
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with:
          fetch-depth: 0
          persist-credentials: false
      - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
        id: app-token
        with:
          app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
          private-key: ${{ secrets.RELEASE_BOT_APP_PRIVATE_KEY }}
      - uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
      - uses: release-plz/action@2eb1d8bcb770b4c48ccfaad919734b38b51958c9 # v0.5
        id: release-pr
        with:
          command: release-pr
        env:
          GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
      # Arm the request the moment it exists: the forge merges it once every
      # required check is green, which is the trunk style's release decision,
      # made once at landing rather than per release; the lines style leaves
      # every request for a human and this step steps aside. Two things keep
      # the arm correct. The app token is one: auto-merge enabled under
      # GITHUB_TOKEN would merge a bump whose push starts no workflow,
      # leaving it untagged and unpublished with nothing reporting a failure.
      # Re-arming is the other: arming an armed request is a no-op, so every
      # refresh re-arms and the arm cannot drift out of sync.
      - name: arm the release request
        env:
          RELEASE_STYLE: RK_STYLE
          GH_TOKEN: ${{ steps.app-token.outputs.token }}
          GH_REPO: ${{ github.repository }}
          RELEASE_PR: ${{ steps.release-pr.outputs.pr }}
        run: |
          set -eu
          if [ "$RELEASE_STYLE" != "trunk" ]; then
            echo "the lines style merges each release by hand; not arming."
            exit 0
          fi
          number="$(printf '%s' "${RELEASE_PR:-}" | sed -n 's/.*"number":[[:space:]]*\([0-9]*\).*/\1/p' | head -n 1)"
          if [ -z "$number" ]; then
            echo "no release request to arm."
            exit 0
          fi
          gh pr merge "$number" --auto --squash --delete-branch
          echo "armed pull request #$number."