kinjo 0.3.7

Kinjo: mDNS TUI and commands launch for local network services
Documentation
name: Prepare Release

# Stage one of the release process. This opens a normal version PR and stops.
# It never creates/moves a tag, merges the PR, or publishes anything.

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Stable version without v (for example 0.3.0)"
        required: true
        type: string

permissions:
  contents: read

concurrency:
  group: prepare-release
  cancel-in-progress: false

env:
  CARGO_TERM_COLOR: always

jobs:
  prepare:
    runs-on: ubuntu-24.04
    timeout-minutes: 15
    environment:
      name: release-preparation
      deployment: false
    # Give gh an explicit repo rather than letting it infer one from the
    # checkout's origin remote, so the release commands do not depend on the
    # local git layout.
    env:
      GH_REPO: ${{ github.repository }}

    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Validate release request
        env:
          VERSION: ${{ inputs.version }}
          GH_TOKEN: ${{ github.token }}
        run: |
          scripts/release/check-version.sh main
          scripts/release/check-version.sh stable "$VERSION"
          current="$(source scripts/release/lib.sh; release_manifest_version)"
          scripts/release/check-version.sh newer "$VERSION" "$current"
          if gh release view "v${VERSION}" >/dev/null 2>&1 ||
             git ls-remote --exit-code --tags origin "refs/tags/v${VERSION}" >/dev/null 2>&1; then
            echo "::error::v${VERSION} already exists as a tag or release"
            exit 1
          fi

      - name: Install cargo-edit
        uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3
        with:
          tool: cargo-edit@0.13.13

      - name: Build the version commit
        env:
          VERSION: ${{ inputs.version }}
        run: |
          branch="release/v${VERSION}"
          git checkout -B "$branch" "$GITHUB_SHA"
          cargo set-version "$VERSION"
          scripts/release/check-version.sh manifest "$VERSION"
          unexpected="$(git diff --name-only | grep -Ev '^(Cargo\.toml|Cargo\.lock)$' || true)"
          if [ -n "$unexpected" ]; then
            echo "::error::version preparation changed unexpected files"
            printf '%s\n' "$unexpected"
            exit 1
          fi
          git diff --check
          git config user.name "github-actions-release[bot]"
          git config user.email "github-actions-release[bot]@users.noreply.github.com"
          git add Cargo.toml Cargo.lock
          git commit -m "Bump version to ${VERSION}"

      - name: Mint release App token
        id: app-token
        uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
        with:
          app-id: ${{ vars.RELEASE_APP_ID }}
          private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
          owner: ${{ github.repository_owner }}
          repositories: ${{ github.event.repository.name }}

      - name: Push branch and open the PR
        env:
          GH_TOKEN: ${{ steps.app-token.outputs.token }}
          VERSION: ${{ inputs.version }}
        run: |
          branch="release/v${VERSION}"
          if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then
            git fetch origin "$branch:refs/remotes/origin/$branch"
            if ! git diff --quiet "origin/$branch" HEAD; then
              echo "::error::$branch already exists with different content"
              exit 1
            fi
          else
            gh auth setup-git
            git push origin "HEAD:$branch"
          fi

          state="$(gh pr view "$branch" --json state --jq .state 2>/dev/null || echo absent)"
          case "$state" in
            OPEN)
              gh pr view "$branch" --json url --jq .url
              ;;
            absent)
              gh pr create \
                --base main \
                --head "$branch" \
                --title "Release v${VERSION}" \
                --body "Automated version bump for v${VERSION}. Merge only after the normal required checks pass."
              ;;
            *)
              echo "::error::existing PR for $branch is $state, not open"
              exit 1
              ;;
          esac