Skip to content
Closed
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
62 changes: 62 additions & 0 deletions .github/workflows/dependabot-rebase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Dependabot rebase workflow
# Copy to .github/workflows/dependabot-rebase.yml

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header comment Copy to .github/workflows/dependabot-rebase.yml is misleading now that this file already lives at that path. Consider removing or rewording it to describe the workflow’s purpose instead of implying it’s a template to be copied.

Suggested change
# Copy to .github/workflows/dependabot-rebase.yml
# Rebases open Dependabot PRs that have fallen behind main after pushes.

Copilot uses AI. Check for mistakes.
#
# Problem: when branch protection requires branches to be up-to-date
# (strict status checks), merging one Dependabot PR makes the others fall
# behind. Dependabot does not auto-rebase PRs that are merely behind — it
# only rebases on its next scheduled run or when there are merge conflicts.
# This leaves auto-merge stalled until the next weekly Dependabot run.
#
# Solution: after every push to main (typically a merged PR), this workflow
# finds open Dependabot PRs that are behind and asks Dependabot to rebase
# them via the @dependabot rebase command. Dependabot performs the rebase
# with its own commit signature, preserving the automerge workflow's ability
# to verify the PR author.
#
# Important: never use the GitHub API update-branch endpoint to rebase
# Dependabot PRs — it replaces Dependabot's commit signature with GitHub's,
# which breaks dependabot/fetch-metadata verification and causes Dependabot
# to refuse future rebases on that PR.
name: Dependabot rebase behind PRs

on:
push:
branches:
- main

permissions: {}

jobs:
rebase:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Rebase behind Dependabot PRs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
# Find open Dependabot PRs
PRS=$(gh pr list --repo "$REPO" --author "app/dependabot" \
--json number,headRefName \
--jq '.[] | "\(.number) \(.headRefName)"')

if [[ -z "$PRS" ]]; then
echo "No open Dependabot PRs"
exit 0
fi

while IFS=' ' read -r PR_NUMBER HEAD_REF; do
BEHIND=$(gh api "repos/$REPO/compare/main...$HEAD_REF" \

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HEAD_REF from Dependabot PRs typically contains slashes (e.g. dependabot/npm_and_yarn/...). Using it unescaped inside the REST path compare/main...$HEAD_REF will produce an invalid URL (extra path segments), causing gh api to 404 and the step to fail under the default bash -e runner shell. URL-encode the ref before calling the compare endpoint (or fetch the behind count via a PR/GraphQL field that doesn't require embedding the ref in the URL path).

Suggested change
BEHIND=$(gh api "repos/$REPO/compare/main...$HEAD_REF" \
ENCODED_HEAD_REF=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$HEAD_REF")
BEHIND=$(gh api "repos/$REPO/compare/main...$ENCODED_HEAD_REF" \

Copilot uses AI. Check for mistakes.
--jq '.behind_by')

if [[ "$BEHIND" -gt 0 ]]; then
echo "PR #$PR_NUMBER ($HEAD_REF) is $BEHIND commit(s) behind — requesting rebase"
gh pr comment "$PR_NUMBER" --repo "$REPO" \
--body "@dependabot rebase"
else
echo "PR #$PR_NUMBER ($HEAD_REF) is up to date"
fi
done <<< "$PRS"