name: MergeApproved
run-name: "Merge Approved for PR ${{github.event.number}}"
on:
  pull_request_target:
    types: [labeled]

env:
  PR_NUMBER:          ${{ github.event.number }}
  BASE_BRANCH:        ${{github.event.pull_request.base.ref}}
  MODULES_BLACKLIST:  ${{ vars.GATETEST_MODULES_BLACKLIST }} ${{ vars.UNITTEST_MODULES_BLACKLIST }}
  FORCE:              ${{ endsWith(github.event.label.name, '-force') }}

jobs:
  IdentifyBranches:
    if: contains(fromJSON(vars.MERGE_APPROVED_LABELS), github.event.label.name)
    outputs:
      branches:     ${{ steps.getbranches.outputs.branches }}
      all_branches: ${{ steps.checkbranches.outputs.all_branches }}
      branch_count: ${{ steps.getbranches.outputs.branch_count }}
    runs-on: ubuntu-latest
    steps:
      - name: Clean up labels
        env:
          GH_TOKEN:          ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit --repo ${{github.repository}} \
            --remove-label ${{github.event.label.name}} \
            --remove-label ${{vars.PRE_MERGE_CHECKS_PASSED_LABEL}} \
            --remove-label ${{vars.PRE_MERGE_CHECKS_FAILED_LABEL}} \
            --remove-label ${{vars.PRE_MERGE_GATES_PASSED_LABEL}} \
            --remove-label ${{vars.PRE_MERGE_GATES_FAILED_LABEL}} \
            --remove-label ${{vars.PRE_MERGE_TESTING_IN_PROGRESS}} \
            ${{env.PR_NUMBER}} || :

      - name: Get cherry-pick branches
        uses: asterisk/asterisk-ci-actions/GetCherryPickBranchesFromPR@main
        id: getbranches
        with:
          repo:                   ${{github.repository}}
          pr_number:              ${{env.PR_NUMBER}}
          cherry_pick_regex:      ${{vars.CHERRY_PICK_REGEX}}
          github_token:           ${{secrets.GITHUB_TOKEN}}

      - name: Check Branch Count
        id: checkbranches
        env:
          BRANCH_COUNT:  ${{ steps.getbranches.outputs.branch_count }}
          BRANCHES:  ${{ steps.getbranches.outputs.branches }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit --repo ${{github.repository}} \
          --add-label ${{vars.PRE_MERGE_TESTING_IN_PROGRESS}} \
          ${{env.PR_NUMBER}} || :
          all_branches=$(echo "$BRANCHES" | jq -c "[ \"$BASE_BRANCH\" ] + .")
          echo "all_branches=${all_branches}" >>${GITHUB_OUTPUT}

      - name: Pre Check Cherry-Picks
        if: ${{ steps.getbranches.outputs.branch_count > 0 }}
        uses: asterisk/asterisk-ci-actions/CherryPick@main
        with:
          repo:              ${{github.repository}}
          pr_number:         ${{env.PR_NUMBER}}
          branches:          ${{steps.getbranches.outputs.branches}}
          github_token:      ${{secrets.GITHUB_TOKEN}}
          push:              false

  PreMergeUnitTestMatrix:
    needs: [ IdentifyBranches ]
    if: success()
    continue-on-error: false
    strategy:
      fail-fast: false
      matrix:
        branch: ${{ fromJSON(needs.IdentifyBranches.outputs.all_branches) }}
    runs-on: ubuntu-latest
    steps:
      - name: Run Unit Tests for branch ${{matrix.branch}}
        uses: asterisk/asterisk-ci-actions/AsteriskUnitComposite@main
        with:
          asterisk_repo:     ${{github.repository}}
          pr_number:         ${{env.PR_NUMBER}}
          base_branch:       ${{matrix.branch}}
          is_cherry_pick:    true
          modules_blacklist: ${{env.MODULES_BLACKLIST}}
          github_token:      ${{secrets.GITHUB_TOKEN}}
          unittest_command:  ${{vars.UNITTEST_COMMAND}}

  PreMergeUnitTests:
    needs: [ IdentifyBranches, PreMergeUnitTestMatrix ]
    runs-on: ubuntu-latest
    steps:
      - name: Check unit test matrix status
        env:
          RESULT:    ${{needs.PreMergeUnitTestMatrix.result}}
          GH_TOKEN:  ${{ secrets.GITHUB_TOKEN }}
        run: |
          case $RESULT in
            success)
              gh pr edit --repo ${{github.repository}} \
                --remove-label ${{vars.PRE_MERGE_TESTING_IN_PROGRESS}} \
                --add-label ${{vars.PRE_MERGE_CHECKS_PASSED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              echo "::notice::All tests passed"
              exit 0
              ;;
            skipped)
              gh pr edit --repo ${{github.repository}} \
                --remove-label ${{vars.PRE_MERGE_TESTING_IN_PROGRESS}} \
                --add-label ${{vars.PRE_MERGE_CHECKS_FAILED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              echo "::notice::Unit tests were skipped because of an earlier failure"
              exit 1
              ;;
            *)
              gh pr edit --repo ${{github.repository}} \
                --remove-label ${{vars.PRE_MERGE_TESTING_IN_PROGRESS}} \
                --add-label ${{vars.PRE_MERGE_CHECKS_FAILED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              echo "::error::One or more tests failed ($RESULT)"
              exit 1
          esac

  MergeAndCherryPick:
    needs: [ IdentifyBranches, PreMergeUnitTests ]
    if: success()
    concurrency:
      group: MergeAndCherryPick
      cancel-in-progress: false
    runs-on: ubuntu-latest
    steps:
      - name: Start Merge
        env:
          GH_TOKEN:  ${{ secrets.GITHUB_TOKEN }}
        run: |
            gh pr edit --repo ${{github.repository}} \
              --add-label ${{vars.MERGE_IN_PROGRESS_LABEL}} \
              ${{env.PR_NUMBER}} || :

      - name: Get Token needed to push cherry-picks
        id: get_workflow_token
        uses: peter-murray/workflow-application-token-action@v2
        with:
          application_id: ${{secrets.ASTERISK_ORG_ACCESS_APP_ID}}
          application_private_key: ${{secrets.ASTERISK_ORG_ACCESS_APP_PRIV_KEY}}
          organization: asterisk

      - name: Merge and Cherry Pick to ${{needs.IdentifyBranches.outputs.branches}}
        id: mergecp
        uses: asterisk/asterisk-ci-actions/MergeAndCherryPickComposite@main
        with:
          repo:          ${{github.repository}}
          pr_number:     ${{env.PR_NUMBER}}
          branches:      ${{needs.IdentifyBranches.outputs.branches}}
          force:         ${{env.FORCE}}
          github_token:  ${{steps.get_workflow_token.outputs.token}}

      - name: Merge Cleanup
        if: always()
        env:
          RESULT:    ${{ steps.mergecp.outcome }}
          GH_TOKEN:  ${{ secrets.GITHUB_TOKEN }}
          BRANCH_COUNT: ${{ needs.IdentifyBranches.outputs.branch_count }}
          BRANCHES:     ${{ needs.IdentifyBranches.outputs.branches }}

        run: |
          case $RESULT in
            success)
              gh pr edit --repo ${{github.repository}} \
                --remove-label ${{vars.MERGE_IN_PROGRESS_LABEL}} \
                ${{env.PR_NUMBER}} || :
              if [ $BRANCH_COUNT -eq 0 ] ; then
                gh pr comment --repo ${{github.repository}} \
                  -b "Successfully merged to branch $BASE_BRANCH." \
                  ${{env.PR_NUMBER}} || :
              else
                gh pr comment --repo ${{github.repository}} \
                  -b "Successfully merged to branch $BASE_BRANCH and cherry-picked to $BRANCHES" \
                  ${{env.PR_NUMBER}} || :
              fi
              exit 0
              ;;
            failure)
              gh pr edit --repo ${{github.repository}} \
                --remove-label ${{vars.MERGE_IN_PROGRESS_LABEL}} \
                --add-label ${{vars.MERGE_FAILED_LABEL}} \
                ${{env.PR_NUMBER}} || :
              exit 1
              ;;
              *)
          esac
