Replace per-merge Slack messages with a daily PR dashboard#1448
Conversation
The merge-to-main-slack workflow posts one message per merged PR, which is noisy. Spec out a replacement that maintains a single per-day dashboard message in #building, updated in place on PR events. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One message per UTC day in #building, created on the first PR event of the day and updated in place after that (chat.update). Content is refetched from the GitHub search API each run: merged / closed-unmerged / opened today, plus a compact line of older still-open PRs. The message ts lives in a repo Actions variable; pushes to *pr-dashboard* branches exercise the workflow against #misha-test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…/iterate into slack-daily-pr-dashboard # Conflicts: # tasks/slack-daily-pr-dashboard.md
GitHub rejects the whole workflow file as malformed if the script
contains an unclosed ${{ sequence, which the local dry-run detection
did. Detect the unexpanded secret by its name instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The e2e run on today's (busy) PR list updated fine on post but failed on update: postMessage truncates long text, chat.update rejects it, and the fallback then posted a second message - the noise problem all over again. Chunk lines into 2900-char mrkdwn section blocks instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…shboard; #1452's #ci routing adopted by pointing the dashboard at #ci)
The full per-PR breakdown was huge in-channel on busy days. The channel message is now a one-line summary with counts; the breakdown lives in a single threaded reply, both updated in place (parent update passes blocks: [] since chat.update retains existing blocks otherwise). Channel moves from #building to #ci, adopting #1452's routing decision for merge announcements (merged from main; the old workflow it edited stays deleted). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5b1c341. Configure here.
| per_page: 100, | ||
| advanced_search: "true", | ||
| }); | ||
| return data.items; |
There was a problem hiding this comment.
Search capped at hundred results
Medium Severity
Each dashboard refresh loads PR lists via issuesAndPullRequests with per_page: 100 and returns only data.items, with no pagination or total_count check. When more than 100 PRs match a bucket (merged today, closed unmerged, opened today, or older open), the Slack summary counts and thread lists silently omit the rest.
Reviewed by Cursor Bugbot for commit 5b1c341. Configure here.
| const message = await slack.chat.postMessage({ channel, text: summaryText }); | ||
| if (!message.ts) throw new Error(`No ts in postMessage response`); | ||
| const detailsTs = await postDetailsInThread(message.ts); | ||
| await writeState({ date: today, channel, ts: message.ts, details_ts: detailsTs }); |
There was a problem hiding this comment.
Slack post before state save
Medium Severity
After posting or re-posting Slack messages, the workflow persists SLACK_PR_DASHBOARD_STATE only in writeState. If writeState fails after a successful postMessage, the job errors but Slack already has the new parent or thread reply while the variable still lacks the matching ts / details_ts. The next PR-triggered run treats the day as uninitialized or stale and can post another dashboard parent or thread reply for the same UTC day.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5b1c341. Configure here.



Replaces the
merge-to-main-slackworkflow (one Slack message per merged PR — noisy on busy days) with a workflow that maintains at most one message per day in#ci: a one-line PR dashboard summary, with the full per-PR breakdown in a single threaded reply. Both are created on the first PR event of the day and updated in place after that.Channel message:
Threaded reply (rendered from real data):
How it works:
SLACK_PR_DASHBOARD_STATE,{date, channel, ts, details_ts}), written with the sameITERATE_BOT_GITHUB_TOKENthe nag workflow uses. No new Slack scopes needed:chat.updateuses thechat:writethe bot already exercises.#ci, adopting [codex] Route merge announcements to ci #1452's decision to move merge announcements out of#building(that PR edited the workflow this one deletes; the conflict is resolved here by keeping the deletion).textparam: on busy days a single text field hitschat.update'smsg_too_long(postMessagetruncates,updaterejects — found by e2e-testing against today's ~50 merges).*pr-dashboard*branch runs it for real against#misha-testwith a separate state variable (create, update-in-place, and threading paths all verified this way — e.g. runs 27280068182, 27288814028), andnode cli.ts github-script pr-dashboard.update_dashboard.update_pr_dashboard --github-token ...does a local dry run that prints both messages.Task file:
tasks/slack-daily-pr-dashboard.md.🤖 Generated with Claude Code
Note
Low Risk
CI/Slack automation only; no app auth or production runtime changes, with test channel and dry-run paths.
Overview
Removes the per-merge Slack workflow and replaces it with a daily PR dashboard in
#ci: one parent message per UTC day with count-only summary, full lists in a single threaded reply, both updated in place on PR open/close/reopen/ready events.The new workflow queries GitHub search (merged, closed-unmerged, opened-today still open, older open PRs), maps authors via existing
slackUsers, and persists parent/threadtsin repo Actions variables (SLACK_PR_DASHBOARD_STATE) usingITERATE_BOT_GITHUB_TOKEN. Thread details use chunked mrkdwn blocks to avoidchat.updatemsg_too_long; concurrency group prevents double-posts. Branches matching*pr-dashboard*post to#misha-testfor e2e testing; localgithub-scriptdry-runs when the Slack secret is unexpanded.Adds
tasks/slack-daily-pr-dashboard.mddocumenting design and rollout.Reviewed by Cursor Bugbot for commit 5b1c341. Bugbot is set up for automated code reviews on this repo. Configure here.