-
Notifications
You must be signed in to change notification settings - Fork 0
fix(ci): stop public-repo-guard's required check from wedging on comment/review bursts #69
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
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,122 @@ | ||||||||||||||||||||||||
| name: public-repo-guard-body | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # The other half of public-repo-guard.yml's coverage, deliberately in its OWN | ||||||||||||||||||||||||
| # workflow file — see the long comment block at the top of public-repo-guard.yml | ||||||||||||||||||||||||
| # for the incident (wave-av/cli PR #68) that caused the split and why it is a | ||||||||||||||||||||||||
| # file-level split, not just a job-level one. | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # `guard` (in public-repo-guard.yml) scans the published TREE and produces the | ||||||||||||||||||||||||
| # REQUIRED check "Secrets + content policy". This job scans a PR/issue/comment | ||||||||||||||||||||||||
| # BODY, which is just as world-readable and, until this job existed, was scanned | ||||||||||||||||||||||||
| # by nothing server-side. That gap was real, not theoretical: a PR was blocked | ||||||||||||||||||||||||
| # for naming a private repo in wrangler.toml while the very same name, with more | ||||||||||||||||||||||||
| # operational detail attached, sat unchallenged in its body. | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # This job's check-run name ("Body content policy") is NOT a required status | ||||||||||||||||||||||||
| # context in this repo's ruleset, so it can safely trigger on every comment/review | ||||||||||||||||||||||||
| # event without any risk of masking or wedging the required tree-scan context — | ||||||||||||||||||||||||
| # that is the entire reason it lives in a separate file from the tree scan. | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # Honest about what it can and cannot do. On a PR this PREVENTS the merge. On an | ||||||||||||||||||||||||
| # issue or comment the text is already public the moment it posts, so this is | ||||||||||||||||||||||||
| # detection — it tells us to go redact, fast. Only the client-side pre-write hook | ||||||||||||||||||||||||
| # can stop that class before publication. | ||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||
| # `edited` matters as much as `opened`: a body can be made to leak long after | ||||||||||||||||||||||||
| # the PR is first raised, and until this job covered it, nothing re-scanned it. | ||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||
| types: [opened, edited, reopened, synchronize] | ||||||||||||||||||||||||
| issues: | ||||||||||||||||||||||||
| types: [opened, edited] | ||||||||||||||||||||||||
| issue_comment: | ||||||||||||||||||||||||
| types: [created, edited] | ||||||||||||||||||||||||
| # Inline review comments on a diff are a SEPARATE event from issue_comment — | ||||||||||||||||||||||||
| # without this trigger they are world-readable text that no job ever scans. | ||||||||||||||||||||||||
| pull_request_review_comment: | ||||||||||||||||||||||||
| types: [created, edited] | ||||||||||||||||||||||||
| # A submitted review's top-level body (the free-text field above any inline | ||||||||||||||||||||||||
| # comments) is yet another world-readable payload, separate from BOTH comment | ||||||||||||||||||||||||
| # events — without this trigger nothing ever scans it. | ||||||||||||||||||||||||
| pull_request_review: | ||||||||||||||||||||||||
| types: [submitted, edited] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # `pull_request`, deliberately NOT `pull_request_target`: a fork PR must never get | ||||||||||||||||||||||||
| # a write token or repo secrets just because a gate wanted to read its body. | ||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||
| body-guard: | ||||||||||||||||||||||||
| name: Body content policy | ||||||||||||||||||||||||
|
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. Suggestion: Assessment: 🟠 Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** .github/workflows/public-repo-guard-body.yml
**Line:** 50:50
**Comment:**
*Api Mismatch: `Body content policy` is not a required check, so a failing body scan does not prevent a pull request from merging as claimed.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix |
||||||||||||||||||||||||
| concurrency: | ||||||||||||||||||||||||
| # Keyed on the specific comment / review / PR / issue rather than github.ref, | ||||||||||||||||||||||||
| # because issue events all report the default branch and a ref-keyed group | ||||||||||||||||||||||||
| # would let two comments cancel each other, leaving one unscanned. The comment | ||||||||||||||||||||||||
| # and review ids come FIRST: those payloads also carry the PR number, and | ||||||||||||||||||||||||
| # keying them on the PR would collapse two rapid comments into one group, | ||||||||||||||||||||||||
| # dropping a verdict. | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # cancel-in-progress is deliberately FALSE. Every version of a body deserves a | ||||||||||||||||||||||||
| # verdict, the job is seconds long, and a cancelled check-run lingers on the | ||||||||||||||||||||||||
| # commit. Since this check-run name is not required, a lingering cancelled | ||||||||||||||||||||||||
| # run here cannot wedge a merge the way the tree scan's could — but a dropped | ||||||||||||||||||||||||
| # verdict on a body would still be a real coverage gap, so the same "let it | ||||||||||||||||||||||||
| # finish" policy applies. | ||||||||||||||||||||||||
| group: public-repo-guard-body-${{ github.event.comment.id || github.event.review.id || github.event.pull_request.number || github.event.issue.number || github.ref }} | ||||||||||||||||||||||||
|
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. Suggestion: GitHub keeps only one running and one pending run per group, so a third rapid edit replaces the pending run and leaves that body version unscanned. [race condition] Assessment: 🟠 Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** .github/workflows/public-repo-guard-body.yml
**Line:** 65:65
**Comment:**
*Race Condition: GitHub keeps only one running and one pending run per group, so a third rapid edit replaces the pending run and leaves that body version unscanned.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix |
||||||||||||||||||||||||
| cancel-in-progress: false | ||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||||||||||||||||||||||||
|
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. Suggestion: The workflow checks out the pull request revision and then executes its Assessment: 🔴 Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** .github/workflows/public-repo-guard-body.yml
**Line:** 69:69
**Comment:**
*Security: The workflow checks out the pull request revision and then executes its `body-policy.sh`, allowing a fork to replace the scanner and make body leaks pass.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix |
||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||
| # Only the gate's own scripts are needed — no reason to pay for the whole | ||||||||||||||||||||||||
| # tree on every comment. | ||||||||||||||||||||||||
| sparse-checkout: scripts/public-repo-guard | ||||||||||||||||||||||||
|
Comment on lines
+69
to
+73
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 | 🛡️ Analyzed with Security Review | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: sed -n '1,145p' .github/workflows/public-repo-guard-body.yml
printf '\n--- scanner ---\n'
sed -n '1,180p' scripts/public-repo-guard/body-policy.sh
printf '\n--- workflow references ---\n'
rg -n "public-repo-guard|body-policy|pull_request|workflow_call|workflow_dispatch" .github/workflows scripts/public-repo-guardRepository: wave-av/cli Length of output: 28832 🤖 get_repo_knowledge executed:
Length of output: 688 🌐 Web query:
💡 Result: When using the actions/checkout action in a GitHub Actions workflow triggered by a pull_request event, the default behavior is to check out a merge commit that combines the base branch and the pull request head branch [1][2]. Specifically, if no ref is specified, the action defaults to checking out the reference or SHA associated with the event [3][4]. For pull_request events, this default reference is a generated merge commit (e.g., refs/pull/:prNumber/merge) [5]. If you prefer to check out the specific head commit of the pull request branch rather than the merge commit, you must explicitly configure the ref input [1][2][6]. The recommended approach is to use the following syntax: - uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.sha }} It is important to note the following distinctions regarding references: 1. Merge Commit: This is the default. It reflects the result of the pull request as it would appear if merged into the base branch at that moment [1][2]. 2. Head Commit: By using ${{ github.event.pull_request.head.sha }}, you checkout the specific commit at the tip of the source branch [7][6]. 3. Security Warning: For workflows triggered by pull_request_target, you should generally avoid checking out the untrusted head commit of a pull request from a fork, as this can execute malicious code in a privileged environment [3][8][9]. In such cases, checking out the base commit (using ${{ github.event.pull_request.base.sha }}) is a safer practice when manual checkout is required [8][9]. Additionally, because the action operates in a detached HEAD state during pull request events, explicitly specifying the ref is often necessary to avoid issues where the desired branch or commit is not checked out correctly [3][7]. Citations:
🏁 Script executed: cat -n .github/workflows/public-repo-guard-body.yml | sed -n '1,145p'Repository: wave-av/cli Length of output: 7774 Reachability: External Check out the scanner from a trusted revision. For Use the base commit for pull-request events and Proposed fix with:
+ ref: ${{ github.event.pull_request.base.sha || github.sha }}
# Only the gate's own scripts are needed — no reason to pay for the whole📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| sparse-checkout-cone-mode: false | ||||||||||||||||||||||||
| # This job only reads the scripts — never leave the token sitting in | ||||||||||||||||||||||||
| # .git/config while repo-supplied scripts execute in the workspace. | ||||||||||||||||||||||||
| persist-credentials: false | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Same rationale as the tree job: body-policy.sh needs a PCRE2-enabled rg, | ||||||||||||||||||||||||
| # and Ubuntu's apt package has none. | ||||||||||||||||||||||||
| - name: Install ripgrep (pinned + checksum-verified, PCRE2 build) | ||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||
| RIPGREP_VERSION: "14.1.1" | ||||||||||||||||||||||||
| RIPGREP_SHA256: "4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e" | ||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||
| if command -v rg >/dev/null && rg --pcre2-version >/dev/null 2>&1; then | ||||||||||||||||||||||||
| echo "using preinstalled $(rg --version | head -n1) with PCRE2"; exit 0 | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
| curl -fsSL --proto '=https' --tlsv1.2 -o ripgrep.tar.gz \ | ||||||||||||||||||||||||
| "https://github.com/BurntSushi/ripgrep/releases/download/${RIPGREP_VERSION}/ripgrep-${RIPGREP_VERSION}-x86_64-unknown-linux-musl.tar.gz" | ||||||||||||||||||||||||
| echo "${RIPGREP_SHA256} ripgrep.tar.gz" | sha256sum -c - | ||||||||||||||||||||||||
| tar -xzf ripgrep.tar.gz --strip-components=1 "ripgrep-${RIPGREP_VERSION}-x86_64-unknown-linux-musl/rg" | ||||||||||||||||||||||||
| sudo install -m 0755 rg /usr/local/bin/rg | ||||||||||||||||||||||||
| rm -f rg ripgrep.tar.gz | ||||||||||||||||||||||||
| rg --pcre2-version | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # The body is read straight out of the event payload FILE and written to | ||||||||||||||||||||||||
| # another file. It is never interpolated into a run: block and never placed | ||||||||||||||||||||||||
| # in an environment variable, so shell metacharacters in a hostile PR body | ||||||||||||||||||||||||
| # have nothing to act on. jq is preinstalled on the GitHub-hosted images. | ||||||||||||||||||||||||
| - name: Materialize the untrusted title/body to a file | ||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||
| mkdir -p "$RUNNER_TEMP/bodyscan" | ||||||||||||||||||||||||
| # An UNRECOGNIZED payload shape must fail, never quietly scan nothing and | ||||||||||||||||||||||||
| # report a pass. If the event schema ever moves, this job must go red | ||||||||||||||||||||||||
| # rather than become a green rubber stamp over an unscanned body. | ||||||||||||||||||||||||
| if [ "$(jq -r 'has("pull_request") or has("issue") or has("comment") or has("review")' "$GITHUB_EVENT_PATH")" != "true" ]; then | ||||||||||||||||||||||||
| echo "::error title=public-repo-guard-body::Event payload contains no pull_request/issue/comment/review object — refusing to report a pass on an unscanned body." | ||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
| jq -r '[.pull_request.title, .pull_request.body, | ||||||||||||||||||||||||
| .issue.title, .issue.body, | ||||||||||||||||||||||||
| .comment.body, .review.body] | ||||||||||||||||||||||||
| | map(select(. != null)) | join("\n")' \ | ||||||||||||||||||||||||
| "$GITHUB_EVENT_PATH" > "$RUNNER_TEMP/bodyscan/body.txt" | ||||||||||||||||||||||||
| echo "scanning $(wc -l < "$RUNNER_TEMP/bodyscan/body.txt") line(s) of body text" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| - name: body policy (PR / issue / comment text) | ||||||||||||||||||||||||
|
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. P1: When a PR body contains a policy violation, this job can fail without preventing the merge because Prompt for AI agents |
||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||
| GUARD_PRIVATE_REPOS: ${{ vars.GUARD_PRIVATE_REPOS }} | ||||||||||||||||||||||||
| run: bash scripts/public-repo-guard/body-policy.sh "$RUNNER_TEMP/bodyscan/body.txt" | ||||||||||||||||||||||||
|
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. P1: A PR can modify the checked-out Prompt for AI agents |
||||||||||||||||||||||||
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.
🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
Repository: wave-av/cli
Length of output: 11964
Security Misconfiguration
Reachability: External
Exploitability: Moderate
CWE: CWE-693
Add a required PR-only body gate if body violations must block merges.
Body content policyis not a required status context. A failedbody-guardjob therefore does not block merges. This conflicts with the documented policy that PR body violations prevent a merge.Keep comment and issue detection in this workflow. Add a separate PR-only required status context for body-policy failures, or change the documented policy to detection only.
🤖 Prompt for AI Agents