Skip to content

Ignore Dependabot security updates in the failure watcher - #327

Merged
oschwald merged 1 commit into
mainfrom
wstorey/stf-1245-dependabot-failure-watcher-emails-go-to-the-correct-person
Jul 30, 2026
Merged

Ignore Dependabot security updates in the failure watcher#327
oschwald merged 1 commit into
mainfrom
wstorey/stf-1245-dependabot-failure-watcher-emails-go-to-the-correct-person

Conversation

@horgh

@horgh horgh commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

GitHub runs Dependabot version updates and Dependabot security updates under one
workflow name, Dependabot Updates, and the watcher counted both. Security
updates routinely fail for reasons no pull request can fix -- the advisory is
against a dependency the project does not declare directly, or no patched
version is reachable -- so the watcher stays red every week on those and trains
everyone to ignore it.

This filters security-update runs out by title, documents why both halves of
" in /. for " are load-bearing, and bounds the gh run list query server-side
with --created instead of fetching all of history and filtering locally.

See the commit message for the full reasoning, including why reading the
directory list out of dependabot.yml was tried and rejected.

This workflow is shared verbatim across MaxMind repos. The change was developed
in maxmind/device-android (maxmind/device-android#71)
and is applied here unmodified; the resulting file is byte-identical in every
repo.

Summary by CodeRabbit

  • Bug Fixes
    • Improved monitoring of failed Dependabot version update runs.
    • Reduced false alerts by excluding security-related updates and unrelated end-to-end smoke test runs.
    • Expanded the monitoring window and refined filtering to more reliably count only relevant failure types.
    • Failure reporting behavior (error annotation, failing run details/links, and non-zero exit) remains the same.
  • Documentation
    • Expanded workflow documentation to precisely describe the different Dependabot run title formats and why specific filtering rules are used.

Copilot AI review requested due to automatic review settings July 30, 2026 16:58
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 65d783a0-d0a6-43f8-b06d-5f10eb1fdf1b

📥 Commits

Reviewing files that changed from the base of the PR and between 4422065 and ab8d064.

📒 Files selected for processing (1)
  • .github/workflows/dependabot-failure-watcher.yml

📝 Walkthrough

Walkthrough

The Dependabot failure watcher now documents run-title distinctions and more precisely filters recent failed version-update runs while excluding security and end-to-end runs. Its failure reporting and exit behavior remain unchanged.

Changes

Dependabot watcher

Layer / File(s) Summary
Document and filter version-update failures
.github/workflows/dependabot-failure-watcher.yml
Documents Dependabot run-title formats and updates the watcher to use server-side date filtering, a larger run limit, title-based exclusions, and selected failure conclusions.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

A rabbit checks the runs at night,
Skips security trails from sight.
Failed updates thump and glow,
The watcher names each one below.
“Hop onward!” says the watchful hare.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: the failure watcher now ignores Dependabot security-update runs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch wstorey/stf-1245-dependabot-failure-watcher-emails-go-to-the-correct-person

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the “Dependabot Failure Watcher” GitHub Actions workflow to ignore Dependabot security update runs (which frequently fail for reasons outside the repo’s control) while continuing to fail on genuinely broken Dependabot version update runs, keeping the signal-to-noise ratio high.

Changes:

  • Filters out security-update runs based on displayTitle patterns (with explicit documentation explaining why the match string is intentionally specific).
  • Uses gh run list --created to bound the query server-side instead of filtering all historical runs locally.
  • Expands and clarifies the workflow’s inline documentation around the different “Dependabot Updates” run types and the tradeoffs of filtering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/dependabot-failure-watcher.yml:
- Around line 93-98: Update the run-collection logic around the gh run list
invocation to detect when the 500-run cap is reached and avoid treating that
truncated result as complete. Paginate through all matching Dependabot Updates
runs until the since boundary is exhausted, or fetch a sentinel row and fail
closed when additional runs may exist; only report no failed runs after the full
time window has been covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a88cfe00-f665-4660-b66b-d3be17d49f7b

📥 Commits

Reviewing files that changed from the base of the PR and between df9d953 and 4422065.

📒 Files selected for processing (1)
  • .github/workflows/dependabot-failure-watcher.yml

Comment on lines +93 to +98
runs=$(gh run list \
--repo "$REPO" \
--workflow "Dependabot Updates" \
--limit 100 \
--json conclusion,createdAt,displayTitle,url \
--jq "[.[] | select((.conclusion == \"failure\" or .conclusion == \"startup_failure\" or .conclusion == \"timed_out\") and .createdAt >= \"$since\")]")
--created ">=$since" \
--limit 500 \
--json conclusion,createdAt,displayTitle,url)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate workflow =="
git ls-files | rg '(^|/)\.github/workflows/dependabot-failure-watcher\.yml$|dependabot-failure-watcher\.yml$' || true

echo "== Relevant workflow excerpt =="
if [ -f .github/workflows/dependabot-failure-watcher.yml ]; then
  nl -ba .github/workflows/dependabot-failure-watcher.yml | sed -n '1,140p'
fi

echo "== Search run-list handling and limit references =="
rg -n "run list|limit|since|conclusion|displayTitle|Dependabot Updates|gh run" .github/workflows || true

Repository: maxmind/GeoIP2-php

Length of output: 299


🏁 Script executed:

#!/bin/sh
set -euo pipefail

echo "== Relevant workflow excerpt =="
awk '{printf "%d\t%s\n", NR, $0}' .github/workflows/dependabot-failure-watcher.yml | sed -n '1,180p'

echo "== Search run-list handling and limit references =="
grep -nE "run list|limit|since|conclusion|displayTitle|Dependabot Updates|gh run|fail|exit|jq" .github/workflows/dependabot-failure-watcher.yml || true

Repository: maxmind/GeoIP2-php

Length of output: 8761


🌐 Web query:

GitHub CLI gh run list --limit maximum number of runs fetched documentation

💡 Result:

The GitHub CLI command gh run list uses the --limit flag (or -L shorthand) to specify the maximum number of workflow runs to fetch [1][2]. According to the official GitHub CLI manual, this flag has a default value of 20 [1][2]. While some legacy documentation may reference a default of 10 [3][4][5], the current authoritative manual for the gh run list command specifies the default limit as 20 [1][2].

Citations:


Fail closed when the 500-run cap is reached.

gh run list --limit returns at most the requested number of runs, newest-first, so an 8-day window with more than 500 matching Dependabot runs can omit older failed runs and print “No failed Dependabot version update runs”. Paginate until the time window is exhausted, or fetch a sentinel row and fail rather than treating a capped result as complete.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/dependabot-failure-watcher.yml around lines 93 - 98,
Update the run-collection logic around the gh run list invocation to detect when
the 500-run cap is reached and avoid treating that truncated result as complete.
Paginate through all matching Dependabot Updates runs until the since boundary
is exhausted, or fetch a sentinel row and fail closed when additional runs may
exist; only report no failed runs after the full time window has been covered.

Source: MCP tools

GitHub runs both Dependabot version updates and Dependabot security
updates under one workflow name, "Dependabot Updates", and the watcher
counted both. Security updates routinely fail for reasons no pull request
can fix -- the advisory is against a dependency this project does not
declare directly, or no patched version is reachable. Left alone the
watcher stays red every week on those and trains everyone to ignore it.

Filter those runs out by title. Version updates are unaffected.

The title check is subtler than it looks, so document it properly. A
security job is marked by "/." AND a " for " suffix together; version
updates are either "/." with no " for " (the scheduled scan) or "/" with
one (the pull request). Both halves of " in /. for " are therefore
load-bearing -- matching on " in /." alone would discard every scan run,
which is most of the version-update runs and the shape the failures this
watcher was written for actually took.

That "/." spelling only separates the two at the repo root. In a
subdirectory a security update and a version update's pull request render
identically, so drop " in /e2e/{js,ts} for " by name as well. The Node
repos this workflow is shared with carry committed lockfiles under e2e/js
and e2e/ts, whose transitive dev dependencies attract advisories no pull
request can fix, and nothing in either is shipped code. That is 16
unactionable failures in each of GeoIP2-node and minfraud-api-node over
retained history; repos without those directories are unaffected.

Unlike the root filter, this one is not free. Both Node repos configure
npm with directories: ["/", "**/*"], and that glob does match e2e/js and
e2e/ts, so those directories do get version updates -- there is an open
version-update pull request under e2e/ts in both repos as this is
written. Dropping the pattern discards their pull-request refresh
failures along with the security jobs, and the ecosystem label is no help
because Dependabot writes "npm_and_yarn" for both. Taken anyway: the
scheduled scan is what this watcher primarily exists to catch and is
still reported for those directories, so what is given up is the narrower
"one open pull request has gone stale" signal for two directories of test
scaffolding. After filtering, 4 genuine failures remain reported in
GeoIP2-node and 3 in minfraud-api-node.

Reading the directories out of dependabot.yml would look more general and
was the earlier plan here, but it fails green. Entries may use globs, and
minfraud-api-dotnet's directories: ["**/*"] yields titles like "nuget in
/**/*" for the scan and "nuget in /MaxMind.MinFraud for
System.Net.Http.Json" for the pull request, neither of which any literal
comparison against the configured value matches -- so its two real nuget
failures would have been dropped without a word. A stale denylist
re-introduces noise, which is loud; a stale allowlist hides failures.

Name the three kinds of run in the comment while here, because the
scheduled scan and the per-pull-request refresh are easy to conflate: the
refresh runs are one per open pull request and are triggered by pushes to
the base branch or by rebases, not by the schedule, so they arrive in
bursts after merges. The scan is the kind this watcher primarily exists
to catch, which is what makes hiding a hypothetical refresh failure under
e2e an acceptable cost rather than a hole.

Bound the query server-side with --created instead of fetching all of
history and filtering by date locally, so --limit now caps an
already-narrowed window rather than standing in for one, and the run list
drops from several API pages to one. --limit rises 100 -> 500 as a
backstop: it still applies before the title filter, and reaching it would
silently drop the oldest in-window runs.

This workflow is shared verbatim across MaxMind repos. The change was
developed in maxmind/device-android and is applied here unmodified; see
that repo's commit for the measurements it was derived from.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@horgh
horgh force-pushed the wstorey/stf-1245-dependabot-failure-watcher-emails-go-to-the-correct-person branch from 4422065 to ab8d064 Compare July 30, 2026 17:53
@oschwald
oschwald merged commit bdde995 into main Jul 30, 2026
39 checks passed
@oschwald
oschwald deleted the wstorey/stf-1245-dependabot-failure-watcher-emails-go-to-the-correct-person branch July 30, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants