name: Promote main to next

on:
  workflow_dispatch:
    inputs:
      source_branch:
        description: "Source branch to promote into next (default main). Required ci-ok checks run only when this is main."
        required: false
        default: main
        type: string
      source_only:
        description: "Create/refresh tagged release only (skip platform builds and verify-nix)"
        required: false
        default: false
        type: boolean

jobs:
  validate-main:
    if: inputs.source_branch == 'main'
    uses: ./.github/workflows/validate-main-green-ci.yml
    with:
      branch: ${{ inputs.source_branch }}
      required_contexts: ci-ok|ci-main / ci-ok

  promote:
    needs: validate-main
    if: ${{ !cancelled() && (needs.validate-main.result == 'success' || needs.validate-main.result == 'skipped') }}
    runs-on: ubuntu-latest
    permissions:
      contents: write
      actions: write
    env:
      SOURCE_BRANCH: ${{ inputs.source_branch }}
    steps:
      - name: note when CI gate was skipped
        if: inputs.source_branch != 'main'
        run: |
          echo "Skipping required-check validation: source_branch is '${{ inputs.source_branch }}', not main."
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0
          ref: next
      - name: setup node
        uses: actions/setup-node@v5
        with:
          node-version: lts/*
      - name: fast-forward next to source branch tip
        run: |
          set -euo pipefail
          git fetch origin "$SOURCE_BRANCH" next
          # Reset channel branch to source snapshot, then create a fresh RC bump commit.
          git reset --hard "origin/$SOURCE_BRANCH"
      - name: bump package version to next RC
        run: |
          set -euo pipefail
          git fetch --tags origin
          CURRENT_VERSION="$(node -p 'require("./package.json").version')"
          BASE_VERSION="$(node -p 'const v=require("./package.json").version; const m=v.match(/^(\d+\.\d+\.\d+)/); if(!m){throw new Error("Invalid version: "+v)}; m[1]')"
          MAX_RC="$(git tag -l "app-v${BASE_VERSION}-rc.*" | sed -E 's/.*-rc\.([0-9]+)$/\1/' | sort -n | tail -n1)"
          if [[ -z "$MAX_RC" ]]; then
            NEXT_RC=1
          else
            NEXT_RC=$((MAX_RC + 1))
          fi
          TARGET_VERSION="${BASE_VERSION}-rc.${NEXT_RC}"
          if [[ "$CURRENT_VERSION" == "$TARGET_VERSION" ]]; then
            echo "package.json already uses $TARGET_VERSION"
            exit 0
          fi
          npm version --no-git-tag-version "$TARGET_VERSION"
      - name: sync Tauri version from package.json
        run: node scripts/sync-tauri-version-from-package.js
      - name: commit RC version bump
        run: |
          set -euo pipefail
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add package.json package-lock.json src-tauri/Cargo.toml src-tauri/Cargo.lock src-tauri/tauri.conf.json
          if git diff --cached --quiet; then
            echo "No version bump changes to commit."
            exit 0
          fi
          NEW_VERSION="$(node -p 'require("./package.json").version')"
          MSG="chore(release): bump next channel to ${NEW_VERSION}"
          if [[ "${{ inputs.source_only }}" == "true" ]]; then
            MSG="${MSG} [source-only]"
          fi
          git commit -m "$MSG"
      - name: push next
        run: git push --force-with-lease origin HEAD:next
      - name: dispatch Next Channel workflow
        uses: actions/github-script@v9
        env:
          SOURCE_ONLY: ${{ inputs.source_only && 'true' || 'false' }}
        with:
          script: |
            const sourceOnly = process.env.SOURCE_ONLY === "true";
            await github.rest.actions.createWorkflowDispatch({
              owner: context.repo.owner,
              repo: context.repo.repo,
              workflow_id: "next.yml",
              ref: "main",
              inputs: {
                source_only: sourceOnly ? "true" : "false",
              },
            });
            core.info(`Dispatched next.yml with source_only=${sourceOnly}`);
