-
Notifications
You must be signed in to change notification settings - Fork 0
feat(repo): add GitHub Actions workflow to validate PR titles #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| name: PR Title Validation | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, edited, synchronize, reopened] | ||
| pull_request_target: | ||
| types: [opened, edited, synchronize, reopened] | ||
|
|
||
| jobs: | ||
| validate-pr-title: | ||
| if: ${{ github.repository_owner == 'nrwl' }} | ||
| name: Validate PR Title | ||
| runs-on: ubuntu-latest | ||
|
Comment on lines
+9
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
file=".github/workflows/pr-title-validation.yml"
printf '%s\n' '--- workflow ---'
cat -n "$file"
printf '%s\n' '--- permission and checkout references ---'
rg -n '^\s*permissions:|^\s+(contents|actions|pull-requests|statuses|checks):|actions/checkout|github\.token|gh |curl |git push|git commit' "$file" || true
printf '%s\n' '--- bounded structural check ---'
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/pr-title-validation.yml")
text = p.read_text()
lines = text.splitlines()
permissions = [i + 1 for i, line in enumerate(lines) if line.strip() == "permissions:"]
checkout = [i + 1 for i, line in enumerate(lines) if "actions/checkout" in line]
print({"permissions_lines": permissions, "checkout_lines": checkout})
PYRepository: LLM-CR-EVAL/nx-242-cr1 Length of output: 1691 Security Misconfiguration (CWE-732): Incorrect Permission Assignment for Critical Resource Reachability: External Declare least-privilege permissions. Add workflow-level 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| # For pull_request_target, we need to checkout the base branch | ||
| ref: ${{ github.event.pull_request.base.ref }} | ||
|
Comment on lines
+15
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- workflow files ---'
git ls-files '.github/workflows/pr-title-validation.yml' '.github/workflows/*' | sed -n '1,80p'
printf '%s\n' '--- target workflow ---'
cat -n .github/workflows/pr-title-validation.yml
printf '%s\n' '--- checkout and shell-related references ---'
rg -n -C 4 'actions/checkout|pull_request_target|run:|github\.event|commit-lint|commit message|title' .github/workflows/pr-title-validation.ymlRepository: LLM-CR-EVAL/nx-242-cr1 Length of output: 3232 🏁 Script executed: #!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
workflow = Path(".github/workflows/pr-title-validation.yml").read_text()
start = workflow.index(" - name: Create PR message file")
end = workflow.index("\n - name: Validate PR title", start)
block = workflow[start:end]
print("--- workflow block ---")
print(block)
# Model GitHub expression interpolation into the run block. The payload is
# data supplied by the pull request, not repository code.
title = 'fix(core): valid $(cat "$GITHUB_WORKSPACE/.git/config")'
body = 'safe\nEOF\nprintf "injected-command-ran\\n"'
generated = block.replace("${{ github.event.pull_request.title }}", title)
generated = generated.replace("${{ github.event.pull_request.body }}", body)
print("--- generated run content ---")
print(generated)
print("--- credential persistence indicators ---")
checkout = workflow[workflow.index("uses: actions/checkout@v4"):workflow.index("\n\n", workflow.index("uses: actions/checkout@v4"))]
print(checkout)
print("persist-credentials explicitly disabled:", "persist-credentials: false" in checkout)
PYRepository: LLM-CR-EVAL/nx-242-cr1 Length of output: 889 🌐 Web query:
💡 Result: In Citations:
Sensitive Data Exposure (CWE-522): Insufficiently Protected Credentials Reachability: External · Exploitability: Trivial Disable checkout credential persistence. The workflow interpolates the pull request title and body into shell commands. An attacker can use this injection to read the token that 🧰 Tools🪛 zizmor (1.29.0)[warning] 15-19: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
|
|
||
| - name: Create PR message file | ||
| run: | | ||
| mkdir -p /tmp | ||
| cat > /tmp/pr-message.txt << 'EOF' | ||
| ${{ github.event.pull_request.title }} | ||
|
|
||
| ${{ github.event.pull_request.body }} | ||
| EOF | ||
|
Comment on lines
+29
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Validate the title independently of the body. The supplied Write only the title for a title check, or anchor the validator to the complete first line. 🧰 Tools🪛 zizmor (1.29.0)[error] 30-30: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 32-32: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI Agents |
||
|
|
||
| - name: Validate PR title | ||
| run: | | ||
| echo "Validating PR title: ${{ github.event.pull_request.title }}" | ||
| node ./scripts/commit-lint.js /tmp/pr-message.txt | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: LLM-CR-EVAL/nx-242-cr1
Length of output: 3489
🌐 Web query:
GitHub Actions workflow both pull_request and pull_request_target same event two workflow runs documentation💡 Result:
Yes, you can configure a single GitHub Actions workflow to be triggered by both
pull_requestandpull_request_targetevents [1][2]. You can include both in theonblock of your workflow file [1]. When you define a workflow to listen for both events, a single pull request activity (such as opening or synchronizing a PR) can trigger two separate workflow runs: one forpull_requestand one forpull_request_target[3][2]. Key differences to consider when using them together: 1. Context and Security: -pull_request: Runs the workflow code from the pull request's merge commit [4][3]. It is restricted to a read-only GITHUB_TOKEN and does not have access to repository secrets to prevent unauthorized code execution from forks [4][5]. -pull_request_target: Runs the workflow code from the target repository's base branch (the version of the code that is trusted) [4][3]. This allows the workflow to access repository secrets and a read/write GITHUB_TOKEN, making it suitable for tasks like labeling or commenting on PRs [3][2]. 2. Triggering: - Both events support the same activity types (such asopened,synchronize, andreopened) [6][2]. - If a pull request has a merge conflict,pull_requestworkflows will not run, butpull_request_targetworkflows will still trigger [6][2]. Because these two events run in different contexts, you should be careful if you use them in the same workflow. It is common practice to use conditional logic (e.g.,if: github.event_name == 'pull_request') within your jobs or steps if you need to perform different actions depending on which event triggered the specific run [7]. Additionally, exercise extreme caution when usingpull_request_target, as it executes code from your base branch while handling potentially untrusted data from a pull request [4][2]. Top results: [6][4][1][2]Citations:
Keep only one pull request trigger.
The matching pull request event starts one run for
pull_requestand another forpull_request_target. Remove one trigger to prevent duplicate validation runs and check results.🧰 Tools
🪛 zizmor (1.29.0)
[error] 3-7: use of fundamentally insecure workflow trigger (dangerous-triggers): pull_request_target is almost always used insecurely
(dangerous-triggers)
🤖 Prompt for AI Agents