Docs
Dependabot CI fix
Dependabot CI fix reacts when a dependency-update PR (Dependabot or Renovate)
goes red in CI. When a check suite completes with a failure, Last Light brings
the branch up to date with its base, diagnoses the breakage, and pushes the
smallest fix that makes CI pass. It is fix-only: it never
classifies, labels, or merges the PR. Once the push turns the checks green,
the pr.checks_passed webhook hands off to
dependabot-pr-merge, the
single owner of the trivial-vs-functional classification and the auto-merge
decision — so the two workflows never duplicate each other's work.
repo-write — it merges the
base branch into the PR branch and pushes commits, but always with a plain
(non-force) push so Dependabot / Renovate don't lose track of their own
branch. It never labels or merges — that's dependabot-pr-merge's
job once the checks go green.
Pipeline
What it does
- Clones the repo at the PR's head branch (the dependency bump is already committed there)
- Merges the base branch into the PR branch first (plain
git merge, no rebase or force-push) so the fix is built on current base and abehindPR is brought up to date — resolving any lockfile conflict by regenerating it - Reads the CI failures and diagnoses the cause — a stale lockfile, a breaking change in the new version, a call site or type that needs updating
- Makes the smallest fix that turns CI green, runs the test / lint / typecheck gate, and plain-pushes to the PR branch
- Stops there — it does not classify, comment, label (except the give-up case below), or merge. The push re-runs CI, and when it goes green the
pr.checks_passedwebhook fires dependabot-pr-merge to make the one classify / auto-merge decision
dependabot-pr-merge later sees is clean rather than
behind — so the merge workflow can act on it directly instead of
asking the bot to rebase.
Triggers
- GitHub webhook: a
check_suite.completedevent with afailure/timed_outconclusion (surfaced internally aspr.checks_failed). The router runs it through the intent classifier, which routes a recognised dependency-update PR here. Requires the GitHub App to subscribe to Check suite events (Checks: read). - Cron backstop: a daily job (
fix-red-dependency-prs, 15:00 — one hour after the green sweep) whose runner finds, in code, the Dependabot / Renovate PRs across managed repos that can't merge on their own and that ci-fix can push toward: a settled-red check conclusion (failing/timed-out, so it never fires while checks are still running), or amergeable_stateofbehind/dirty/blocked. It fans out one bounded run per PR — the same single-PR shape as the webhook, carrying the PR head branch (pre-clone) and thereason(checks-failing|behind|dirty|blocked; failing CI wins). It runs alongside webhooks — a safety net for PRs that went red, or fell out of a mergeable state, before boot or during a missed delivery. (cleanis the green sweep's;unknownis left for a later tick.) Per-PR runs dedup by (repo, PR). - Maintainer mention: an
@last-lightcomment on a red Dependabot / Renovate PR (e.g. "can you look at this?"). The router hands the PR author + check state to the classifier, which routes a red dependency PR here — the on-demand version of the webhook. (A green one routes to dependabot-pr-merge instead; an explicit "review this" still gets a normal review.)
Because routing goes through the classifier rather than a fixed rule, other
workflows can react to the same failing-checks event by declaring their own
classification block — this workflow simply claims the
dependency-update case.
Labels
The dependency workflows share a small label state machine so status is
visible and the crons don't churn. ci-fix touches labels in only one case:
when it can't land the PR — it can't repair CI with a small,
safe change, or there's nothing to push and it can't unblock the PR (e.g. a
blocked PR awaiting a required human review) — it applies
requires-human and stops. The verdict labels
(dependency-trivial / dependency-functional) — and
clearing a stale requires-human once a later fix lands green — are
owned entirely by dependabot-pr-merge,
which keeps the classification in one place. Both the red and green cron sweeps
skip PRs labelled requires-human, so they never
re-attempt what Last Light already gave up on — while the webhooks stay
label-blind, so a genuinely new bot push is handled live and the success path
clears the label. Labels are created on demand
(github_ensure_labels).