Skip to content

ci: add PR hygiene — UNREVIEWED label + Slack review reminders - #12

Open
severindemchuk wants to merge 3 commits into
masterfrom
pr-hygiene
Open

ci: add PR hygiene — UNREVIEWED label + Slack review reminders#12
severindemchuk wants to merge 3 commits into
masterfrom
pr-hygiene

Conversation

@severindemchuk

@severindemchuk severindemchuk commented Jul 13, 2026

Copy link
Copy Markdown

Summary

  • New PRs (org-wide, once repos adopt templates/pr-label.yml) get the UNREVIEWED label automatically. Reviewers remove it manually after reviewing — that removal is the "reviewed" acknowledgment, automation never touches it again.
  • A weekday-morning cron (pr-reminder.yml) DMs requested reviewers (or the author, if none requested) on Slack about PRs still carrying the label. Nag 1 the next weekday, daily, hard stop after 3.
  • Dogfooding: this repo's own pr-label.yml should label this very PR.

Config needed before the reminder cron can run for real (see follow-up)

  • Actions vars: GH_SLACK_MAP, PR_HYGIENE_DRY_RUN, PR_HYGIENE_ALLOWLIST
  • Secrets: PR_BOT_PAT, SLACK_BOT_TOKEN

Test plan

  • scripts/pr_reminder.py unit tests (kept local for now, not part of this diff)
  • Live dry-run against the org (read-only) — correctly found and evaluated existing UNREVIEWED PRs
  • This PR should get the UNREVIEWED label automatically on open
  • Manually removing the label should stick (nothing re-adds it)

🤖 Generated with Claude Code

New PRs get the UNREVIEWED label via a reusable workflow (consumers copy
templates/pr-label.yml); reviewers remove it manually after reviewing.
A weekday-morning cron DMs reviewers/authors on Slack about PRs still
carrying the label (nag 1-3, then silent). Dry-run and allowlist phases
via Actions variables; PAT now, GitHub App swap planned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings July 13, 2026 07:52
@github-actions github-actions Bot added the UNREVIEWED No review yet — remove this label after reviewing label Jul 13, 2026

Copilot AI 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.

Pull request overview

Adds organization-wide PR hygiene automation by applying an UNREVIEWED label to new PRs and sending weekday Slack DM reminders until the label is manually removed.

Changes:

  • Introduces a reusable workflow (plus template + local “dogfooding” workflow) to label PRs as UNREVIEWED on open/reopen.
  • Adds a scheduled GitHub Actions workflow that runs a Python script to find UNREVIEWED PRs and DM the appropriate people on Slack.
  • Adds a Slack app manifest to document required Slack bot setup/scopes.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
templates/pr-label.yml Template workflow to apply UNREVIEWED label in adopting repos
scripts/pr_reminder.py Implements GitHub search + nag calculation + Slack DM sending
docs/slack-app-manifest.yml Documents Slack app configuration/scopes for the reminder bot
.github/workflows/reusable-pr-label.yml Reusable workflow that ensures the label exists and applies it
.github/workflows/pr-reminder.yml Cron/dispatch workflow wiring env/secrets and running the reminder script
.github/workflows/pr-label.yml Dogfooding workflow to label PRs in this repo

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

Comment thread .github/workflows/pr-reminder.yml
Comment thread .github/workflows/pr-reminder.yml
Comment thread .github/workflows/pr-reminder.yml
Comment thread templates/pr-label.yml
Comment thread .github/workflows/pr-label.yml
Comment thread scripts/pr_reminder.py Outdated
Comment thread scripts/pr_reminder.py Outdated
- pr-reminder.yml declared explicit permissions, which zeroes out any
  unlisted scope — actions/checkout needs contents: read to work.
- pr_reminder.py: bound GitHub/Slack urlopen() calls with a timeout so a
  hung connection can't stall the whole workflow run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 13, 2026 08:20

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

name: PR label
on:
pull_request:
types: [opened, reopened]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ist es vermutlich einfacher, als erst beim Merge das Label hinzuzufügen. Dann aber bitte auch das Label automatisch entfernen, wenn der PR approved wird: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request_review

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das war bewusst so entschieden, dass das entfernen vom Label impliziert das man fertig ist mit dem Review. Ausserdem kann man gemergte PRs nicht mehr approven nur kommentieren.

env:
GH_TOKEN: ${{ github.token }}
run: |
gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warum ist das issues? Unterscheidet die REST API nicht zwischen issues und PRs?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> GitHub's REST API has no PR-specific labels endpoint — labels only live under /issues/{number}/labels since a PR is an issue under the hood (gh pr edit --add-label hits the same endpoint internally). So issues here is required, not a mix-up.

GH_TOKEN: ${{ github.token }}
run: |
gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels" \
-f "labels[]=UNREVIEWED"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Werden so alle bestehenden Labels überschrieben? Oder ist das ein append?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ist ein append, kein replace

Comment thread templates/pr-label.yml

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich denke es reicht, wenn man es aus .github/actions kopieren kann. Sonst geraten die Files früher oder später out of sync.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aus welchem .github/actions meinst du?

Comment thread scripts/pr_reminder.py Outdated
Comment thread scripts/pr_reminder.py Outdated
Comment thread scripts/pr_reminder.py Outdated
…rity

Laila's PR #12 review feedback: search query dropped is:open only, missing
merged-but-unreviewed PRs (e.g. hotfixes reviewed after the fact) — now
matches is:merged OR is:open. Cadence changed from daily/capped-at-3 to
weekly/uncapped, since the goal is "don't forget entirely" not urgency
escalation. pr_targets() now checks assignees first — reassigning a PR to
the author after requesting changes should stop notifying the reviewer,
since requested_reviewers isn't cleared by submitting a review.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 21, 2026 12:26

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

UNREVIEWED No review yet — remove this label after reviewing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants