name: Automatic semantic version

on:
  push:
    branches: ["master"]
  workflow_dispatch:
    inputs:
      bump:
        description: Override Conventional Commit classification
        required: true
        default: auto
        type: choice
        options:
          - auto
          - patch
          - minor
          - major

permissions:
  contents: write
  actions: write

concurrency:
  group: pg_local_cache-auto-version
  cancel-in-progress: false

jobs:
  bump:
    if: >-
      github.event_name == 'workflow_dispatch' ||
      github.actor != 'github-actions[bot]'
    runs-on: ubuntu-24.04
    timeout-minutes: 15
    env:
      GH_TOKEN: ${{ github.token }}
      VERSION_BUMP: >-
        ${{ github.event_name == 'workflow_dispatch' && inputs.bump || 'auto' }}
    steps:
      - name: Check out the selected master revision
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
        with:
          ref: ${{ github.sha }}
          fetch-depth: 0
          fetch-tags: true

      - name: Calculate and prepare the next semantic version
        id: version
        shell: bash
        run: |
          set -Eeuo pipefail
          python3 scripts/auto_version.py \
            --bump "$VERSION_BUMP" \
            --write \
            --json \
            --github-output "$GITHUB_OUTPUT"

      - name: Commit the prepared release and dispatch CI
        if: steps.version.outputs.changed == 'true'
        shell: bash
        env:
          RELEASE_VERSION: ${{ steps.version.outputs.next_version }}
        run: |
          set -Eeuo pipefail

          git fetch --no-tags origin master
          [[ "$(git rev-parse origin/master)" == "$GITHUB_SHA" ]] || {
            echo "::error::master moved after this workflow started"
            exit 1
          }

          git diff --check
          python3 scripts/validate_pgxn_meta.py

          git config user.name 'pg_local_cache release bot'
          git config user.email 'noreply@github.com'
          git add -A
          git diff --cached --quiet && {
            echo "::error::version planner reported a change but staged nothing"
            exit 1
          }
          git commit \
            -m "chore(release): v${RELEASE_VERSION}" \
            -m "[skip version]"

          make verify-static source-test source-sanitize benchmark-test
          make dist

          git fetch --no-tags origin master
          [[ "$(git rev-parse origin/master)" == "$GITHUB_SHA" ]] || {
            echo "::error::master moved while validating the version commit"
            exit 1
          }
          git push origin HEAD:master

          # Pushes made with GITHUB_TOKEN do not recursively start workflows.
          # Dispatch CI explicitly for the new version-bearing master commit.
          gh workflow run ci.yml --ref master
