name: Cherry Pick Single

on:
  workflow_call:
    inputs:
      merge_commit_sha:
        required: true
        type: string
        description: "The merge commit SHA to cherry-pick"
      version_number:
        required: true
        type: string
        description: "The version number (from cherry-pick/ label)"
      pr_number:
        required: true
        type: string
        description: "The original PR number"
      pr_title:
        required: true
        type: string
        description: "The original PR title"
    secrets:
      CHERRYPICK_APP_ID:
        required: true
      CHERRYPICK_APP_PRIVATE_KEY:
        required: true

env:
  # a workaround to disable harden runner
  STEP_SECURITY_HARDEN_RUNNER: ${{ vars.disable_harden_runner }}

jobs:
  cherry-pick:
    name: Cherry Pick to ${{ inputs.version_number }}
    runs-on: ubuntu-24.04
    steps:
      - name: Harden the runner (Audit all outbound calls)
        if: ${{ vars.disable_harden_runner != 'true' }}
        uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
        with:
          egress-policy: audit

      - name: Generate a token
        id: generate-token
        uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
        with:
          app-id: ${{ secrets.CHERRYPICK_APP_ID }}
          private-key: ${{ secrets.CHERRYPICK_APP_PRIVATE_KEY }}

      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
        with:
          fetch-depth: 0
          token: ${{ steps.generate-token.outputs.token }}

      - name: Configure Git
        run: |
          git config --global user.name "github-actions[bot]"
          git config --global user.email "github-actions[bot]@users.noreply.github.com"

      - name: Cherry pick commit
        id: cherry-pick
        run: |
          set -e

          MERGE_COMMIT="${{ inputs.merge_commit_sha }}"
          TARGET_BRANCH="release-${{ inputs.version_number }}"

          echo "🍒 Cherry-picking commit $MERGE_COMMIT to branch $TARGET_BRANCH"

          # Check if target branch exists
          if ! git show-ref --verify --quiet "refs/remotes/origin/$TARGET_BRANCH"; then
            echo "❌ Target branch '$TARGET_BRANCH' does not exist"
            exit 1
          fi

          # Create new branch for cherry-pick
          CHERRY_PICK_BRANCH="cherry-pick-${{ inputs.pr_number }}-to-${TARGET_BRANCH}"

          git checkout -b "$CHERRY_PICK_BRANCH" "origin/$TARGET_BRANCH"

          # Perform cherry-pick
          if git cherry-pick -m 1 "$MERGE_COMMIT"; then
            echo "✅ Cherry-pick successful"

            # Extract Signed-off-by from the cherry-pick commit
            SIGNOFF=$(git log -1 --pretty=format:"%B" | grep -E '^Signed-off-by:' || echo "")

            # Push the new branch. Force push to ensure that in case the original cherry-pick branch is stale, 
            # that the current state of the $TARGET_BRANCH + cherry-pick gets in $CHERRY_PICK_BRANCH.
            git push origin -f "$CHERRY_PICK_BRANCH"

            # Save data for PR creation
            echo "branch_name=$CHERRY_PICK_BRANCH" >> "$GITHUB_OUTPUT"
            {
              echo "signoff<<EOF"
              echo "$SIGNOFF"
              echo "EOF"
            } >> "$GITHUB_OUTPUT"
            echo "target_branch=$TARGET_BRANCH" >> "$GITHUB_OUTPUT"
          else
            echo "❌ Cherry-pick failed due to conflicts"
            git cherry-pick --abort
            exit 1
          fi

      - name: Create Pull Request
        run: |
          # Create cherry-pick PR
          TITLE="${PR_TITLE} (cherry-pick #${{ inputs.pr_number }} for ${{ inputs.version_number }})"
          BODY=$(cat <<EOF
          Cherry-picked ${PR_TITLE} (#${{ inputs.pr_number }})

          ${{ steps.cherry-pick.outputs.signoff }}
          EOF
          )

          gh pr create \
            --title "$TITLE" \
            --body "$BODY" \
            --base "${{ steps.cherry-pick.outputs.target_branch }}" \
            --head "${{ steps.cherry-pick.outputs.branch_name }}"

          # Comment on original PR
          gh pr comment ${{ inputs.pr_number }} \
            --body "🍒 Cherry-pick PR created for ${{ inputs.version_number }}: #$(gh pr list --head ${{ steps.cherry-pick.outputs.branch_name }} --json number --jq '.[0].number')"
        env:
          PR_TITLE: ${{ inputs.pr_title }}
          GH_TOKEN: ${{ steps.generate-token.outputs.token }}

      - name: Comment on failure
        if: failure()
        run: |
          gh pr comment ${{ inputs.pr_number }} \
            --body "❌ Cherry-pick failed for ${{ inputs.version_number }}. Please check the [workflow logs](https://github.com/argoproj/argo-cd/actions/runs/${{ github.run_id }}) for details."
        env:
          GH_TOKEN: ${{ steps.generate-token.outputs.token }}
