# .github/workflows/release-from-main.yml
# 
# This workflow:
# 1. Triggers on push to main with "RELEASE" in commit message
# 2. Creates/merges PR from main -> release branch
# 3. Tags the release with version from commit message (e.g., "RELEASE v2.3.0")
# 4. Creates GitHub release with generated notes
# the changelog gen still needs work tbfh
name: Merge main -> release

on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write

jobs:
  merge_and_release:
    if: >
      github.actor == 'floris-xlx' &&
      contains(github.event.head_commit.message, 'RELEASE')
    runs-on: ubuntu-latest

    steps:
      - name: Checkout (full history + tags)
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure git identity
        run: |
          git config user.name  "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
      - name: Parse release version (optional)
        id: ver
        shell: bash
        run: |
          MSG="${{ github.event.head_commit.message }}"
          RAW="$(echo "$MSG" | grep -Eo 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -n1 || true)"
          if [ -n "$RAW" ] && [[ "$RAW" != v* ]]; then RAW="v$RAW"; fi
          echo "version=$RAW" >> "$GITHUB_OUTPUT"
      - name: Stop if no version specified
        if: steps.ver.outputs.version == ''
        run: |
          echo "Didn't run: commit message contains 'RELEASE' but no version found. Expected e.g. 'RELEASE v2.3.0'."
          exit 0
      - name: Determine previous version tag (fallback v2.2.0)
        id: prev
        shell: bash
        run: |
          git fetch --tags --force
          NEW="${{ steps.ver.outputs.version }}"
          PREV="$(git tag --list 'v*' --sort=-v:refname | grep -vx "$NEW" | head -n1 || true)"
          if [ -z "$PREV" ]; then PREV="v2.2.0"; fi
          echo "prev_tag=$PREV" >> "$GITHUB_OUTPUT"
      - name: Ensure release branch exists
        shell: bash
        run: |
          if ! git ls-remote --exit-code --heads origin release >/dev/null 2>&1; then
            echo "Remote branch 'release' does not exist. Create it first."
            exit 1
          fi
      - name: Create branch for previous version (if missing)
        shell: bash
        run: |
          PREV="${{ steps.prev.outputs.prev_tag }}"
          BR="releases/${PREV}"   # <-- changed prefix
          if git ls-remote --exit-code --heads origin "$BR" >/dev/null 2>&1; then
            exit 0
          fi
          if ! git show-ref --tags --verify --quiet "refs/tags/$PREV"; then
            echo "Previous tag '$PREV' not found. Create tag '$PREV' (or adjust fallback)."
            exit 1
          fi
          git branch "$BR" "$PREV"
          git push origin "$BR"
      - name: Create (or reuse) PR main -> release
        id: pr
        env:
          GH_TOKEN: ${{ github.token }}
        shell: bash
        run: |
          set -euo pipefail
          # Get existing open PR number for main -> release (first column like "#123")
          PR_NUM="$(
            gh pr list --head main --base release --state open \
            | awk 'NR==1{print $1}' \
            | tr -d '#'
          )"
          if [ -z "${PR_NUM:-}" ]; then
            # gh pr create (older gh) outputs the PR URL on success
            PR_URL="$(
              gh pr create \
                --base release \
                --head main \
                --title "Release: ${{ steps.ver.outputs.version }}" \
                --body "Automated PR created from a RELEASE commit on main."
            )"
            # Extract number from URL: .../pull/123
            PR_NUM="$(echo "$PR_URL" | sed -n 's#.*/pull/\([0-9]\+\).*#\1#p')"
          fi
          if [ -z "${PR_NUM:-}" ]; then
            echo "Failed to determine PR number." >&2
            exit 1
          fi
          echo "number=$PR_NUM" >> "$GITHUB_OUTPUT"
      - name: Merge PR (merge commit) main -> release
        env:
          GH_TOKEN: ${{ github.token }}
        shell: bash
        run: |
          gh pr merge "${{ steps.pr.outputs.number }}" --merge --admin --delete-branch=false
      - name: Create branch for new version at release HEAD (if missing)
        shell: bash
        run: |
          NEW="${{ steps.ver.outputs.version }}"
          BR="releases/${NEW}"   # <-- changed prefix
          git fetch origin release --force
          RELEASE_SHA="$(git rev-parse origin/release)"
          if git ls-remote --exit-code --heads origin "$BR" >/dev/null 2>&1; then
            exit 0
          fi
          git branch "$BR" "$RELEASE_SHA"
          git push origin "$BR"
      - name: Tag release at release HEAD (if missing) and push tag
        shell: bash
        run: |
          NEW="${{ steps.ver.outputs.version }}"
          git fetch origin release --force
          RELEASE_SHA="$(git rev-parse origin/release)"
          if git show-ref --tags --verify --quiet "refs/tags/$NEW"; then
            exit 0
          fi
          git tag -a "$NEW" "$RELEASE_SHA" -m "Release $NEW"
          git push origin "$NEW"
      - name: Create GitHub Release (if missing)
        env:
          GH_TOKEN: ${{ github.token }}
        shell: bash
        run: |
          NEW="${{ steps.ver.outputs.version }}"
          if gh release view "$NEW" >/dev/null 2>&1; then
            exit 0
          fi
          gh release create "$NEW" --title "$NEW" --generate-notes
