ci: add automatic PR labeling from linked issues#67
Conversation
When a PR references an issue (e.g., "fixes #42"), labels from that issue are automatically copied to the PR. Status and difficulty labels are excluded.
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughThis PR adds a GitHub Actions workflow that automatically labels pull requests based on referenced issues. When a PR opens, a script extracts the issue number from the PR description, fetches the issue's labels, filters out certain label types, and applies the remaining labels to the PR. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
chengwenxi
left a comment
There was a problem hiding this comment.
LGTM. Security posture is sound (pull_request not pull_request_target, scoped permissions). Label propagation logic is correct. Minor notes: only first issue link is processed, fetch-depth: 0 is unnecessary (shallow clone suffices).
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
.github/workflows/label-pr.yml (2)
15-16: Avoid full-history checkout for this workflow.
fetch-depth: 0is unnecessary here and slows runs. Default shallow checkout is enough for loading.github/assets/label_pr.js.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/label-pr.yml around lines 15 - 16, The workflow step currently sets fetch-depth: 0 which forces a full-history checkout and slows the run; remove the unnecessary "fetch-depth: 0" key (or change it to "fetch-depth: 1") from the checkout step so the default shallow checkout is used when loading .github/assets/label_pr.js — locate the checkout step that contains the "with:" block and update the fetch-depth setting accordingly.
5-5: Trigger coverage is too narrow for real PR editing flows.With only
opened, labels will not be applied if the issue reference is added later by editing the PR body. Consider includingedited(and optionallyreopened) to make behavior dependable.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/label-pr.yml at line 5, The GitHub Actions workflow trigger only listens for the pull_request event with types: [opened], which misses later edits to the PR body; update the pull_request trigger's types array (the types field in .github/workflows/label-pr.yml) to include "edited" (and optionally "reopened") alongside "opened" so label application runs when a PR is modified after creation; locate the types: [opened] entry in label-pr.yml and expand it to types: [opened, edited, reopened] (or at minimum add "edited") to ensure labels are applied on PR edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/assets/label_pr.js:
- Around line 61-64: The catch block in label_pr.js currently only logs errors
in the catch (err) { console.error("Failed to label PR"); console.error(err); }
which swallows failures; modify that catch to propagate the failure so the
workflow fails — either rethrow the error or set process.exitCode = 1 (or call
process.exit(1)) after logging. Locate the try/catch around the PR labeling
logic (the catch handling the label API call) and change it to log the error
then rethrow or set a non-zero exit code to ensure CI/workflow reports failure.
- Around line 15-22: The current regexes urlPattern and issuePattern are fragile
because they use a literal space and inject repoUrl unescaped; update both to
accept flexible whitespace (use \s+), allow optional URL schemes and optional
surrounding angle brackets, and escape repoUrl before interpolation (add a
helper like escapeRegExp to sanitize repoUrl) so special characters don't break
the RegExp; also consider using a case-insensitive non-capturing group for verbs
(e.g. (?:close|closes|fixes|resolved)) and anchor or word-boundary the issue
number capture (?<issue_number>\d+) to avoid unintended matches.
In @.github/workflows/label-pr.yml:
- Around line 10-12: Update the workflow permissions block to follow
least-privilege: remove the unnecessary pull-requests: write permission, keep
issues: write for the labels API usage, and add contents: read so the
actions/checkout step has explicit read access to the repository; adjust the
permissions stanza that currently lists issues and pull-requests and ensure
actions/checkout can operate with contents: read instead of granting broader
pull-requests scope.
---
Nitpick comments:
In @.github/workflows/label-pr.yml:
- Around line 15-16: The workflow step currently sets fetch-depth: 0 which
forces a full-history checkout and slows the run; remove the unnecessary
"fetch-depth: 0" key (or change it to "fetch-depth: 1") from the checkout step
so the default shallow checkout is used when loading .github/assets/label_pr.js
— locate the checkout step that contains the "with:" block and update the
fetch-depth setting accordingly.
- Line 5: The GitHub Actions workflow trigger only listens for the pull_request
event with types: [opened], which misses later edits to the PR body; update the
pull_request trigger's types array (the types field in
.github/workflows/label-pr.yml) to include "edited" (and optionally "reopened")
alongside "opened" so label application runs when a PR is modified after
creation; locate the types: [opened] entry in label-pr.yml and expand it to
types: [opened, edited, reopened] (or at minimum add "edited") to ensure labels
are applied on PR edits.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: a8f5ca5b-1e11-431b-8184-e2dcb5d79128
📒 Files selected for processing (2)
.github/assets/label_pr.js.github/workflows/label-pr.yml
| const urlPattern = new RegExp( | ||
| `(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) ${repoUrl}/issues/(?<issue_number>\\d+)`, | ||
| "i" | ||
| ); | ||
| const issuePattern = new RegExp( | ||
| `(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) #(?<issue_number>\\d+)`, | ||
| "i" | ||
| ); |
There was a problem hiding this comment.
Make issue-link regex more robust to formatting and URL matching.
Current patterns are fragile (single literal space) and repoUrl is injected unescaped into a regex. This can miss references in common PR body formatting and allow unintended matches.
💡 Proposed hardening
function getIssueLink(repoUrl, body) {
if (!body) return undefined;
+ const escapedRepoUrl = repoUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const urlPattern = new RegExp(
- `(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) ${repoUrl}/issues/(?<issue_number>\\d+)`,
+ `\\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\b\\s+${escapedRepoUrl}/issues/(?<issue_number>\\d+)\\b`,
"i"
);
const issuePattern = new RegExp(
- `(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) #(?<issue_number>\\d+)`,
+ `\\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\b\\s+#(?<issue_number>\\d+)\\b`,
"i"
);📝 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.
| const urlPattern = new RegExp( | |
| `(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) ${repoUrl}/issues/(?<issue_number>\\d+)`, | |
| "i" | |
| ); | |
| const issuePattern = new RegExp( | |
| `(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) #(?<issue_number>\\d+)`, | |
| "i" | |
| ); | |
| const escapedRepoUrl = repoUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | |
| const urlPattern = new RegExp( | |
| `\\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\b\\s+${escapedRepoUrl}/issues/(?<issue_number>\\d+)\\b`, | |
| "i" | |
| ); | |
| const issuePattern = new RegExp( | |
| `\\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\b\\s+#(?<issue_number>\\d+)\\b`, | |
| "i" | |
| ); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/assets/label_pr.js around lines 15 - 22, The current regexes
urlPattern and issuePattern are fragile because they use a literal space and
inject repoUrl unescaped; update both to accept flexible whitespace (use \s+),
allow optional URL schemes and optional surrounding angle brackets, and escape
repoUrl before interpolation (add a helper like escapeRegExp to sanitize
repoUrl) so special characters don't break the RegExp; also consider using a
case-insensitive non-capturing group for verbs (e.g.
(?:close|closes|fixes|resolved)) and anchor or word-boundary the issue number
capture (?<issue_number>\d+) to avoid unintended matches.
| } catch (err) { | ||
| console.error("Failed to label PR"); | ||
| console.error(err); | ||
| } |
There was a problem hiding this comment.
Do not swallow labeling failures silently.
Line 61-Line 64 only logs errors. If GitHub API calls fail, the workflow still appears successful and masking this breaks reliability of auto-labeling.
✅ Suggested fix
} catch (err) {
console.error("Failed to label PR");
console.error(err);
+ throw err;
}
};📝 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.
| } catch (err) { | |
| console.error("Failed to label PR"); | |
| console.error(err); | |
| } | |
| } catch (err) { | |
| console.error("Failed to label PR"); | |
| console.error(err); | |
| throw err; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/assets/label_pr.js around lines 61 - 64, The catch block in
label_pr.js currently only logs errors in the catch (err) {
console.error("Failed to label PR"); console.error(err); } which swallows
failures; modify that catch to propagate the failure so the workflow fails —
either rethrow the error or set process.exitCode = 1 (or call process.exit(1))
after logging. Locate the try/catch around the PR labeling logic (the catch
handling the label API call) and change it to log the error then rethrow or set
a non-zero exit code to ensure CI/workflow reports failure.
| permissions: | ||
| issues: write | ||
| pull-requests: write |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find .github/workflows -name "*label-pr*" -type fRepository: morph-l2/morph-reth
Length of output: 93
🏁 Script executed:
cat -n .github/workflows/label-pr.ymlRepository: morph-l2/morph-reth
Length of output: 688
🏁 Script executed:
cat -n .github/assets/label_pr.jsRepository: morph-l2/morph-reth
Length of output: 2433
🌐 Web query:
GitHub Actions pull-requests write permission required addLabels
💡 Result:
Yes, GitHub Actions workflows require pull-requests: write permission to add labels to pull requests using the GITHUB_TOKEN. To add labels to a pull request (via the Issues API endpoint POST /repos/{owner}/{repo}/issues/{issue_number}/labels, since PRs are issues), declare the permission in your workflow YAML: permissions: pull-requests: write Example workflow step using gh pr edit or REST API: - name: Add label to PR run: gh pr edit ${{ github.event.pull_request.number }} --add-label "your-label" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} This grants the GITHUB_TOKEN write access for pull requests. For labeler actions or creating new labels (if they don't exist), issues: write may also be needed alongside pull-requests: write, as PRs leverage the Issues API internally. Official examples in GitHub Docs use issues: write for issue labeling (applicable to PRs), but pull-requests: write is standard and sufficient for adding existing labels to PRs per actions/labeler documentation and community usage. For forked PRs, use pull_request_target trigger with explicit permissions for write access.
Citations:
- 1: Warn about the limitations of GitHub tokens actions/labeler#491
- 2: Labeler not triggering 'labeled' pull_request event type actions/labeler#315
- 3: HttpError: You do not have permission to create labels on this repository actions/labeler#870
- 4: Fails to create label when action runs googleapis/release-please-action#1105
- 5: https://github.com/actions/labeler
- 6: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions
- 7: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
- 8: https://docs.github.com/en/actions/use-cases-and-examples/project-management/adding-labels-to-issues
- 9: https://docs.github.com/en/rest/issues/labels
🌐 Web query:
GitHub API issues.addLabels pull request permission requirements
💡 Result:
The GitHub REST API endpoint for adding labels to issues or pull requests is POST /repos/{owner}/{repo}/issues/{issue_number}/labels. Pull requests use the issues endpoints since every pull request is an issue. Permissions required: - For fine-grained personal access tokens (PATs): issues:write or pull-requests:write permission. - For GitHub Apps: issues:write or pull-requests:write permission. - For classic PATs: repo scope (provides push access to the repository). - Users must have write (push) access to the repository. Without sufficient permissions, label changes are silently dropped or the request fails with 403/404. In GitHub Actions, use permissions: { issues: write } or { pull-requests: write }.
Citations:
- 1: https://docs.github.com/en/rest/issues/labels
- 2: https://docs.github.com/rest/issues/labels
- 3: https://docs.github.com/en/actions/use-cases-and-examples/project-management/adding-labels-to-issues
- 4: "Add labels to an issue" doc refers to
pull_requests:writepermission, but should bepull-requests:writegithub/docs#32167 - 5: https://docs.github.com/en/rest/issues/issues
- 6: https://docs.github.com/rest/authentication/authenticating-to-the-rest-api
- 7: https://docs.github.com/en/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens
- 8: https://docs.github.com/rest/overview/permissions-required-for-github-apps
Tighten job token scope to least privilege.
This job labels pull requests via the Issues API; pull-requests: write is redundant since the label operation uses issues.addLabels(). Keep issues: write and add explicit contents: read for the checkout action.
🔐 Suggested permissions block
permissions:
+ contents: read
issues: write
- pull-requests: write📝 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.
| permissions: | |
| issues: write | |
| pull-requests: write | |
| permissions: | |
| contents: read | |
| issues: write |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/label-pr.yml around lines 10 - 12, Update the workflow
permissions block to follow least-privilege: remove the unnecessary
pull-requests: write permission, keep issues: write for the labels API usage,
and add contents: read so the actions/checkout step has explicit read access to
the repository; adjust the permissions stanza that currently lists issues and
pull-requests and ensure actions/checkout can operate with contents: read
instead of granting broader pull-requests scope.
Summary
label-pr.ymlworkflow and.github/assets/label_pr.jsscriptS-*), difficulty (D-*), andM-prevent-stalelabels are excludedTest plan
Summary by CodeRabbit
Release Notes