Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 22 additions & 16 deletions .github/workflows/renovate-auto-approve.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ name: renovate-auto-approve
# It approves a Renovate PR that carries the automerge label, added by Renovate,
# and not the block label (security), and only while the branch still holds
# exactly one commit, authored by Renovate and signed, and pushed by Renovate.
# Once someone pushes
# onto the branch it stops qualifying, because that change was never reviewed by
# anyone. If a PR stops qualifying or later gains the block label, the workflow
# revokes its own earlier approval so a human is required again. The merge
# itself always stays gated on the repo's required status checks.
# Once someone pushes onto the branch it stops qualifying, because that change
# was never reviewed by anyone. If a PR stops qualifying (including losing the
# automerge label) or later gains the block label, the workflow revokes its own
# earlier approval so a human is required again. The merge itself always stays
# gated on the repo's required status checks.
#
# Which update types are eligible (the automerge label) is decided by the
# renovate-config presets, not here: github>opendefensecloud/renovate-config.
Expand Down Expand Up @@ -61,11 +61,12 @@ concurrency:
jobs:
auto-approve:
runs-on: ubuntu-26.04
# No label condition: a PR that just lost the automerge label must still
# reach the revoke path below.
if: >-
github.event_name == 'pull_request' &&
github.event.pull_request.user.login == inputs.renovate-actor &&
(contains(github.event.pull_request.labels.*.name, inputs.automerge-label) ||
contains(github.event.pull_request.labels.*.name, inputs.block-label))
github.event.pull_request.state == 'open' &&
github.event.pull_request.user.login == inputs.renovate-actor
Comment thread
coderabbitai[bot] marked this conversation as resolved.
steps:
- name: Approve an unmodified Renovate PR, or revoke a prior approval
env:
Expand All @@ -75,14 +76,17 @@ jobs:
HEAD_REF: ${{ github.event.pull_request.head.ref }}
LABEL: ${{ inputs.automerge-label }}
BLOCK_LABEL: ${{ inputs.block-label }}
HAS_BLOCK: ${{ contains(github.event.pull_request.labels.*.name, inputs.block-label) }}
RENOVATE_ACTOR: ${{ inputs.renovate-actor }}
run: |
set -euo pipefail
# Current labels, not the event payload's: runs can finish out of
# event order, and a stale payload would approve or revoke wrongly.
labels=$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name')
has_label() { grep -qxF "$1" <<<"$labels"; }
# Latest review state left by this workflow's identity (github-actions[bot]).
latest_state=$(gh api "repos/$GH_REPO/pulls/$PR_NUMBER/reviews" \
--jq 'map(select((.user.login // "" | ascii_downcase) | startswith("github-actions"))) | last | .state // empty')
if [ "$HAS_BLOCK" = "true" ]; then
if has_label "$BLOCK_LABEL"; then
if [ "$latest_state" = "APPROVED" ]; then
echo "PR now carries the $BLOCK_LABEL label; revoking the earlier automated approval."
gh pr review "$PR_NUMBER" --request-changes \
Expand All @@ -103,6 +107,9 @@ jobs:
fi
exit 0
}
if ! has_label "$LABEL"; then
reject "the PR does not carry the $LABEL label"
fi
# The job-level gate only checks who opened the PR. Also check that
# the branch holds exactly one commit, authored by Renovate, signed, and
# pushed by Renovate, and that Renovate itself added the automerge label.
Expand Down Expand Up @@ -132,15 +139,14 @@ jobs:
if [ "$labeler" != "$RENOVATE_ACTOR" ]; then
reject "the $LABEL label was added by '$labeler', not $RENOVATE_ACTOR"
fi
# Re-read labels: they may have changed after this run started.
labels=$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name')
if has_label "$BLOCK_LABEL" || ! has_label "$LABEL"; then
reject "the labels changed while this run was checking"
fi
if [ "$latest_state" = "APPROVED" ]; then
echo "Already approved by github-actions; nothing to do."
exit 0
fi
# Re-read labels right before approving: the block label may have been
# added after this run started, concurrently with this approval.
if gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name' | grep -qxF "$BLOCK_LABEL"; then
echo "PR now carries the $BLOCK_LABEL label; not approving."
exit 0
fi
gh pr review "$PR_NUMBER" --approve \
--body "Auto-approved: Renovate \`$LABEL\` update. Merge remains gated on required status checks."
2 changes: 1 addition & 1 deletion docs/NEW_REPO.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ preCommitHooks = {

### Renovate auto-approve (optional)

To let Renovate auto-merge digest, patch, and minor PRs without a manual approval, copy `example/.github/workflows/renovate-auto-approve.yml` into your project and pin the `uses:` ref to a dev-kit release tag or commit SHA. It calls dev-kit's reusable `renovate-auto-approve.yml`, which approves Renovate PRs labeled `automerge` by Renovate itself and skips (and revokes) anything labeled `security`. It approves a PR only while the branch is still exactly one signed Renovate commit that Renovate itself pushed, so pushing onto a Renovate branch, including amending or rebasing its commit, revokes the automated approval and hands the review back to a human.
To let Renovate auto-merge digest, patch, and minor PRs without a manual approval, copy `example/.github/workflows/renovate-auto-approve.yml` into your project and pin the `uses:` ref to a dev-kit release tag or commit SHA. It calls dev-kit's reusable `renovate-auto-approve.yml`, which approves Renovate PRs labeled `automerge` by Renovate itself and skips (and revokes) anything labeled `security`. It approves a PR only while the branch is still exactly one signed Renovate commit that Renovate itself pushed, so pushing onto a Renovate branch, including amending or rebasing its commit, revokes the automated approval and hands the review back to a human. Removing the `automerge` label revokes it the same way.

Two more things are needed:

Expand Down
Loading