|  | 
|  | 1 | +name: Auto Merge Dependabot PRs | 
|  | 2 | + | 
|  | 3 | +on: | 
|  | 4 | +  pull_request: | 
|  | 5 | +    types: | 
|  | 6 | +      - opened | 
|  | 7 | +      - synchronize | 
|  | 8 | + | 
|  | 9 | +permissions: | 
|  | 10 | +  pull-requests: write | 
|  | 11 | +  contents: write | 
|  | 12 | + | 
|  | 13 | +jobs: | 
|  | 14 | +  auto-merge: | 
|  | 15 | +    runs-on: ubuntu-latest | 
|  | 16 | +    if: github.actor == 'dependabot[bot]' | 
|  | 17 | +     | 
|  | 18 | +    steps: | 
|  | 19 | +      - name: Checkout the repository | 
|  | 20 | +        uses: actions/checkout@v3 | 
|  | 21 | +         | 
|  | 22 | +      - name: Set up GitHub CLI | 
|  | 23 | +        run: | | 
|  | 24 | +          # Install GitHub CLI (gh) | 
|  | 25 | +          sudo apt-get update | 
|  | 26 | +          sudo apt-get install gh | 
|  | 27 | +
 | 
|  | 28 | +          # Authenticate GitHub CLI using the provided token | 
|  | 29 | +          echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token | 
|  | 30 | +           | 
|  | 31 | +      - name: Wait for CI workflow to pass (Ensure CI workflow succeeded) | 
|  | 32 | +        id: wait_for_ci | 
|  | 33 | +        run: | | 
|  | 34 | +           # Get the PR number from the GitHub event | 
|  | 35 | +            PR_NUMBER=${{ github.event.pull_request.number }} | 
|  | 36 | +            echo "Checking CI status for PR #$PR_NUMBER" | 
|  | 37 | +             | 
|  | 38 | +            # Define the maximum wait time (in seconds) and the polling interval (in seconds) | 
|  | 39 | +            MAX_WAIT_TIME=600  # 10 minutes | 
|  | 40 | +            POLL_INTERVAL=10   # Check every 10 seconds | 
|  | 41 | +             | 
|  | 42 | +            # Initialize a timer | 
|  | 43 | +            elapsed_time=0 | 
|  | 44 | +             | 
|  | 45 | +            # Poll CI status until all checks are completed | 
|  | 46 | +            while true; do | 
|  | 47 | +              # Fetch the status check rollup for the PR | 
|  | 48 | +              CI_STATUS=$(gh pr view $PR_NUMBER --json statusCheckRollup) | 
|  | 49 | +               | 
|  | 50 | +              # Log the fetched response | 
|  | 51 | +              echo "CI Status Response: $CI_STATUS" | 
|  | 52 | +               | 
|  | 53 | +              # Parse the checks and check their status | 
|  | 54 | +              ALL_COMPLETED=true | 
|  | 55 | +              ALL_CHECKS_PASSED=true | 
|  | 56 | +               | 
|  | 57 | +              for check in $(echo "$CI_STATUS" | jq -r '.statusCheckRollup[] | @base64'); do | 
|  | 58 | +                _jq() { | 
|  | 59 | +                  echo "${check}" | base64 --decode | jq -r "${1}" | 
|  | 60 | +                } | 
|  | 61 | +                 | 
|  | 62 | +                status=$(_jq '.status') | 
|  | 63 | +                conclusion=$(_jq '.conclusion') | 
|  | 64 | +                check_name=$(_jq '.name') | 
|  | 65 | +             | 
|  | 66 | +                # Log check details | 
|  | 67 | +                echo "Check: $check_name, Status: $status, Conclusion: $conclusion" | 
|  | 68 | +                 if [[ "$check_name" == "auto-merge" ]]; then | 
|  | 69 | +                    echo "Skipping 'auto-merge' workflow check to prevent self-referencing." | 
|  | 70 | +                    continue | 
|  | 71 | +                  fi | 
|  | 72 | +                   | 
|  | 73 | +                # If any check is still in progress, set ALL_COMPLETED to false | 
|  | 74 | +                if [[ "$status" == "IN_PROGRESS" ]]; then | 
|  | 75 | +                  ALL_COMPLETED=false | 
|  | 76 | +                fi | 
|  | 77 | +             | 
|  | 78 | +                # If any completed check has failed, set ALL_CHECKS_PASSED to false | 
|  | 79 | +                if [[ "$status" == "COMPLETED" && "$conclusion" != "SUCCESS" ]]; then | 
|  | 80 | +                  ALL_CHECKS_PASSED=false | 
|  | 81 | +                fi | 
|  | 82 | +              done | 
|  | 83 | +             | 
|  | 84 | +              # Break the loop if all checks are completed | 
|  | 85 | +              if [[ "$ALL_COMPLETED" == true ]]; then | 
|  | 86 | +                break | 
|  | 87 | +              fi | 
|  | 88 | +             | 
|  | 89 | +              # Wait for the next polling interval | 
|  | 90 | +              echo "Waiting for checks to complete... ($elapsed_time/$MAX_WAIT_TIME seconds elapsed)" | 
|  | 91 | +              sleep $POLL_INTERVAL | 
|  | 92 | +              elapsed_time=$((elapsed_time + POLL_INTERVAL)) | 
|  | 93 | +             | 
|  | 94 | +              # Exit if the maximum wait time is exceeded | 
|  | 95 | +              if [[ "$elapsed_time" -ge "$MAX_WAIT_TIME" ]]; then | 
|  | 96 | +                echo "Timed out waiting for CI checks to complete." | 
|  | 97 | +                exit 1 | 
|  | 98 | +              fi | 
|  | 99 | +            done | 
|  | 100 | +             | 
|  | 101 | +            # Final check: Ensure all CI checks passed | 
|  | 102 | +            if [[ "$ALL_CHECKS_PASSED" == false ]]; then | 
|  | 103 | +              echo "One or more CI checks failed. Aborting merge." | 
|  | 104 | +              exit 1 | 
|  | 105 | +            fi | 
|  | 106 | +             | 
|  | 107 | +            echo "All CI checks passed successfully." | 
|  | 108 | +
 | 
|  | 109 | +           | 
|  | 110 | +      - name: Check Target Branch and PR Title | 
|  | 111 | +        id: check_branch | 
|  | 112 | +        run: | | 
|  | 113 | +          PR_TITLE='${{ github.event.pull_request.title }}' | 
|  | 114 | +          echo "Original PR Title: $PR_TITLE" | 
|  | 115 | +           | 
|  | 116 | +          # Escape problematic quotes | 
|  | 117 | +          ESCAPED_TITLE=$(echo "$PR_TITLE" | sed 's/"/\\"/g') | 
|  | 118 | +          echo "Escaped PR Title: $ESCAPED_TITLE" | 
|  | 119 | +
 | 
|  | 120 | +          if [[ "$ESCAPED_TITLE" =~ ([0-9]+\.[0-9]+\.[0-9]+).*to.*([0-9]+\.[0-9]+\.[0-9]+) ]]; then | 
|  | 121 | +            # Extract version numbers | 
|  | 122 | +            OLD_VERSION="${BASH_REMATCH[1]}" | 
|  | 123 | +            NEW_VERSION="${BASH_REMATCH[2]}" | 
|  | 124 | +            echo "Version change detected: $OLD_VERSION to $NEW_VERSION" | 
|  | 125 | +             | 
|  | 126 | +            # Split version into major, minor, patch components | 
|  | 127 | +            OLD_MAJOR=$(echo "$OLD_VERSION" | cut -d '.' -f1) | 
|  | 128 | +            OLD_MINOR=$(echo "$OLD_VERSION" | cut -d '.' -f2) | 
|  | 129 | +            OLD_PATCH=$(echo "$OLD_VERSION" | cut -d '.' -f3) | 
|  | 130 | +             | 
|  | 131 | +            NEW_MAJOR=$(echo "$NEW_VERSION" | cut -d '.' -f1) | 
|  | 132 | +            NEW_MINOR=$(echo "$NEW_VERSION" | cut -d '.' -f2) | 
|  | 133 | +            NEW_PATCH=$(echo "$NEW_VERSION" | cut -d '.' -f3) | 
|  | 134 | +             | 
|  | 135 | +            # Check if it's a minor or patch update | 
|  | 136 | +            if [[ "$OLD_MAJOR" == "$NEW_MAJOR" ]] && [[ "$OLD_MINOR" == "$NEW_MINOR" ]] && [[ "$NEW_PATCH" -gt "$OLD_PATCH" ]]; then | 
|  | 137 | +              echo "Patch update detected" | 
|  | 138 | +              echo "should_merge=true" >> $GITHUB_ENV | 
|  | 139 | +            elif [[ "$OLD_MAJOR" == "$NEW_MAJOR" ]] && [[ "$NEW_MINOR" -gt "$OLD_MINOR" ]]; then | 
|  | 140 | +              echo "Minor update detected" | 
|  | 141 | +              echo "should_merge=true" >> $GITHUB_ENV | 
|  | 142 | +            else | 
|  | 143 | +              echo "No minor/patch update detected" | 
|  | 144 | +              echo "should_merge=false" >> $GITHUB_ENV | 
|  | 145 | +            fi | 
|  | 146 | +          else | 
|  | 147 | +            echo "No version change detected" | 
|  | 148 | +            echo "should_merge=false" >> $GITHUB_ENV | 
|  | 149 | +          fi | 
|  | 150 | +
 | 
|  | 151 | +      - name: Debug Context | 
|  | 152 | +        uses: actions/github-script@v6 | 
|  | 153 | +        with: | 
|  | 154 | +          script: | | 
|  | 155 | +            console.log("Target branch:", context.payload.pull_request.base.ref); | 
|  | 156 | +
 | 
|  | 157 | +      - name: Check if Should Merge | 
|  | 158 | +        run: | | 
|  | 159 | +          echo "DEBUG: should_merge=${{ env.should_merge }}" | 
|  | 160 | +          if [[ "${{ env.should_merge }}" == "true" ]] && [[ "${{ github.event.pull_request.base.ref }}" == "Automatic_version_update_dependabot" ]]; then | 
|  | 161 | +            echo "DEBUG: should merge PR" | 
|  | 162 | +            echo "should_merge=true" >> $GITHUB_ENV | 
|  | 163 | +          else | 
|  | 164 | +            echo "DEBUG: skip merge" | 
|  | 165 | +            echo "should_merge=false" >> $GITHUB_ENV | 
|  | 166 | +          fi | 
|  | 167 | +
 | 
|  | 168 | +      - name: Merge Pull Request | 
|  | 169 | +        if: ${{ env.should_merge == 'true' }} | 
|  | 170 | +        uses: actions/github-script@v6 | 
|  | 171 | +        with: | 
|  | 172 | +          script: | | 
|  | 173 | +            github.rest.pulls.merge({ | 
|  | 174 | +              owner: context.repo.owner, | 
|  | 175 | +              repo: context.repo.repo, | 
|  | 176 | +              pull_number: context.payload.pull_request.number, | 
|  | 177 | +              merge_method: "squash" | 
|  | 178 | +            }); | 
0 commit comments