Skip to content

feat(pr-digest): reusable workflow for AI-curated PR Slack digest#293

Merged
gabrielanhaia merged 3 commits into
mainfrom
feat/pr-digest-reusable
May 29, 2026
Merged

feat(pr-digest): reusable workflow for AI-curated PR Slack digest#293
gabrielanhaia merged 3 commits into
mainfrom
feat/pr-digest-reusable

Conversation

@gabrielanhaia
Copy link
Copy Markdown
Member

What?

Adds a new reusable workflow at .github/workflows/pr-digest.yml that any Monta repo can call to post a daily Slack digest of its open pull requests. Updates README.md and docs/workflow-guide.md with usage examples.

The message is AI-curated by default: a compact JSON of open-PR metadata is sent to Claude, which produces a 1–2 sentence headline plus up to N focus PRs with one-line "why this matters" notes. The deterministic Block Kit builder then renders the full Slack message — header counts, AI headline, today's focus, critical PRs, area summary, deep links. A threaded reply carries the full per-area breakdown so the channel stays scannable at high volume.

Caller-tunable via inputs: slack-channel-id, stale-threshold-days (2), critical-threshold-days (7), max-prs-to-surface (5), use-ai-curation (true), model (claude-sonnet-4-7), post-thread-breakdown (true), empty-state (silent), include-drafts (false), exclude-authors, title.

Secrets: SLACK_APP_TOKEN (existing org/repo secret used by ~20 deploy workflows) and ANTHROPIC_API_KEY (only when AI curation is enabled — falls back gracefully if missing or the call fails).

Why?

Built for high-volume repos like monorepo-typescript (100+ open PRs). A flat list of every open PR is unreadable and hits Slack's 50-block ceiling; a smart curated view ("here are the 5 things to act on today, by area") is the only thing that scales. Designed to be reusable so any other repo can adopt the same digest with a ~20-line caller workflow.

Complements the existing automation-stale-prs.yml housekeeper (which closes PRs after 14 days of inactivity) by surfacing them to the team early.

Context

Consumer workflow lands in parallel: https://github.com/monta-app/monorepo-typescript/pull/new/feat/NOJIRA/pr-digest

That PR must wait for this one to merge — it references monta-app/github-workflows/.github/workflows/pr-digest.yml@main.

A new reusable workflow that posts a daily Slack digest of open pull
requests in the calling repository. Designed for high-volume repos
(100+ open PRs) — uses Claude to surface a focused triage view (today's
focus, critical PRs, area summary) instead of a flat list. Falls back
to deterministic oldest-first surfacing if the AI step fails or is
disabled.

Includes README and workflow-guide entries with caller examples for
both high-volume (AI on) and low-volume (flat list) usage.
@gabrielanhaia gabrielanhaia self-assigned this May 29, 2026
@gabrielanhaia gabrielanhaia marked this pull request as ready for review May 29, 2026 18:18
@gabrielanhaia gabrielanhaia requested a review from a team as a code owner May 29, 2026 18:18
@gabrielanhaia gabrielanhaia requested review from Copilot and sudheer-monta and removed request for a team May 29, 2026 18:18
Copy link
Copy Markdown

Copilot AI left a comment

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 new reusable workflow .github/workflows/pr-digest.yml that posts a daily Slack digest of open PRs for a calling repository, with optional Claude-powered curation, deterministic fallback, and an in-thread per-area breakdown. README and the workflow guide are updated with usage examples and a full reference.

Changes:

  • New reusable workflow_call workflow that fetches open PRs via gh, enriches/buckets them with jq, optionally calls Anthropic for headline + focus selection, and posts a Slack Block Kit message (plus optional thread reply) via chat.postMessage.
  • README entry and a new "PR Digest" section in docs/workflow-guide.md with inputs, secrets, behaviour notes, and two example caller workflows.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
.github/workflows/pr-digest.yml New reusable workflow implementing PR fetch, filtering, AI curation, Slack message build, and threaded breakdown post.
README.md Lists the new workflow and adds two caller examples plus prerequisites.
docs/workflow-guide.md Adds a full PR Digest reference section (inputs, secrets, permissions, behaviour, examples, manual testing).

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

Comment thread .github/workflows/pr-digest.yml
Comment thread .github/workflows/pr-digest.yml Outdated
Comment thread .github/workflows/pr-digest.yml Outdated
Comment thread docs/workflow-guide.md
Comment thread .github/workflows/pr-digest.yml Outdated
- Fix --slurpfile crash when AI step is skipped: write empty fallback
  /tmp/ai.json before the build-step jq invocation. Previously, with
  use-ai-curation=false or missing ANTHROPIC_API_KEY, the build step
  would abort with 'Could not open file /tmp/ai.json'.
- Switch runs-on from ubuntu-latest to linux-arm64 to match the
  established convention across deploy-*.yml, pull-request*.yml,
  semgrep-security-scan.yml, etc.
- Default model: claude-sonnet-4-7 -> claude-sonnet-4-6. The 4-7 ID
  is not a valid Sonnet alias on the Anthropic API (it's an Opus
  identifier); the default would have 404'd and silently fallen
  back to deterministic curation every run.
- Slack title escaping: replace gsub('[<>&]'; ' ') with HTML-entity
  escaping ('&amp;', '&lt;', '&gt;'). Stripping mangled legitimate
  characters in titles like 'Bump foo from <2.0 to >=2.1'.
- Docs: clarify that pr-digest.yml only supports workflow_call;
  manual testing happens via the caller workflow which declares
  workflow_dispatch itself.
@gabrielanhaia
Copy link
Copy Markdown
Member Author

Thanks @copilot — all five points are valid. Addressed in f97d7ff:

# Comment Fix
1 --slurpfile /tmp/ai.json crashes when AI step is skipped Write empty fallback {"headline":"","focus":[]} to /tmp/ai.json in the build step before calling jq.
2 runs-on: ubuntu-latest deviates from repo convention Switched to linux-arm64.
3 Default model claude-sonnet-4-7 doesn't exist on Anthropic API Verified via Anthropic model docs — current Sonnet alias is claude-sonnet-4-6. Updated both the input default and the docs example. (4-7 is an Opus identifier, not Sonnet — my mistake.) Also updated the consumer caller in monta-app/monorepo-typescript#3535 to drop the now-obsolete model: override.
4 Docs claim workflow_dispatch works on the reusable workflow Rewrote "Manual testing" to make clear pr-digest.yml only declares workflow_call; manual testing happens via the caller workflow (which both example callers in the doc declare workflow_dispatch themselves).
5 gsub("[<>&]"; " ") mangles legitimate PR titles Switched to HTML-entity escaping (&amp;, &lt;, &gt;) in both the main-message and thread-breakdown builders, ordered to avoid double-escaping.

Resolving the threads.

@gabrielanhaia gabrielanhaia merged commit 4faf3e5 into main May 29, 2026
2 checks passed
@gabrielanhaia gabrielanhaia deleted the feat/pr-digest-reusable branch May 29, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants