|
1 | 1 | #!/usr/bin/env bash |
2 | 2 | # |
3 | | -# Merges one Dependabot pull request, if it is an example-only update that a code owner |
4 | | -# has approved and that Verify Examples has verified at the pull request's current head. |
| 3 | +# Merges one Dependabot pull request, if it is an example-only update that Verify Examples |
| 4 | +# has verified at the pull request's current head. |
5 | 5 | # |
6 | | -# Not auto-merge-on-green: main is governed by a ruleset requiring one code-owner approval |
7 | | -# with zero bypass actors, so nothing can merge without a human. What this removes is the |
8 | | -# second trip — approve once and the merge happens within the hour, but only if the |
9 | | -# verification covers the exact commit being merged, so a stale approval cannot land an |
10 | | -# unverified head. |
| 6 | +# Whether that merge is unattended depends on main's ruleset, not on this script. The |
| 7 | +# ruleset currently requires one code-owner approval and lists no bypass actors, so the |
| 8 | +# merge is refused until a human approves and the refusal is reported as exactly that. |
| 9 | +# Making this workflow's identity a bypass actor turns the same code into unattended |
| 10 | +# auto-merge, with the guards below as the only thing standing between a bump and main — |
| 11 | +# which is why they are what they are: example-only, verified at this exact head, every |
| 12 | +# check green. |
11 | 13 | # |
12 | 14 | # Usage: REPO=<owner/repo> dependabot-automerge.sh <pr-number> |
13 | 15 | # |
@@ -164,28 +166,13 @@ if [[ -n "$unverified" ]]; then |
164 | 166 | skip "in the matrix but not verified by run $run_id: $(join_list "$unverified")" |
165 | 167 | fi |
166 | 168 |
|
167 | | -# The approval is the last gate, and it is checked here rather than earlier on purpose: |
168 | | -# reaching this line means the pull request is example-only, verified at its current head, |
169 | | -# and green. Reporting it now makes the job summary a worklist of "verified, waiting only |
170 | | -# on you" rather than a list of things that may also be unverified. |
171 | | -# |
172 | | -# main is governed by a ruleset (not classic branch protection, which is why |
173 | | -# `branches/main/protection` returns 404): one approving review, `require_code_owner_review`, |
174 | | -# and zero bypass actors, with .github/CODEOWNERS assigning `*` to @aws/aws-lambda-tooling. |
175 | | -# No token can merge past that and no bot approval can satisfy it, so this workflow merges |
176 | | -# after a human approves — it does not approve on anyone's behalf. |
177 | | -review=$(jq -r '.reviewDecision // ""' <<<"$pr_json") |
178 | | -case "$review" in |
179 | | - APPROVED) ;; |
180 | | - CHANGES_REQUESTED) |
181 | | - skip "verified at ${head_sha:0:8} by run $run_id, but a reviewer requested changes." |
182 | | - ;; |
183 | | - *) |
184 | | - skip "verified at ${head_sha:0:8} by run $run_id — waiting for a code-owner approval (@aws/aws-lambda-tooling)." |
185 | | - ;; |
186 | | -esac |
187 | | - |
188 | | -echo "PR #$PR is example-only, verified at $head_sha by run $run_id, and approved. Merging." |
| 169 | +# Deliberately no approval gate of its own: the merge is attempted and the outcome |
| 170 | +# classified below. That way this one script behaves correctly whichever way main's |
| 171 | +# ruleset is configured — it merges unattended where the workflow is a bypass actor, and |
| 172 | +# reports "waiting for a code-owner approval" where it is not, with no toggle to keep in |
| 173 | +# sync with a repository setting it cannot see. |
| 174 | +review=$(jq -r '.reviewDecision // "NONE"' <<<"$pr_json") |
| 175 | +echo "PR #$PR is example-only and verified at $head_sha by run $run_id (reviewDecision=$review). Merging." |
189 | 176 |
|
190 | 177 | # --match-head-commit closes the remaining window: if the branch moves between the |
191 | 178 | # lookups above and this call, the API rejects the merge rather than applying it to an |
@@ -221,7 +208,21 @@ case "$state" in |
221 | 208 | # reported as "a sibling update landed first", which was simply the wrong diagnosis: |
222 | 209 | # main's ruleset blocks a merge until the required review is satisfied. |
223 | 210 | BLOCKED) |
224 | | - skip "merge rejected, blocked by main's ruleset (review or a required check) — reviewDecision was $review." |
| 211 | + # main's ruleset requires one code-owner approval (.github/CODEOWNERS assigns `*` to |
| 212 | + # @aws/aws-lambda-tooling) and lists no bypass actors, so this is the expected |
| 213 | + # outcome until either a human approves or this workflow's identity is made a bypass |
| 214 | + # actor. Named precisely, because it used to be reported as a sibling conflict. |
| 215 | + case "$review" in |
| 216 | + APPROVED) |
| 217 | + skip "merge rejected, blocked by main's ruleset even though it is approved — a required rule is unsatisfied." |
| 218 | + ;; |
| 219 | + CHANGES_REQUESTED) |
| 220 | + skip "merge rejected, a reviewer requested changes." |
| 221 | + ;; |
| 222 | + *) |
| 223 | + skip "verified at ${head_sha:0:8} by run $run_id — blocked awaiting a code-owner approval (@aws/aws-lambda-tooling), or a ruleset bypass actor for this workflow." |
| 224 | + ;; |
| 225 | + esac |
225 | 226 | ;; |
226 | 227 | DIRTY | BEHIND | DRAFT | UNKNOWN) |
227 | 228 | skip "merge rejected, not mergeable (mergeStateStatus=$state) — most likely a sibling update landed first." |
|
0 commit comments