Skip to content

Commit 7898dfc

Browse files
authored
Fix: Remove App Slug detection (#28)
Turns out the /app or /installation both uses JWT authentication rather than installation token. As such we cannot detect the app slug from inside the workflow, but delegate to the parent workflow. Added documentation for this use case
1 parent c9f0170 commit 7898dfc

File tree

2 files changed

+57
-44
lines changed

2 files changed

+57
-44
lines changed

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Based on the original work from [anthropics/claude-code-security-review](https:/
1616

1717
## Quick Start
1818

19+
### Basic Setup (Default GitHub Token)
20+
1921
Add this to your repository's `.github/workflows/code-review.yml`:
2022

2123
```yaml
@@ -51,6 +53,50 @@ jobs:
5153
require-label: 'READY TO REVIEW' # If this isn't set, the action will trigger any time *any* label is applied
5254
```
5355
56+
### GitHub App Setup (Recommended for Organizations)
57+
58+
For custom bot name/avatar and better mention detection:
59+
60+
```yaml
61+
name: Code Review
62+
63+
permissions:
64+
pull-requests: write
65+
contents: read
66+
67+
on:
68+
pull_request:
69+
types: [opened, synchronize, reopened, labeled, review_requested]
70+
issue_comment:
71+
types: [created]
72+
73+
jobs:
74+
review:
75+
runs-on: ubuntu-latest
76+
if: github.event_name == 'pull_request' || (github.event_name == 'issue_comment' && github.event.issue.pull_request)
77+
steps:
78+
- uses: actions/checkout@v4
79+
with:
80+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
81+
fetch-depth: 2
82+
83+
- name: Generate App Token
84+
id: app-token
85+
uses: actions/create-github-app-token@v1.9.0
86+
with:
87+
app-id: ${{ secrets.CODE_REVIEW_APP_ID }}
88+
private-key: ${{ secrets.CODE_REVIEW_APP_PRIVATE_KEY }}
89+
90+
- uses: PSPDFKit-labs/nutrient-code-review@main
91+
with:
92+
claude-api-key: ${{ secrets.CLAUDE_API_KEY }}
93+
app-slug: ${{ steps.app-token.outputs.app-slug }}
94+
env:
95+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
96+
```
97+
98+
**Note**: The `app-slug` parameter enables the bot to detect when it's mentioned in PR comments (e.g., `@my-code-review-app`). Requires `actions/create-github-app-token@v1.9.0` or later.
99+
54100
## Security Considerations
55101

56102
This action is not hardened against prompt injection attacks and should only be used to review trusted PRs. We recommend [configuring your repository](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#controlling-changes-from-forks-to-workflows-in-public-repositories) to use the "Require approval for all external contributors" option to ensure workflows only run after a maintainer has reviewed the PR.
@@ -79,6 +125,7 @@ This action is not hardened against prompt injection attacks and should only be
79125
| `custom-security-scan-instructions` | Path to custom security scan instructions text file to append to the security section | None | No |
80126
| `dismiss-stale-reviews` | Dismiss previous bot reviews when posting a new review (useful for follow-up commits) | `true` | No |
81127
| `skip-draft-prs` | Skip code review on draft pull requests | `true` | No |
128+
| `app-slug` | GitHub App slug for bot mention detection. If using `actions/create-github-app-token@v1.9.0+`, pass `${{ steps.app-token.outputs.app-slug }}`. Otherwise defaults to `github-actions`. | `github-actions` | No |
82129
| `require-label` | Only run review if this label is present. Leave empty to review all PRs. Add `labeled` to your workflow `pull_request` types to trigger on label addition. | None | No |
83130

84131
### Action Outputs

action.yml

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ inputs:
5959
required: false
6060
default: 'true'
6161

62+
app-slug:
63+
description: 'GitHub App slug for bot mentions (e.g., "my-code-review-app"). Defaults to "github-actions".'
64+
required: false
65+
default: 'github-actions'
66+
6267
require-label:
6368
description: 'Only run review if this label is present on the PR. Leave empty to review all PRs. To trigger on label addition, add "labeled" to your workflow pull_request types.'
6469
required: false
@@ -196,53 +201,14 @@ runs:
196201
restore-keys: |
197202
claudecode-${{ github.repository_id }}-pr-${{ github.event.pull_request.number || steps.pr-info.outputs.pr_number }}-
198203
199-
- name: Detect bot identity
200-
id: bot-identity
201-
shell: bash
202-
env:
203-
GH_TOKEN: ${{ env.GITHUB_TOKEN || github.token }}
204-
GITHUB_REPOSITORY: ${{ github.repository }}
205-
run: |
206-
# Get authenticated user (the bot making API calls)
207-
# Note: /user endpoint doesn't work with GitHub App tokens, so we try multiple methods
208-
BOT_LOGIN=""
209-
210-
# Method 1: Try /user endpoint (works for PATs, not GitHub App tokens)
211-
if [ -z "$BOT_LOGIN" ]; then
212-
if BOT_LOGIN_TMP=$(gh api user --jq '.login' 2>/dev/null); then
213-
BOT_LOGIN="$BOT_LOGIN_TMP"
214-
echo "Detected bot via /user endpoint: $BOT_LOGIN"
215-
fi
216-
fi
217-
218-
# Method 2: Try /app endpoint (works for GitHub App tokens)
219-
if [ -z "$BOT_LOGIN" ]; then
220-
if APP_DATA=$(gh api app 2>/dev/null); then
221-
APP_SLUG=$(echo "$APP_DATA" | jq -r '.slug // empty' 2>/dev/null)
222-
if [ -n "$APP_SLUG" ] && [ "$APP_SLUG" != "null" ]; then
223-
BOT_LOGIN="${APP_SLUG}[bot]"
224-
echo "Detected bot via /app endpoint: $BOT_LOGIN"
225-
fi
226-
fi
227-
fi
228-
229-
# Method 3: Fallback to default
230-
if [ -z "$BOT_LOGIN" ]; then
231-
BOT_LOGIN="github-actions"
232-
echo "Using default bot identity: $BOT_LOGIN"
233-
fi
234-
235-
echo "bot_login=$BOT_LOGIN" >> $GITHUB_OUTPUT
236-
echo "Detected bot identity: $BOT_LOGIN"
237-
238204
- name: Detect trigger type
239205
id: trigger-detection
240206
shell: bash
241207
env:
242208
EVENT_NAME: ${{ github.event_name }}
243209
EVENT_ACTION: ${{ github.event.action }}
244210
COMMENT_BODY: ${{ github.event.comment.body }}
245-
BOT_LOGIN: ${{ steps.bot-identity.outputs.bot_login }}
211+
APP_SLUG: ${{ inputs.app-slug }}
246212
run: |
247213
TRIGGER_TYPE="unknown"
248214
@@ -264,11 +230,11 @@ runs:
264230
elif [ "$EVENT_NAME" == "issue_comment" ]; then
265231
# Check if comment mentions this specific bot
266232
# Escape special regex characters in bot login to prevent regex injection
267-
if [ -n "$BOT_LOGIN" ]; then
268-
ESCAPED_BOT=$(printf '%s\n' "$BOT_LOGIN" | sed 's/[]\/$*.^[]/\\&/g')
233+
if [ -n "$APP_SLUG" ]; then
234+
ESCAPED_BOT=$(printf '%s\n' "$APP_SLUG" | sed 's/[]\/$*.^[]/\\&/g')
269235
if echo "$COMMENT_BODY" | grep -qE "@${ESCAPED_BOT}\\b"; then
270236
TRIGGER_TYPE="mention"
271-
echo "Detected mention of @$BOT_LOGIN in comment"
237+
echo "Detected mention of @$APP_SLUG in comment"
272238
fi
273239
fi
274240
fi
@@ -543,7 +509,7 @@ runs:
543509
GH_TOKEN: ${{ env.GITHUB_TOKEN || github.token }}
544510
GITHUB_REPOSITORY: ${{ github.repository }}
545511
PR_NUMBER: ${{ github.event.pull_request.number || steps.pr-info.outputs.pr_number }}
546-
BOT_LOGIN: ${{ steps.bot-identity.outputs.bot_login }}
512+
BOT_LOGIN: ${{ inputs.app-slug }}[bot]
547513
run: |
548514
# Request the bot as a reviewer to make it appear in the PR's reviewer list
549515
# This is optional and will fail silently if the bot is already a reviewer or doesn't have permissions

0 commit comments

Comments
 (0)