This GitHub Action sends a friendly Slack reminder about open Pull Requests. The Slack message contains a list of PRs with (optional) highlighting for the old ones.
You may not need this action; GitHub provides built-in scheduled reminders for teams which works well in many situations.
When to use GitHub's built-in reminders:
- Your team structure aligns well with GitHub teams
- The CODEOWNERS files of your repositories accurately match your team structure (-> reviews are automatically requested from the right people)
- You're okay with the 5 repository limit per reminder
- You don't need custom message content or formatting
- You don't need different filtering options for each repository
- You prefer a GUI (github.com) for setting up the reminders (as opposed to YAML)
What's special about this action:
- Monitor up to 30 repositories
- Option to "refresh" the latest PR reminder when PRs get reviewed or merged (with run-mode:
update) - Highlight old PRs that need attention (with optional age threshold input)
- Concise review status info for each PR with emojis (incl. approvers & commenters)
- More customizable message content
- Global and repository specific filters
- Anyone can set this up (no need to be a GitHub team maintainer)
- No need for official GitHub team setup
- No need for perfect CODEOWNERS files to get reminded about the right PRs
- Slack bot token with permissions to post messages
- GitHub token with read access to your repositories
This monitors open PRs in your current repository.
name: PR Reminder
on:
schedule:
- cron: "0 9 * * MON-FRI" # 9 AM on weekdays
jobs:
remind:
runs-on: ubuntu-latest
steps:
- uses: hellej/pr-slack-reminder-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
slack-channel-name: "dev-team"Monitor several repositories with user mentions, filters and custom messaging.
name: PR Reminder
on:
schedule:
- cron: "0 9 * * MON-FRI" # 9 AM on weekdays
jobs:
remind:
runs-on: ubuntu-latest
steps:
- uses: hellej/pr-slack-reminder-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
slack-channel-name: "code-reviews"
github-repositories: |
myorg/frontend
myorg/backend
myorg/mobile-app
github-user-slack-user-id-mapping: |
alice: U1234567890
kronk: U2345678901
charlie: U3456789012
pr-list-heading: "We have <pr_count> PRs waiting for review! π"
no-prs-message: "π All caught up! No PRs waiting for review."
old-pr-threshold-hours: 48
filters: |
{
"ignored-labels": ["draft", "wip"],
"ignored-authors": ["dependabot[bot]"]
}
repository-filters: |
backend: {"labels": ["ready-for-review"], "ignored-authors": ["intern-bot"]}
mobile-app: {}(^ PRs from mobile-app repo won't be filtered by the global filters)
Setup where the latest message is also updated when PRs get reviewed/merged. PRs that were merged since the original message are shown with π emoji suffix. However, the updated message will not contain new PRs published since the original message.
Example:
name: PR Reminder
on:
schedule:
- cron: "0 9 * * MON-FRI" # 9 AM on weekdays
push:
branches: [main]
pull_request:
types: [closed, ready_for_review]
pull_request_review:
types: [submitted]
issue_comment:
jobs:
send-or-update-pr-reminder:
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
steps:
- uses: hellej/pr-slack-reminder-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
slack-channel-name: "dev-team"
run-mode: ${{ github.event_name == 'schedule' && 'post' || 'update' }}
- uses: actions/upload-artifact@v7
with:
name: pr-slack-reminder-state
path: pr-slack-reminder-state.json
retention-days: 1| Name | Required | Description |
|---|---|---|
slack-bot-token |
β | Slack bot token for sending messages Example: ${{ secrets.SLACK_BOT_TOKEN }} |
github-token |
β | GitHub token for repository access Example: ${{ secrets.GITHUB_TOKEN }} |
github-token-for-state |
β | GitHub token that has read access to artifacts of the current repository (i.e. actions: read). Only needed if the run-mode is update and if the default github-token misses permissions. |
run-mode |
β | Run mode: post (default) posts a new reminder; update refreshes an existing reminder |
state-artifact-name |
β | Name of the artifact containing state from previous run (used when run-mode is update)Default: pr-slack-reminder-state |
slack-channel-name |
β | Slack channel name (use this OR slack-channel-id) |
slack-channel-id |
β | Slack channel ID (use this OR slack-channel-name)Example: C1234567890 |
github-repositories |
β | Repositories to monitor (max 30) - defaults to current repo Example: owner/repo1owner/repo2 |
filters |
β | Global filters (JSON) Example: {"authors": ["alice"], "ignored-labels": ["wip"]} |
repository-filters |
β | Repository-specific filters Example: repo1: {"labels": ["bug"]}repo2: {"ignored-authors": ["bot"]} |
github-user-slack-user-id-mapping |
β | Map of GitHub usernames to Slack user IDs Example: alice: U1234567890kronk: U2345678901 |
pr-list-heading |
β | Message heading (<pr_count> gets replaced)Default: There are <pr_count> open PRs π |
no-prs-message |
β | Message when no PRs are found (if not set, no empty message gets sent) Example: All caught up! π |
old-pr-threshold-hours |
β | PR age in hours after which a PR is highlighted as old with alarm emoji and bold age text (defaults to 96) |
group-by-repository |
β | Group PRs by repository with repository headings (defaults to false). When enabled, pr-list-heading is ignored. |
Both filters and repository-filters support:
authors- Only include PRs by these usersignored-authors- Exclude PRs by these userslabels- Only include PRs with these labelsignored-labels- Exclude PRs with these (overrides the above)ignored-terms- Exclude PRs whose title contains any of these terms
authors and ignored-authors in the same filter.
For monitoring just your current repository, the default GITHUB_TOKEN (available automatically) works perfectly:
github-token: ${{ secrets.GITHUB_TOKEN }}For better security and granular permissions, especially when monitoring multiple repositories, using a GitHub App is the recommended approach.
- Create a GitHub App in your organization or personal account settings.
- Give it necessary permissions (e.g., "read" access to PRs).
- Install the app on the repositories you want to monitor. During installation, you can choose to grant access to all repositories (of your organization) or only to specific ones. For better security, it's recommended to select only the repositories you intend to monitor.
- Add the App ID and Private Key as secrets in the repository where your workflow runs.
- Use a token generation action (like
actions/create-github-app-token) in your workflow to generate a temporary token.
Here is an example of how to implement it in your workflow:
name: PR Reminder
on:
schedule:
- cron: "0 9 * * MON-FRI"
jobs:
remind:
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Send PR Reminder
uses: hellej/pr-slack-reminder-action@v1
with:
github-token: ${{ steps.generate-token.outputs.token }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
slack-channel-name: "dev-team"
github-repositories: |
my-org/repo1
my-org/repo2To monitor multiple repositories, you may also use a Personal Access Token (PAT):
- Go to GitHub Settings β Developer settings β Personal access tokens β Fine-grained tokens
- Click "Generate new token" β Select the repositories of interest and at least read access to PRs
- Add the token as a repository secret named
PR_REMINDER_GITHUB_TOKEN - Use it in your workflow:
github-token: ${{ secrets.PR_REMINDER_GITHUB_TOKEN }}
- Test with
workflow_dispatch: Allow manual testing for your workflow - Use cron scheduling: Run reminders at times that work for your team (avoid weekends!)
- Customize messages: Make the reminders fit your team's culture
- Highlight old PRs: Set a reasonable
old-pr-threshold-hoursto highlight stale PRs (consider weekends too)
Found a bug or have a feature request? We'd love your help! Feel free to open an issue.
This project is licensed under the MIT License - see the LICENSE file for details.

