Skip to content

feat(stale): reusable stale-PR workflow + name the repo in the Slack digest (BE-2776)#26

Merged
mattmillerai merged 3 commits into
mainfrom
matt/be-2776-stale-reusable
Jul 21, 2026
Merged

feat(stale): reusable stale-PR workflow + name the repo in the Slack digest (BE-2776)#26
mattmillerai merged 3 commits into
mainfrom
matt/be-2776-stale-reusable

Conversation

@mattmillerai

Copy link
Copy Markdown
Contributor

ELI-5

Two repos (cloud and comfy-infra) each had their own copy of the same "stale PR bot" workflow, and both post to the same Slack channel. Their digests looked identical — a bare #158 doesn't say which repo it's from, so the two batches were impossible to tell apart. This adds one shared reusable version of that workflow to this repo (so there's no more copy-paste drift), and makes the Slack header name the source repo so each batch is unambiguous.

What this PR does

  • Adds .github/workflows/stale.yml as a reusable (on: workflow_call). It ports the existing actions/stale + Slack chat.postMessage logic verbatim, parameterizing what differs per repo:
    • slack_channel (default C08V9NDB3B4), days_before_pr_stale/days_before_pr_close, stale_pr_message/close_pr_message, stale_pr_label, exempt_pr_labels, and a dry_run pass-through. SLACK_BOT_TOKEN is passed via secrets: (optional — the sweep still runs without it).
    • The caller owns the schedule + workflow_dispatch dry-run toggle (a reusable can't declare those triggers); the header documents the caller pattern.
  • Names the repo in the digest header (*Stale PR bot — <owner/repo>*) so two repos' batches in the same channel are distinguishable. Per-PR link lines are unchanged — they already resolve via github.repository.
  • Updates the README workflows table.

actionlint (+ shellcheck on the inline script) is clean.

Follow-ups (must land after this merges)

Per the "land the reusable first, then flip callers" sequencing (a caller referencing a not-yet-merged path fails), these are separate PRs in their own repos, pinned to this PR's merge SHA:

  1. Replace Comfy-Org/cloud/.github/workflows/stale.yml with a thin caller.
  2. Replace Comfy-Org/comfy-infra/.github/workflows/stale.yml with a thin caller.
  3. Optionally add a bump-stale-callers.yml dispatcher (mirroring bump-cursor-review-callers.yml) to keep those callers pinned — deferred because the callers don't exist yet.
  4. Confirm whether any other repo carries the same PR+Slack-digest stale bot (org search shows only cloud + comfy-infra match; the various stale-issues.yml are a different issue-triage bot, out of scope).

Judgment calls

  • exempt_pr_labels default is cloud's superset (includes do-not-merge); comfy-infra's current copy omits it. Broadening to exempt do-not-merge is arguably an improvement (don't nag/close a deliberately-held PR), but the comfy-infra caller can override the input to its exact prior set if desired.
  • The "auto-closes in N days" text now interpolates days_before_pr_close instead of a hardcoded "14"; the closed-digest line drops the "(~4 weeks inactive)" parenthetical since it was only accurate at the default 14/14 thresholds.

…ack digest (BE-2776)

Consolidates the per-repo stale-PR sweeper (duplicated in cloud + comfy-infra)
into one reusable workflow, and names the source repo in the Slack digest
header so batches from different repos posted to the same channel are no longer
ambiguous ("#158" alone could be any repo).

Ports the actions/stale + chat.postMessage logic verbatim, parameterizing what
differs per repo (Slack channel, stale/close thresholds, messages, exempt
labels) as inputs, with SLACK_BOT_TOKEN passed through secrets.
@mattmillerai mattmillerai added the cursor-review Multi-model cursor review label Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d1b798ed-f37b-41c8-b693-30641bfdc45b

📥 Commits

Reviewing files that changed from the base of the PR and between b47ac21 and e75e2f2.

📒 Files selected for processing (2)
  • .github/workflows/stale.yml
  • README.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matt/be-2776-stale-reusable
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch matt/be-2776-stale-reusable

Comment @coderabbitai help to get the list of available commands.

@mattmillerai mattmillerai added the agent-coded Authored by the agent-work loop label Jul 9, 2026
@mattmillerai mattmillerai added cursor-review Multi-model cursor review and removed cursor-review Multi-model cursor review labels Jul 21, 2026

@github-actions github-actions 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.

🔍 Cursor Review — Consolidated panel

Triggered by @mattmillerai.

Found 6 finding(s).

Severity Count
🟠 High 1
🟡 Medium 2
🟢 Low 3

Panel: 6/8 reviewers contributed findings.

Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)

Comment thread .github/workflows/stale.yml Outdated
Comment thread .github/workflows/stale.yml
Comment thread .github/workflows/stale.yml Outdated
Comment thread .github/workflows/stale.yml Outdated
Comment thread .github/workflows/stale.yml Outdated
Comment thread .github/workflows/stale.yml Outdated
Address cursor-review panel findings on the reusable stale-PR workflow:

- Escape Slack mrkdwn control chars (& < >) in interpolated PR titles so a
  crafted title can't inject <!channel>/<!here> pings or masked <url|label>
  phishing links (High).
- Skip the Slack post entirely when SLACK_BOT_TOKEN is unset instead of
  firing a curl with an empty Bearer header that still ships repo name + PR
  titles to Slack's API; honors the secret's documented optional contract
  (Medium).
- Reword default stale/close messages to drop hardcoded day counts and the
  label name so they stay correct when a caller overrides days_before_pr_* or
  stale_pr_label without also overriding the messages (Medium).
- Add curl --connect-timeout/--max-time and a job timeout-minutes so a
  stalled Slack endpoint can't hang the runner (Low).
- Suppress the "auto-closes in N days" line when days_before_pr_close <= 0
  (actions/stale's never-close sentinel), which otherwise read "-1 days" (Low).
- Capture curl HTTP status so a transport/non-JSON failure yields a real
  reason instead of an empty "Slack notification failed:" warning (Low).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mattmillerai
mattmillerai merged commit f645e69 into main Jul 21, 2026
2 of 3 checks passed
@mattmillerai
mattmillerai deleted the matt/be-2776-stale-reusable branch July 21, 2026 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-coded Authored by the agent-work loop cursor-review Multi-model cursor review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants