Skip to content

Add workflow that fails when Dependabot updates error#323

Merged
oschwald merged 1 commit into
mainfrom
wstorey/stf-1124-failures-to-run-dependabot-are-visible
Jul 22, 2026
Merged

Add workflow that fails when Dependabot updates error#323
oschwald merged 1 commit into
mainfrom
wstorey/stf-1124-failures-to-run-dependabot-are-visible

Conversation

@horgh

@horgh horgh commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Add a weekly scheduled workflow that fails when any "Dependabot Updates" run concluded with failure, startup_failure, or timed_out in the last 8 days, so a silently-broken Dependabot ecosystem surfaces as a red scheduled run that emails a human instead of only a red triangle in the Dependabot tab that nobody checks.

This is a copy of the reference change in maxmind/device-android#61, adjusted to run on Wednesdays and to also treat timed_out as a failure.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added a weekly automated check for recent dependency update workflow failures.
    • Added manual execution support for the check.
    • Reports failure details and marks the check as failed when issues are detected.

Dependabot version update failures only surface as a red triangle in
the Dependabot tab, which nobody checks. This weekly scheduled workflow
fails if any "Dependabot Updates" run concluded with failure,
startup_failure, or timed_out in the last 8 days, so a broken ecosystem
surfaces as a red scheduled run that emails a human.

See maxmind/device-android#61 for the reference implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 16:12
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a weekly and manually triggered GitHub Actions workflow that checks recent Dependabot Updates runs and fails with details when failure-like conclusions are detected.

Changes

Dependabot failure monitoring

Layer / File(s) Summary
Scheduled failure detection
.github/workflows/dependabot-failure-watcher.yml
Queries Dependabot Updates runs from the previous 8 days, filters failure, startup_failure, and timed_out conclusions, and conditionally reports and fails the workflow.

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

Possibly related PRs

Suggested reviewers: copilot

Poem

I’m a rabbit watching workflows run,
Checking failures one by one.
Dependabot hops through the night,
I flag the runs that aren’t quite right.
A green report, or thumps of fright!

🚥 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: a new workflow that fails when Dependabot update runs error out.
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-1124-failures-to-run-dependabot-are-visible

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
.github/workflows/dependabot-failure-watcher.yml

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


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

Adds a scheduled GitHub Actions workflow to detect and surface silently failing “Dependabot Updates” runs by failing a weekly watcher job when recent Dependabot update runs have concluded unsuccessfully.

Changes:

  • Introduces a new scheduled + manually-dispatchable workflow to scan recent “Dependabot Updates” workflow runs.
  • Fails the watcher job and emits an error annotation listing failing runs when failures are detected.

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

failures=$(gh run list \
--repo "$REPO" \
--workflow "Dependabot Updates" \
--limit 100 \
--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\")]")

@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: 4

🤖 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 3-11: Update the comments in the Dependabot failure watcher
workflow to describe an 8-day lookback instead of the past week, and replace the
guaranteed email claim with an accurate statement that notifications depend on
GitHub notification settings and the scheduled-workflow actor. Leave the
workflow behavior unchanged.
- Around line 31-33: Update the gh run list invocation in the failures
assignment to include the --all option, ensuring disabled “Dependabot Updates”
workflow runs are considered while preserving the existing repository, workflow,
and time-window filters.
- Around line 34-36: Update the Dependabot run query in the workflow to paginate
through all matching runs instead of using --limit 100, and filter the failure
conditions by each run’s conclusion time rather than createdAt. Preserve the
existing failure conclusions and eight-day cutoff while ensuring runs that
conclude within the window are included even if they were created earlier.
- Around line 35-36: Update the `gh run list` JSON fields and jq filter to use
`updatedAt` instead of `createdAt` when comparing against `$since`, so runs
completed within the eight-day window are included even if they started earlier.
🪄 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: 5669ba20-fbfe-4847-af48-55eeade35840

📥 Commits

Reviewing files that changed from the base of the PR and between a598ecd and 70feb6d.

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

Comment on lines +3 to +11
# Dependabot version updates run as GitHub Actions workflow runs named
# "Dependabot Updates". This scheduled job looks back over the past week for any
# of those runs that failed and fails itself if it finds one, so a silently-broken
# ecosystem surfaces as a red scheduled run instead of only a red triangle in the
# Dependabot tab that nobody checks.
#
# Runs entirely within this repo (no external service). A failed scheduled run
# emails the person who last edited the cron below. Note: GitHub auto-disables
# scheduled workflows after 60 days of repo inactivity.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- workflow file outline ---\n'
wc -l .github/workflows/dependabot-failure-watcher.yml
cat -n .github/workflows/dependabot-failure-watcher.yml | sed -n '1,220p'

printf '\n--- search for related docs or comments ---\n'
rg -n "Dependabot Updates|scheduled workflows after 60 days|person who last edited the cron|notification|workflow runs" .github/workflows .github -g '!**/*.png' || true

Repository: maxmind/GeoIP2-php

Length of output: 247


🌐 Web query:

GitHub Actions notifications for workflow runs scheduled workflow actor cron editor email delivery docs

💡 Result:

For GitHub Actions scheduled workflows, notifications are automatically sent to the user identified as the actor [1][2]. Specifically, the system sends notifications to the user who last modified the cron syntax in the workflow file [1][2]. If the workflow is disabled and then re-enabled, the notifications are sent to the user who performed the re-enabling action rather than the original author of the cron syntax [1]. Key points regarding scheduled workflow notifications: - Recipient: Notifications go to the user associated with the workflow's cron schedule [1][2]. This is typically the last person who updated the cron syntax or re-enabled the workflow [1]. - Delivery Method: If you have email or web notifications enabled for GitHub Actions in your personal notification settings, these alerts will be delivered accordingly [1][3]. You can configure your preferences to receive updates for all workflow runs or only for failed runs [1][3]. - Customization: GitHub does not natively provide a way to change the notification recipient for a specific scheduled workflow to someone other than the current "actor." [1][2] - Alternative Solutions: To notify a broader team or a specific channel (e.g., Slack or Microsoft Teams) about a scheduled workflow's status, users often add an explicit notification step to their workflow file [4]. This is commonly done using actions or scripts that send a payload to an external webhook (such as a Slack webhook or a REST API endpoint) upon completion or failure [4]. For managing your personal notification settings, you can navigate to your GitHub notification settings page and look under the Actions section to select your preferred delivery method (Web or Email) and filter criteria (e.g., failed workflows only) [3][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- workflow file ---'
cat -n .github/workflows/dependabot-failure-watcher.yml | sed -n '1,220p'

echo
echo '--- nearby references ---'
rg -n "past week|eight days|60 days|cron|email|Dependabot Updates|scheduled workflows" .github/workflows .github -g '!**/*.png' || true

Repository: maxmind/GeoIP2-php

Length of output: 4068


Align the comment with the actual behavior.

  • The lookback is 8 days, not “the past week”.
  • Don’t promise an email to the person who last edited the cron; scheduled-workflow notifications depend on GitHub notification settings and the scheduled-workflow actor.
🤖 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 3 - 11, Update
the comments in the Dependabot failure watcher workflow to describe an 8-day
lookback instead of the past week, and replace the guaranteed email claim with
an accurate statement that notifications depend on GitHub notification settings
and the scheduled-workflow actor. Leave the workflow behavior unchanged.

Comment on lines +31 to +33
failures=$(gh run list \
--repo "$REPO" \
--workflow "Dependabot Updates" \

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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the workflow file around the referenced lines
nl -ba .github/workflows/dependabot-failure-watcher.yml | sed -n '1,120p'

# Show the exact gh run list help text for workflow filtering if gh is available
if command -v gh >/dev/null 2>&1; then
  gh run list --help | sed -n '1,220p'
else
  echo "gh CLI not available in sandbox"
fi

Repository: maxmind/GeoIP2-php

Length of output: 196


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the workflow file without relying on nl
git ls-files .github/workflows/dependabot-failure-watcher.yml
echo '---'
cat -n .github/workflows/dependabot-failure-watcher.yml | sed -n '1,140p'

Repository: maxmind/GeoIP2-php

Length of output: 2272


🌐 Web query:

gh run list --workflow --all disabled workflows manual

💡 Result:

To list runs for disabled workflows using the GitHub CLI (gh), you must use the --all (or -a) flag in conjunction with the --workflow (-w) flag [1][2][3]. By default, when you filter by a workflow name using the -w flag, the GitHub CLI does not include disabled workflows in the results [1][4]. Adding the --all flag explicitly instructs the command to include them [1][5]. Example command: gh run list --workflow "Workflow Name" --all Key details: - The --all flag mirrors the behavior found in gh workflow list [5]. - When filtering by workflow, you can provide the workflow name, ID, or filename [6]. - If you encounter issues where disabled workflows are not appearing, ensure that you are providing the correct identifier and appending --all to your command [1][7].

Citations:


Include disabled workflow runs.

gh run list --workflow ... skips disabled workflows unless --all is added. If Dependabot Updates is disabled, this watcher can miss a failure in the eight-day window and report success.

Proposed fix
           failures=$(gh run list \
             --repo "$REPO" \
+            --all \
             --workflow "Dependabot Updates" \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
failures=$(gh run list \
--repo "$REPO" \
--workflow "Dependabot Updates" \
failures=$(gh run list \
--repo "$REPO" \
--all \
--workflow "Dependabot Updates" \
🤖 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 31 - 33,
Update the gh run list invocation in the failures assignment to include the
--all option, ensuring disabled “Dependabot Updates” workflow runs are
considered while preserving the existing repository, workflow, and time-window
filters.

Comment on lines +34 to +36
--limit 100 \
--json conclusion,createdAt,displayTitle,url \
--jq "[.[] | select((.conclusion == \"failure\" or .conclusion == \"startup_failure\" or .conclusion == \"timed_out\") and .createdAt >= \"$since\")]")

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

Don't cap this completeness check at 100 runs.

  • --limit 100 can hide a failing Dependabot run once more than 100 runs exist in the eight-day window.
  • Filtering on createdAt also misses runs created before the cutoff that fail inside the window.

Use pagination and filter by the run’s conclusion time, not createdAt.

🤖 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 34 - 36,
Update the Dependabot run query in the workflow to paginate through all matching
runs instead of using --limit 100, and filter the failure conditions by each
run’s conclusion time rather than createdAt. Preserve the existing failure
conclusions and eight-day cutoff while ensuring runs that conclude within the
window are included even if they were created earlier.

Comment on lines +35 to +36
--json conclusion,createdAt,displayTitle,url \
--jq "[.[] | select((.conclusion == \"failure\" or .conclusion == \"startup_failure\" or .conclusion == \"timed_out\") and .createdAt >= \"$since\")]")

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 | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## file slice\n'
nl -ba .github/workflows/dependabot-failure-watcher.yml | sed -n '1,140p'

printf '\n## search timestamp fields in repo\n'
rg -n --hidden --glob '!**/.git/**' '\b(createdAt|updatedAt|startedAt|completedAt)\b' .github/workflows . 2>/dev/null | sed -n '1,160p'

Repository: maxmind/GeoIP2-php

Length of output: 211


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## file slice\n'
cat -n .github/workflows/dependabot-failure-watcher.yml | sed -n '1,140p'

printf '\n## gh run list docs mentions\n'
python3 - <<'PY'
import urllib.request
from html.parser import HTMLParser

url = "https://cli.github.com/manual/gh_run_list"
print("Fetching:", url)
with urllib.request.urlopen(url, timeout=20) as r:
    data = r.read().decode("utf-8", "replace")
for needle in ["createdAt", "updatedAt", "completedAt", "conclusion"]:
    idx = data.find(needle)
    print("\nNEEDLE", needle, "idx", idx)
    if idx != -1:
        start = max(0, idx - 200)
        end = min(len(data), idx + 400)
        print(data[start:end].replace("\n", " "))
PY

Repository: maxmind/GeoIP2-php

Length of output: 4602


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## file slice\n'
cat -n .github/workflows/dependabot-failure-watcher.yml | sed -n '1,140p'

printf '\n## gh run list docs mentions\n'
python3 - <<'PY'
import urllib.request
url = "https://cli.github.com/manual/gh_run_list"
print("Fetching:", url)
with urllib.request.urlopen(url, timeout=20) as r:
    data = r.read().decode("utf-8", "replace")
for needle in ["createdAt", "updatedAt", "completedAt", "conclusion"]:
    idx = data.find(needle)
    print("\nNEEDLE", needle, "idx", idx)
    if idx != -1:
        start = max(0, idx - 200)
        end = min(len(data), idx + 400)
        print(data[start:end].replace("\n", " "))
PY

Repository: maxmind/GeoIP2-php

Length of output: 4602


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## file slice\n'
sed -n '1,160p' .github/workflows/dependabot-failure-watcher.yml | cat -n

printf '\n## grep timestamp-related lines\n'
grep -nE 'createdAt|updatedAt|completedAt|conclusion|gh run list' .github/workflows/dependabot-failure-watcher.yml || true

Repository: maxmind/GeoIP2-php

Length of output: 2630


🏁 Script executed:

#!/bin/bash
set -euo pipefail

gh run list --help | sed -n '1,240p'

printf '\n## timestamp field mentions\n'
gh run list --help | grep -nE 'createdAt|updatedAt|completedAt|json' || true

Repository: maxmind/GeoIP2-php

Length of output: 2504


🌐 Web query:

GitHub Actions workflow run createdAt updatedAt completion time gh run list updatedAt documentation

💡 Result:

In GitHub Actions, workflow run metadata includes timestamps for creation and updates, though "completion time" is not provided as a single field. Workflow Run Timestamps - created_at: The timestamp indicating when the workflow run was created [1][2][3]. - updated_at: The timestamp indicating the last time the workflow run was modified [1][2][3]. - run_started_at: In the REST API, this field provides the time when the workflow execution actually began [1][2]. - completion time: There is no dedicated completion_time field. To calculate the total duration, you typically use the run_started_at timestamp and the time at which the status reached completed, or derive it from the completed_at field available in individual job details [4]. Using gh run list The GitHub CLI (gh run list) supports displaying these timestamps via the --json flag. You can request the following fields [5][6]: - createdAt - updatedAt - startedAt (corresponds to run_started_at) - status (used to determine if the run is completed) Example usage: gh run list --json createdAt,updatedAt,startedAt,status,name For custom formatting or calculations (such as duration), you can use the --template flag with Go templates or pipe the JSON output to jq to process the timestamps [5][7]. The API and CLI return these values as ISO 8601 formatted strings [1][4].

Citations:


Filter on updatedAt instead of createdAt. This check is meant to catch runs that concluded in the last 8 days, but createdAt can miss runs that start before the cutoff and finish after it. gh run list exposes updatedAt, which fits this window better.

🤖 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 35 - 36,
Update the `gh run list` JSON fields and jq filter to use `updatedAt` instead of
`createdAt` when comparing against `$since`, so runs completed within the
eight-day window are included even if they started earlier.

@oschwald
oschwald merged commit c6d020c into main Jul 22, 2026
40 checks passed
@oschwald
oschwald deleted the wstorey/stf-1124-failures-to-run-dependabot-are-visible branch July 22, 2026 17:41
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