display-types 0.4.0

Shared display capability types for display connection negotiation.
Documentation
name: Release Prep

on:
  workflow_dispatch:
    inputs:
      bump:
        description: 'Version bump type (auto = let cargo semver-checks decide)'
        required: true
        default: auto
        type: choice
        options:
          - auto
          - patch
          - minor
          - major

env:
  CARGO_TERM_COLOR: always
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
  prepare:
    name: Prepare release
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          ref: develop
          fetch-depth: 0

      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}-cargo-release-

      - name: Cache tools
        uses: actions/cache@v4
        with:
          path: ~/.cargo/bin
          key: ${{ runner.os }}-cargo-tools-semver-checks-v1

      - name: Install cargo-semver-checks
        run: |
          if ! command -v cargo-semver-checks &>/dev/null; then
            cargo install cargo-semver-checks --locked
          fi

      - name: Determine bump type and new version
        id: version
        run: |
          CURRENT=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
          MAJOR=$(echo "$CURRENT" | cut -d. -f1)
          MINOR=$(echo "$CURRENT" | cut -d. -f2)
          PATCH=$(echo "$CURRENT" | cut -d. -f3)

          BUMP="${{ inputs.bump }}"

          if [ "$BUMP" = "auto" ]; then
            echo "Running cargo semver-checks to determine required bump..."
            if cargo semver-checks --release-type patch; then
              BUMP=patch
            elif [ "$MAJOR" = "0" ]; then
              BUMP=minor
            elif cargo semver-checks --release-type minor; then
              BUMP=minor
            else
              BUMP=major
            fi
            echo "Auto-detected minimum required bump: $BUMP"
          else
            if [ "$MAJOR" = "0" ] && [ "$BUMP" = "major" ]; then
              echo "::error::Cannot bump a 0.x crate to 1.0.0 via this workflow — stabilising to 1.0.0 is a deliberate decision. Update Cargo.toml manually."
              exit 1
            fi
            echo "Validating requested bump type: $BUMP"
            if ! cargo semver-checks --release-type "$BUMP"; then
              echo "::error::semver-checks reports '$BUMP' is insufficient for the API changes present. Choose a higher bump type."
              exit 1
            fi
          fi

          case "$BUMP" in
            patch) NEW="${MAJOR}.${MINOR}.$((PATCH + 1))" ;;
            minor) NEW="${MAJOR}.$((MINOR + 1)).0" ;;
            major) NEW="$((MAJOR + 1)).0.0" ;;
          esac

          echo "current=$CURRENT" >> "$GITHUB_OUTPUT"
          echo "new=$NEW" >> "$GITHUB_OUTPUT"
          echo "bump=$BUMP" >> "$GITHUB_OUTPUT"
          echo "Current: $CURRENT → New: $NEW (bump: $BUMP)"

      - name: Bump Cargo.toml version
        run: |
          NEW="${{ steps.version.outputs.new }}"
          sed -i "s/^version = \"[0-9]*\.[0-9]*\.[0-9]*\"/version = \"${NEW}\"/" Cargo.toml

      - name: Update CHANGELOG.md
        run: |
          NEW="${{ steps.version.outputs.new }}"
          TODAY=$(date -u +%Y-%m-%d)
          if ! grep -q '^## \[Unreleased\]' CHANGELOG.md; then
            echo "::error::CHANGELOG.md has no '## [Unreleased]' section — add one before releasing."
            exit 1
          fi
          awk -v new_hdr="## [${NEW}] - ${TODAY}" '
            /^## \[Unreleased\]$/ { print; print ""; print new_hdr; next }
            { print }
          ' CHANGELOG.md > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md

      - name: Refresh Cargo.lock
        run: cargo check

      - name: Configure git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: Commit and push release branch
        run: |
          NEW="${{ steps.version.outputs.new }}"
          git checkout -b "release/v${NEW}"
          git add Cargo.toml Cargo.lock CHANGELOG.md
          git commit -m "Release v${NEW}"
          git push origin "release/v${NEW}"

      - name: Open pull request
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          NEW="${{ steps.version.outputs.new }}"
          CURRENT="${{ steps.version.outputs.current }}"
          gh pr create \
            --base develop \
            --head "release/v${NEW}" \
            --title "Release v${NEW}" \
            --body "$(cat <<EOF
          Automated release prep for **v${NEW}**.

          | File | Change |
          |---|---|
          | \`Cargo.toml\` | \`${CURRENT}\` → \`${NEW}\` |
          | \`CHANGELOG.md\` | \`[Unreleased]\` stamped with today's date |
          | \`Cargo.lock\` | regenerated |

          Once CI passes and this PR merges, run the [Release Tag](${{ github.server_url }}/${{ github.repository }}/actions/workflows/release-tag.yml) workflow to push the tag and kick off publish.
          EOF
          )"