name: Claude Rebase

on:
  pull_request_target:
    types: [labeled, closed]

# Restrict default permissions; the job below declares only what it needs.
permissions: {}

concurrency:
  group: claude-rebase-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  rebase:
    environment: ai-bots
    if: github.event.action == 'labeled' && github.event.label.name == 'cc:rebase'
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Create GitHub App token for base repo
        id: base-app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ vars.DYAD_GITHUB_APP_ID }}
          private-key: ${{ secrets.DYAD_GITHUB_APP_PRIVATE_KEY }}
          permission-contents: write
          permission-pull-requests: write

      - name: Check PR author
        id: check-author
        uses: actions/github-script@v7
        with:
          github-token: ${{ steps.base-app-token.outputs.token }}
          script: |
            const pr = context.payload.pull_request;
            const allowedUsers = ['wwwillchen', 'keppo-bot', 'keppo-bot[bot]', 'dyad-assistant', 'azizmejri1', 'princeaden1'];
            if (!allowedUsers.includes(pr.user.login)) {
              console.log(`PR author ${pr.user.login} is not allowed to use this workflow`);
              core.setOutput('should_continue', 'false');
              return;
            }
            core.setOutput('should_continue', 'true');
            core.setOutput('pr_number', pr.number);

      - name: Create GitHub App token for PR head repo
        if: steps.check-author.outputs.should_continue == 'true'
        id: head-app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ vars.DYAD_GITHUB_APP_ID }}
          private-key: ${{ secrets.DYAD_GITHUB_APP_PRIVATE_KEY }}
          owner: ${{ github.event.pull_request.head.repo.owner.login }}
          repositories: ${{ github.event.pull_request.head.repo.name }}
          permission-contents: write

      - name: Checkout repository
        if: steps.check-author.outputs.should_continue == 'true'
        uses: actions/checkout@v4
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}
          fetch-depth: 0

      - name: Configure git remotes for cross-repo PR
        if: steps.check-author.outputs.should_continue == 'true'
        run: |
          # Add upstream remote pointing to the base repo for rebasing
          git remote add upstream https://github.com/${{ github.repository }}.git
          git fetch upstream main

          echo "Git remotes configured:"
          echo "  origin -> ${{ github.event.pull_request.head.repo.full_name }} (head repo / fork)"
          echo "  upstream -> ${{ github.repository }} (base repo)"
          git remote -v
        env:
          GITHUB_TOKEN: ${{ steps.base-app-token.outputs.token }}

      - name: Configure push remote for fork PRs
        if: steps.check-author.outputs.should_continue == 'true'
        run: |
          # claude-code-action overwrites origin's fetch URL to point to dyad-sh/dyad
          # (using GITHUB_REPOSITORY which is always the base repo in pull_request_target events).
          # Setting pushurl separately ensures git push still targets the fork,
          # because git uses pushurl over url when both are configured.
          #
          # We use a GitHub App token instead of GITHUB_TOKEN so that
          # the push creates real PR events (synchronize) that trigger downstream workflows
          # like CI. Pushes made with GITHUB_TOKEN are silently ignored by GitHub to prevent
          # infinite loops.
          git remote set-url --push origin "https://x-access-token:${PR_HEAD_APP_TOKEN}@github.com/${{ github.event.pull_request.head.repo.full_name }}.git"
          echo "Configured pushurl to ${{ github.event.pull_request.head.repo.full_name }}"
        env:
          PR_HEAD_APP_TOKEN: ${{ steps.head-app-token.outputs.token }}

      - name: Remove cc:rebase label and add cc:rebasing
        if: steps.check-author.outputs.should_continue == 'true'
        run: |
          gh pr edit ${{ steps.check-author.outputs.pr_number }} --repo ${{ github.repository }} --remove-label "cc:rebase" --add-label "cc:rebasing"
        env:
          GITHUB_TOKEN: ${{ steps.base-app-token.outputs.token }}

      - name: Run PR Rebase
        if: steps.check-author.outputs.should_continue == 'true'
        uses: anthropics/claude-code-action@v1.0.96
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          github_token: ${{ steps.base-app-token.outputs.token }}
          display_report: true
          prompt: |
            You are orchestrating the /dyad:pr-rebase skill. Your job is to run it end-to-end as a sub-agent with NO shortcuts.

            Rules:
            1. Execute every step of /dyad:pr-rebase sequentially. Do not skip, summarize, or stop early.
            2. The skill includes a "/dyad:pr-push" step. This step MUST be fully executed — not just mentioned or planned, but actually run to completion.
            3. After "/dyad:pr-push" completes, verify its output to confirm success (e.g., a PR URL or push confirmation).
            4. Do not consider the task complete until "/dyad:pr-push" has succeeded and you have confirmed its output.

            Now run the following command:          
            /dyad:pr-rebase ${{ steps.check-author.outputs.pr_number }}

      - name: Update labels on success
        if: steps.check-author.outputs.should_continue == 'true' && success()
        run: |
          gh pr edit ${{ steps.check-author.outputs.pr_number }} --repo ${{ github.repository }} --remove-label "cc:rebasing"
        env:
          GITHUB_TOKEN: ${{ steps.base-app-token.outputs.token }}

      - name: Update labels on failure
        if: steps.check-author.outputs.should_continue == 'true' && failure()
        run: |
          gh pr edit ${{ steps.check-author.outputs.pr_number }} --repo ${{ github.repository }} --remove-label "cc:rebasing" --add-label "cc:rebase-failed"
        env:
          GITHUB_TOKEN: ${{ steps.base-app-token.outputs.token }}
