# Keep develop in sync with main.
#
# On every push to main (or manual dispatch), merge main into develop:
# - Clean merge → pushed straight to develop, no ceremony.
# - Conflicts → a standing PR (base develop, head main) is opened instead, so
#   the conflict is resolved in the PR UI; if one is already open we reuse it
#   (its head is the moving main ref, so it tracks new commits by itself).
#
# Token notes (same trade-off documented in resolve-pr-conflicts.yml):
# - GITHUB_TOKEN pushes are rejected whenever the merge brings ANY change
#   under .github/workflows/. When that happens we fall back to the PR path
#   rather than failing the run. An optional SYNC_BRANCHES_PAT (repo +
#   workflow scope) makes those pushes work too — CONFLICT_RESOLVER_PAT is
#   honoured as a fallback since it already carries the right scopes.
# - Pushes made with GITHUB_TOKEN do not retrigger workflows; with a PAT the
#   merge commit runs CI on develop as usual.

name: Sync main into develop

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write

concurrency:
  group: sync-main-into-develop
  cancel-in-progress: false

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - name: Check develop exists
        id: develop
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          if gh api "repos/${{ github.repository }}/branches/develop" --silent 2>/dev/null; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
            echo "::notice::No develop branch — nothing to sync."
          fi

      - name: Checkout develop
        if: steps.develop.outputs.exists == 'true'
        uses: actions/checkout@v4
        with:
          ref: develop
          fetch-depth: 0
          token: ${{ secrets.SYNC_BRANCHES_PAT || secrets.CONFLICT_RESOLVER_PAT || github.token }}

      - name: Merge main into develop
        if: steps.develop.outputs.exists == 'true'
        id: merge
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

          if git merge --no-edit origin/main; then
            echo "result=clean" >> "$GITHUB_OUTPUT"
          else
            git merge --abort
            echo "result=conflict" >> "$GITHUB_OUTPUT"
            echo "::notice::main → develop has conflicts; opening a PR instead."
          fi

      - name: Push develop
        if: steps.merge.outputs.result == 'clean'
        id: push
        run: |
          if git push origin develop; then
            echo "result=pushed" >> "$GITHUB_OUTPUT"
            echo "Merged main into develop cleanly." >> "$GITHUB_STEP_SUMMARY"
          else
            # Most likely: GITHUB_TOKEN refused because the merge touches
            # .github/workflows/**. Hand the merge to a PR instead of failing.
            echo "result=blocked" >> "$GITHUB_OUTPUT"
            echo "::warning::Push to develop was refused (workflow-file changes need a PAT); falling back to a PR."
          fi

      - name: Open (or reuse) the sync PR
        if: steps.merge.outputs.result == 'conflict' || steps.push.outputs.result == 'blocked'
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          existing=$(gh pr list --repo "${{ github.repository }}" --base develop --head main --state open --json number --jq '.[0].number')
          if [ -n "$existing" ]; then
            echo "Sync PR #$existing is already open and tracks main automatically." >> "$GITHUB_STEP_SUMMARY"
            exit 0
          fi
          gh pr create \
            --repo "${{ github.repository }}" \
            --base develop \
            --head main \
            --title "Sync main into develop" \
            --body "Automated sync opened by the *Sync main into develop* workflow because main could not be merged into develop directly (merge conflicts, or the merge touches workflow files that GITHUB_TOKEN cannot push). Resolve any conflicts here and merge — this PR's head is \`main\`, so it picks up new commits on its own."
          echo "Opened a sync PR (main → develop)." >> "$GITHUB_STEP_SUMMARY"
