fix(pre-fetch): extract the prior SHA with sed, not BSD-incompatible grep -P - #6676
Conversation
E2E tests did not runE2E tests run automatically for org/repo members and collaborators on pull requests. For other contributors, a maintainer must add the See E2E testing guide for details. |
PR Summary by QodoMake prior-review SHA extraction portable across macOS and Linux
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1. Multiple matches abort pre-fetch
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
waynesun09
left a comment
There was a problem hiding this comment.
Review sweep at head 0ce3f82. Both findings land on files outside this PR's diff (the diff is only pre-fetch-prior-review.sh), so they are here in the review body rather than as inline comments. Neither blocks the fix itself — the sed -nE change is correct and the right call.
MEDIUM — The GitLab scaffold twin keeps the byte-identical grep -oP, and the PR body's "five other scripts" sweep is understated
internal/scaffold/fullsend-repo-gitlab/.gitlab/ci/fullsend-agent.yml:462
internal/scaffold/fullsend-repo-gitlab/.gitlab/ci/fullsend-agent.yml:462 runs:
PRIOR_REVIEW_SHA=$(printf '%s' "${CURRENT_SECTION}" \
| grep -oP '(?<=\*\*Head SHA:\*\* )[0-9a-f]{7,64}' | head -1 || true)That is byte-identical to the line this PR replaces, including the surrounding awk '/<!-- sticky:history-start -->/{exit}' section split and the 1 MB MAX_REVIEW_BYTES cap. The comment at lines 390-394 calls it out explicitly: "Pre-fetch prior review for the review agent — equivalent to pre-fetch-prior-review.sh in the GitHub scaffold." After this PR the two self-declared-equivalent extractors diverge in exactly the multi-marker-on-one-line case the PR body flags as a deliberate behavior change (grep takes the first, sed's greedy .* takes the last).
Separately, the PR body's sweep enumeration is wrong. It says "five other scripts use grep -P (scripts/renovate/*, hack/gitlab-runner-vm/setup.sh, reconcile-repos.sh). They are Linux-only automation and out of scope." A repo-wide search returns two sites that enumeration misses. The GitLab twin above is one. The other is hack/lint-docs-links:32:
done < <(grep -oP '(?<=\])\(\K[^)]+' "$mdfile" || true)which is not Linux-only automation: .pre-commit-config.yaml:156-161 wires it as the lint-docs-links pre-commit hook over ^docs/.*\.md$, so it runs on developer machines, macOS included, with the same fail-open || true this PR is fixing. On a macOS checkout it yields zero links and the docs-link scope check passes vacuously. That is the same bug class on the same platform the PR exists to fix, described in the PR body as out of scope.
Suggestion: Apply the same sed -nE extraction at fullsend-agent.yml:462 so the pair the comment calls "equivalent" stays equivalent (one line), or leave it and note at that line why it is deliberately divergent. Either way correct the PR body: the sweep is seven sites, not six, and hack/lint-docs-links is a macOS-reachable pre-commit hook rather than Linux-only automation — worth its own follow-up issue, since it fails open exactly the way this PR's target did.
MEDIUM — PR body's reconcile-repos.sh:208 claim is factually wrong; the anchored allowlist three lines later already rejects control characters
internal/scaffold/fullsend-repo/scripts/reconcile-repos.sh:208
The PR body asserts as fact: "reconcile-repos.sh:208 deserves its own look — its grep -qP '[\x00-\x1f]' control-character guard does not error out on BSD, it just evaluates false, so that check quietly passes everything on a macOS run."
Reading the file at head 0ce3f82: line 208 is if printf '%s' "$name" | grep -qP '[\x00-\x1f]'; then inside validate_repo_name, and line 212 is if ! [[ "$name" =~ $REPO_NAME_PATTERN ]]; then with REPO_NAME_PATTERN='^[a-zA-Z0-9._-]+$' defined at line 30. That is an anchored allowlist that rejects every byte in \x00-\x1f regardless of what the grep on 208 returns, so "that check quietly passes everything on a macOS run" is false — the grep is defense-in-depth on top of a check that already covers its entire input class, and the macOS exposure is nil.
The mechanism claim is also imprecise: BSD grep does not succeed on -P, it exits non-zero with a usage error; the reason set -e does not fire is that the call sits in an if condition, where a non-zero status simply reads as false. Same net effect, different cause, and the difference matters to whoever follows the pointer — they will find stderr noise, not silence. Shipping "quietly passes everything" in a merged PR description invites someone to file a security issue against code that is already safe.
Suggestion: Reword to something checkable, e.g. "BSD grep exits non-zero on -P; inside the if that reads as false, so the guard at line 208 is inert on macOS — harmless in practice because the anchored REPO_NAME_PATTERN allowlist at line 212 already rejects control characters. Worth cleaning up for hygiene, not a hole."
…grep -P
pre-fetch-prior-review.sh read the prior review's head SHA with
`grep -oP '(?<=\*\*Head SHA:\*\* )[0-9a-f]{7,64}'`. BSD grep, which is
what macOS ships as /usr/bin/grep, has no -P: the call exits with
"grep: invalid option -- P" and the trailing `|| true` swallows it, so
PRIOR_SHA silently comes back empty.
The effect is confined to developer machines — CI and the vendored
consumer path both run on Linux with GNU grep — but there it is not
subtle: body-with-valid-sha and body-with-full-sha fail on every macOS
checkout of main, which is two red tests a newcomer has to rule out
before trusting their own changes. I spent a while assuming they were
mine.
sed -nE expresses the same match in POSIX ERE and behaves identically on
both platforms. A no-match prints nothing and exits 0, so the fallback
that `|| true` was covering is now structural rather than suppressed —
body-without-sha-no-crash still passes without it.
One deliberate difference, since it is a behavior change and not a
refactor: with two "**Head SHA:**" markers on the *same line*, grep -o
emitted both and head -1 took the first, while sed's greedy leading .*
takes the last. Across separate lines — the only shape this pipeline
writes, one bolded field per line — head -1 still yields the first, which
the tests cover.
Not swept: five other scripts use grep -P (scripts/renovate/*,
hack/gitlab-runner-vm/setup.sh, reconcile-repos.sh). They are Linux-only
automation and out of scope here, but reconcile-repos.sh:208 is worth a
look on its own — its `grep -qP '[\x00-\x1f]'` control-character guard
does not error out on BSD, it just evaluates false, so the check quietly
passes everything on a macOS run.
Verification: pre-fetch-prior-review-test.sh goes from 2 failures to all
tests passing on macOS (BSD grep 2.6.0-FreeBSD); shellcheck clean.
Signed-off-by: guy oron <goron@redhat.com>
The GitLab scaffold's fullsend-agent.yml carries a byte-identical copy of the extraction the previous commit replaced — its own comment calls it "equivalent to pre-fetch-prior-review.sh in the GitHub scaffold", and after that commit the two self-declared-equivalent extractors diverged in exactly the multi-marker-on-one-line case the change declared. Same sed -nE expression here, so the pair stays equivalent, with a pointer comment so the next edit finds the rationale in one place. Unlike the GitHub script, this path never breaks at runtime — GitLab runners are Linux — so this is equivalence maintenance, not a platform fix. Raised in review by @waynesun09. Verification: the embedded pipeline extracted verbatim from the yml and run under set -euo pipefail against the same fixture shapes as pre-fetch-prior-review-test.sh (valid short SHA, full 40-char SHA, no marker, marker only in the sticky-history section) — identical output to the GitHub script in all four; multi-document YAML still parses. Signed-off-by: guy oron <goron@redhat.com>
0ce3f82 to
c3babba
Compare
|
Both fixed, thanks for the sweep check — both catches were right.
|
Heyaaaa : )
Summary
pre-fetch-prior-review.shextracts the prior review SHA withgrep -oP. BSD grep (macOS) has no-P, the|| trueswallows the failure, andPRIOR_SHAcomes back empty — two script tests fail on every macOS checkout. Replaced withsed -nE, the same expression in POSIX ERE. Second commit applies the identical swap to the GitLab scaffold twin (its comment declares it "equivalent" to this script) so the pair stays in lockstep — caught in review by @waynesun09.Related Issue
None — found running the script test suite on macOS.
Changes
sed -nE 's/.*\*\*Head SHA:\*\* ([0-9a-f]{7,64}).*/\1/p' | head -1replaces the grep; the|| truegoes too, since a sed no-match exits 0.fullsend-repo-gitlab/.gitlab/ci/fullsend-agent.yml:462, with a lockstep pointer comment.**Head SHA:**markers on one line now yield the last, not the first. Across lines — the only shape the pipeline writes — behavior is identical, and the tests cover it.Sweep status:
hack/lint-docs-linkshad the same bug class and is macOS-reachable via pre-commit — fixed in #6728. The guard atreconcile-repos.sh:208is inert on macOS (BSD grep exits non-zero, theifreads that as false) but harmless: the anchored allowlist at :212 already rejects control characters. Still unswept, genuinely Linux-only:scripts/renovate/*,hack/gitlab-runner-vm/setup.sh.Testing
make lintpasses (stage changes first, then run)pre-fetch-prior-review-test.sh: 2 failures → all pass on macOS. GitLab twin pipeline run on the same fixtures, identical output. CI (GNU grep) behaviorally unchanged.Checklist
!for breaking changes)