From baf3b26d0e29afdcea8ad731be67313c387b42c5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Jul 2026 22:14:47 +0000 Subject: [PATCH 1/3] Add workflow that fails when Dependabot updates error --- .../workflows/dependabot-failure-watcher.yml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/dependabot-failure-watcher.yml diff --git a/.github/workflows/dependabot-failure-watcher.yml b/.github/workflows/dependabot-failure-watcher.yml new file mode 100644 index 0000000..417412b --- /dev/null +++ b/.github/workflows/dependabot-failure-watcher.yml @@ -0,0 +1,24 @@ +name: Dependabot Failure Watcher + +# Dependabot version updates now run as ordinary Actions workflow runs named +# "Dependabot Updates". This watcher fails (goes red in the Actions tab) whenever +# one of those runs completes with a failure, so a silently-broken ecosystem is +# visible instead of only appearing as a red triangle in the Dependabot tab. + +on: + workflow_run: + workflows: ["Dependabot Updates"] + types: [completed] + +permissions: {} + +jobs: + report-failure: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + runs-on: ubuntu-latest + steps: + - name: Fail on a failed Dependabot run + run: | + echo "::error::Dependabot Updates run failed: ${{ github.event.workflow_run.display_title }}" + echo "See: ${{ github.event.workflow_run.html_url }}" + exit 1 From fb6b719c271fe54f61e2081f2bd9f47ca1e9dc4b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Jul 2026 22:18:38 +0000 Subject: [PATCH 2/3] Address zizmor: use env vars for run metadata, ignore workflow_run trigger warning --- .github/workflows/dependabot-failure-watcher.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dependabot-failure-watcher.yml b/.github/workflows/dependabot-failure-watcher.yml index 417412b..6aa4b50 100644 --- a/.github/workflows/dependabot-failure-watcher.yml +++ b/.github/workflows/dependabot-failure-watcher.yml @@ -4,9 +4,13 @@ name: Dependabot Failure Watcher # "Dependabot Updates". This watcher fails (goes red in the Actions tab) whenever # one of those runs completes with a failure, so a silently-broken ecosystem is # visible instead of only appearing as a red triangle in the Dependabot tab. +# +# This workflow checks out no code, consumes no untrusted input in a dangerous +# way, and holds no permissions (permissions: {}), so the usual workflow_run +# risks do not apply; the trigger is required to observe Dependabot job outcomes. on: - workflow_run: + workflow_run: # zizmor: ignore[dangerous-triggers] no checkout, no secrets, permissions: {}; only reads the run conclusion and reports. workflows: ["Dependabot Updates"] types: [completed] @@ -18,7 +22,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Fail on a failed Dependabot run + env: + TITLE: ${{ github.event.workflow_run.display_title }} + URL: ${{ github.event.workflow_run.html_url }} run: | - echo "::error::Dependabot Updates run failed: ${{ github.event.workflow_run.display_title }}" - echo "See: ${{ github.event.workflow_run.html_url }}" + echo "::error::Dependabot Updates run failed: ${TITLE}" + echo "See: ${URL}" exit 1 From 407b82ca03a794f84005e4f30e44347bc086321c Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 14:48:58 +0000 Subject: [PATCH 3/3] Switch Dependabot failure watcher to a scheduled cron check --- .../workflows/dependabot-failure-watcher.yml | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/.github/workflows/dependabot-failure-watcher.yml b/.github/workflows/dependabot-failure-watcher.yml index 6aa4b50..a0c9c9b 100644 --- a/.github/workflows/dependabot-failure-watcher.yml +++ b/.github/workflows/dependabot-failure-watcher.yml @@ -1,31 +1,43 @@ name: Dependabot Failure Watcher -# Dependabot version updates now run as ordinary Actions workflow runs named -# "Dependabot Updates". This watcher fails (goes red in the Actions tab) whenever -# one of those runs completes with a failure, so a silently-broken ecosystem is -# visible instead of only appearing as a red triangle in the Dependabot tab. +# 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. # -# This workflow checks out no code, consumes no untrusted input in a dangerous -# way, and holds no permissions (permissions: {}), so the usual workflow_run -# risks do not apply; the trigger is required to observe Dependabot job outcomes. +# 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. on: - workflow_run: # zizmor: ignore[dangerous-triggers] no checkout, no secrets, permissions: {}; only reads the run conclusion and reports. - workflows: ["Dependabot Updates"] - types: [completed] + schedule: + - cron: "17 14 * * 1" # Mondays 14:17 UTC + workflow_dispatch: -permissions: {} +permissions: + actions: read jobs: - report-failure: - if: ${{ github.event.workflow_run.conclusion == 'failure' }} + check-dependabot-runs: runs-on: ubuntu-latest steps: - - name: Fail on a failed Dependabot run + - name: Fail if any Dependabot update failed in the last 8 days env: - TITLE: ${{ github.event.workflow_run.display_title }} - URL: ${{ github.event.workflow_run.html_url }} + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} run: | - echo "::error::Dependabot Updates run failed: ${TITLE}" - echo "See: ${URL}" - exit 1 + since=$(date -u -d '8 days ago' +%Y-%m-%dT%H:%M:%SZ) + failures=$(gh run list \ + --repo "$REPO" \ + --workflow "Dependabot Updates" \ + --limit 100 \ + --json conclusion,createdAt,displayTitle,url \ + --jq "[.[] | select((.conclusion == \"failure\" or .conclusion == \"startup_failure\") and .createdAt >= \"$since\")]") + count=$(echo "$failures" | jq 'length') + if [ "$count" -gt 0 ]; then + echo "::error::$count failed Dependabot update run(s) in the last 8 days:" + echo "$failures" | jq -r '.[] | "- \(.displayTitle) (\(.createdAt))\n \(.url)"' + exit 1 + fi + echo "No failed Dependabot update runs in the last 8 days."