fix: make docs generation alerts say why and what to do - #1124
fix: make docs generation alerts say why and what to do#1124teallarson wants to merge 9 commits into
Conversation
The nightly Slack alert named the affected toolkits and nothing else, so "MicrosoftUsers has no docs" required reading the run log to learn that the cause was a missing design-system entry — and the log's `0 tools` line reads like a different problem entirely. - Carry the failure reason into the report instead of dropping it, and build the message in `src/alerts/docs-alert.ts` where it can be tested. A jq program embedded in workflow YAML could only ever repeat toolkit names. - Lead with omitted toolkits, which have no page at all, over preserved ones, which still serve their last good output. - Map each known reason to its fix. - Link the job log rather than the run summary, and attach the full report as an artifact. - Drop `continue-on-error` from the Slack step. It swallowed a curl failure against an unset webhook secret, which is how the alert went unnoticed. The reviewer step keeps running on failure but now annotates the run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The Slack step can now fail the job, and the alert job fires on any job failure — so a broken webhook would announce a generation failure that never happened, sending people to look for one. The generate step records that it finished, and the alert job requires that marker to be absent. A later step failing still turns the run red, which is the visible signal it should be. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Actions runs `run:` steps with `-e -o pipefail`, so the job-URL lookup
could abort the step before curl and lose the alert it exists to send.
`${job_url:-$RUN_URL}` covers an empty URL, not a failed lookup, and
because generation itself succeeded the failure-alert job is suppressed —
so nothing reaches Slack.
Two ways it could fail:
- `gh api` exits non-zero (the token already hits "Resource not
accessible" on the reviewer step, so this is not hypothetical).
- `gh api` succeeds and `| head -n 1` SIGPIPEs it, which `pipefail`
turns into exit 141.
Select the first match in jq instead of piping to head, and fall back to
the run URL on any failure. Verified under `-e -o pipefail` that all four
outcomes — API failure, no matching job, empty job list, and a match —
now reach curl.
Reported by Cursor Bugbot on #1124.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re: Bugbot's job-URL finding — Good catch, and there's a second path to the same outcome: even when Fixed in f5f855b by selecting the first match in jq instead of piping to head, plus — Strider 🐦⬛, Teal's agent · approved by Teal |
The recoverable Slack step ran last, under the default "everything so far succeeded" gate. A failed sidebar sync or PR creation therefore skipped it — and because generation itself succeeded, `generation-succeeded` suppressed the failure-alert job too. Missing and stale pages went unannounced in both directions, with the reason sitting in an uploaded artifact nobody had a reason to open. Gate the step on the generate step instead, which is the signal the workflow already tracks to tell "generation broke" from "a later step broke". `!cancelled()` rather than `always()`, since `cancel-in-progress` cancels superseded runs and those have nothing to report. Checked every combination of cancelled, generate outcome, and job result: no case sends both alerts, and no case drops a recoverable report. Reported by Cursor Bugbot on #1124. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A red run whose generate step succeeded sent nothing to Slack: the recoverable report had nothing to say, and the alert job deliberately excluded that case to avoid calling a failed sidebar sync a "generation failure". So an auto-PR that never got created was visible only to someone who happened to open the Actions tab. Give the alert job the third case instead of excluding it. It now fires on every failed generate job and picks wording from `generation-succeeded`: a validation error points at the run, and a publishing break points at sidebar sync and PR creation, and says there may be no auto-PR to merge. A run that recovers from a toolkit failure and then fails to publish sends two messages, on purpose — missing pages and a broken publish are separate things to fix. Checked every combination of cancelled, generate outcome, job result, and recoverable-toolkit presence: no red run is silent. Rendered both alert bodies from the workflow's own run block to confirm valid JSON and the right copy. README documents the three messages. Reported by Cursor Bugbot on #1124. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The alert job now picks its headline from whether generation finished, rather than staying silent when a later step fails. Two assertions still described the old shape: one pinned the literal "generation failed" prefix that jq now builds from a variable, and one pinned the `if:` guard that moved into the step body. Both keep their original intent — that the escaping stays correct, and that a red run after successful generation is not reported as a generation failure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 38c3a4b. Configure here.
…ion-alerts # Conflicts: # toolkit-docs-generator/README.md
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 34d49f3. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 346f4ff. Configure here.

Why
The nightly Slack alert fired for the first time today and read like this:
Which raises every question it should answer. Why did it fail? Is that bad? What do I do? Answering it meant opening the run, expanding the log, and scrolling — and the most visible line there,
✓ MicrosoftUsers: 0 tools, points at the wrong cause. It's the placeholder's empty tool list, not the API's. The real reason,missing design-system metadata, was already infailed-tools.jsonand got thrown away by the jq that built the message.Changes
The reason survives.
FailedToolsReportcarriesrecoveredToolkits: {id, recovery, reason}in place of two arrays of bare names.The message is built in tested code. New
src/alerts/docs-alert.tsplus aalertCLI subcommand that prints the payload, or nothing when a run is clean. A jq program embedded in workflow YAML can only ever repeat what it's given, and nothing tests it.Severity is no longer flattened. An omitted toolkit has no page at all; a preserved one still serves yesterday's. They now get different headlines and ordering, with omitted first.
Each reason maps to its fix. Missing metadata points at
@arcadeai/design-systemandskip-toolkits.txt; curation failures point atcuration/<toolkit>/.The link lands on the failing job, not the run summary, and the full report uploads as the
failed-toolsartifact.Silent failure is gone. The Slack step drops
continue-on-error— it swallowedcurl: (3) URL rejectedagainst an unset webhook secret, which is exactly how this went unnoticed. The reviewer step still can't fail the run, but now annotates it instead of dying quietly (it's been failing onResource not accessible by personal access tokenand nobody knew).Same alert under this change:
Verification
alertcommand against a report reproducing today's failure to produce the message above, and against a missing report to confirm it stays silent.Follow-up not included here:
DOCS_PUBLISHABLE_GH_TOKENneeds reviewer permission, or the review step should go.Note
Low Risk
Changes are limited to CI notifications, run report JSON shape, and alert formatting; no auth or docs generation logic paths are altered beyond persisting richer recovery metadata.
Overview
Toolkit docs generation alerts now carry failure reasons and fixes, instead of listing bare toolkit names in workflow YAML.
failed-tools.jsonreplaces separatepreservedToolkits/omittedToolkitsarrays withrecoveredToolkitsentries (id,recovery,reason). NewbuildDocsAlertand a CLIalertcommand build the Slack payload in tested TypeScript—omitted toolkits lead preserved ones, with per-reason fix hints (design-system metadata, curation paths, etc.).The generate-toolkit-docs workflow posts that payload via
tsx … alert, deep-links the generate job log (actions: read), uploads thefailed-toolsartifact, and dropscontinue-on-erroron the recoverable-failure Slack step so webhook misconfigurations fail loudly. The failure alert job distinguishes generation failed vs generated but a later step failed via ageneration-succeededoutput; PR review request failures stay non-fatal but emit::warning.Docs (README run-alerts section, CURATION
tsxinvocation note) and workflow/unit tests were updated to match.Reviewed by Cursor Bugbot for commit 5303469. Bugbot is set up for automated code reviews on this repo. Configure here.