yarp-cli 0.3.1

Prune Pi command output and archive tool calls locally
Documentation
name: publish

on:
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      tag:
        description: Existing published GitHub Release tag to publish
        required: true
        type: string

permissions:
  contents: read
  id-token: write

jobs:
  crates-io:
    name: crates.io
    runs-on: ubuntu-latest
    steps:
      - name: Resolve release tag
        id: release
        env:
          EVENT_NAME: ${{ github.event_name }}
          RELEASE_TAG: ${{ github.event.release.tag_name }}
          INPUT_TAG: ${{ inputs.tag }}
          GH_TOKEN: ${{ github.token }}
          REPO: ${{ github.repository }}
        run: |
          set -euo pipefail
          tag="${RELEASE_TAG:-${INPUT_TAG:-}}"
          if [ -z "$tag" ]; then
            echo "missing release tag" >&2
            exit 1
          fi
          if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
            release_state="$(gh release view "$tag" --repo "$REPO" --json isDraft,publishedAt \
              --jq 'if .isDraft == false and .publishedAt != null then "published" else "unpublished" end')"
            if [ "$release_state" != "published" ]; then
              echo "release tag '$tag' is not a published GitHub Release" >&2
              exit 1
            fi
          fi
          echo "tag=$tag" >>"$GITHUB_OUTPUT"

      - name: Checkout release tag
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          ref: ${{ steps.release.outputs.tag }}
          fetch-depth: 0

      - name: Install Rust
        uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
        with:
          toolchain: "1.91"

      - name: Validate release
        env:
          RELEASE_TAG: ${{ steps.release.outputs.tag }}
          DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
        run: |
          set -euo pipefail
          metadata="$(cargo metadata --no-deps --format-version 1)"
          version="$(jq -r '.packages[] | select(.name == "yarp-cli") | .version' <<<"$metadata")"
          publishable="$(jq -r '[.packages[] | select(.publish != []) | .name] | sort | join("\n")' <<<"$metadata")"
          if [ "$publishable" != "yarp-cli" ]; then
            echo "expected yarp-cli to be the only publishable crate, got: $publishable" >&2
            exit 1
          fi
          tag_version="${RELEASE_TAG#v}"
          if [ "$tag_version" != "$version" ]; then
            echo "release tag '$RELEASE_TAG' does not match Cargo.toml version '$version'" >&2
            exit 1
          fi
          git fetch --no-tags origin "$DEFAULT_BRANCH"
          tag_commit="$(git rev-list -n 1 "$RELEASE_TAG")"
          if ! git merge-base --is-ancestor "$tag_commit" "origin/$DEFAULT_BRANCH"; then
            echo "release tag '$RELEASE_TAG' is not on '$DEFAULT_BRANCH'" >&2
            exit 1
          fi
          if cargo search yarp-cli --limit 1 | grep -Eq "^yarp-cli = \"$version\""; then
            echo "yarp-cli $version is already published on crates.io" >&2
            exit 1
          fi

      - name: Verify package
        run: cargo package --locked -p yarp-cli

      - name: Authenticate with crates.io
        id: auth
        uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
        run: cargo publish --locked -p yarp-cli