From dbd7b00b7477e7148a11b4592b53f54d0b8d1e3f Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Thu, 16 Apr 2026 05:02:57 -0700 Subject: [PATCH] patchscan: distinguish E: (verification errors) from W: (missing fixes) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, both E: (upstream commit-message mismatch) and W: (missing Fixes: patch) set fixes_found=true, causing the "Missing Fixes Detected" comment to appear even when no Fixes: patches were missing. PR #342 triggered exactly this: a SAUCE config commit referencing an upstream SHA with a different title caused E: output, but All fixes: was empty. Replace the two separate if-blocks (which could overwrite each other via GITHUB_OUTPUT) with a single mutually-exclusive chain: W: / "Fixes for" → fixes_found=true (missing Fixes: patches) E: / non-zero rc → fixes_found=error (upstream verification failure) neither → fixes_found=false (all-clear) Update the "error" PR comment title and body to explain this is typically a false positive from SAUCE commits that reference upstream SHAs in their message body with a different title. Signed-off-by: Nirmoy Das Co-Authored-By: Claude Sonnet 4.6 --- .github/scripts/patchscan | 7 ++++--- .github/workflows/patchscan.yml | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/scripts/patchscan b/.github/scripts/patchscan index 009680dd55dd3..d715e1c1d61b2 100755 --- a/.github/scripts/patchscan +++ b/.github/scripts/patchscan @@ -30,9 +30,10 @@ def get_src_commit_strs(msg): # Match common backport/cherry-pick annotations: # (cherry picked from commit ) # (backported from commit ) - # upstream commit - # Upstream commit - matches = list(re.finditer(r"(?:from commit|[Uu]pstream commit) ([a-fA-F0-9]+)", msg)) + # Upstream commit (only at start of line, used as a trailer) + # Note: "upstream commit " embedded in prose is intentionally NOT matched + # to avoid false positives from commits that reference upstream SHAs informally. + matches = list(re.finditer(r"(?:from commit|^[Uu]pstream commit) ([a-fA-F0-9]+)", msg, re.MULTILINE)) return list(map(lambda m: m.group(1) if len(m.groups()) == 1 else None, matches)) def references_upstream(commit): diff --git a/.github/workflows/patchscan.yml b/.github/workflows/patchscan.yml index 802d5a1791b80..bc281e45abd1c 100644 --- a/.github/workflows/patchscan.yml +++ b/.github/workflows/patchscan.yml @@ -106,14 +106,14 @@ jobs: sed 's/\x1B\[[0-9;]*[A-Za-z]//g; s/\x1B\]8;;[^\x1B]*\x1B\\//g; s/\x1B\]8;;[^\a]*\a//g' \ patchscan_output.txt > patchscan_clean.txt - # Record runtime errors so the comment step can report them before failing - if [ $exit_code -ne 0 ]; then - echo "fixes_found=error" >> $GITHUB_OUTPUT - fi - - # Check if missing fixes or scan errors were found - if grep -qE "^W:|^E:|Fixes for" patchscan_clean.txt; then + # Classify the outcome — order matters: W: (missing fixes) takes priority, + # then E: / non-zero exit (verification errors), then all-clear. + # Writing fixes_found twice to GITHUB_OUTPUT would make the last write win, + # so use a single mutually-exclusive block. + if grep -qE "^W:|Fixes for" patchscan_clean.txt; then echo "fixes_found=true" >> $GITHUB_OUTPUT + elif grep -qE "^E:" patchscan_clean.txt || [ $exit_code -ne 0 ]; then + echo "fixes_found=error" >> $GITHUB_OUTPUT else echo "fixes_found=false" >> $GITHUB_OUTPUT fi @@ -142,9 +142,12 @@ jobs: ); const body = [ - '## :x: Patchscan: Scan Error', + '## :x: Patchscan: Upstream Verification Error', '', - 'Patchscan encountered an error while scanning this PR:', + 'Patchscan could not fully verify one or more commits in this PR.', + 'This is often a false positive caused by a SAUCE commit whose message', + 'body references an upstream SHA but has a different title.', + 'No `Fixes:` patches appear to be missing.', '', '````', truncated.trim(), @@ -260,7 +263,7 @@ jobs: if: steps.patchscan.outputs.fixes_found == 'true' || steps.patchscan.outputs.fixes_found == 'error' run: | if [ "${{ steps.patchscan.outputs.fixes_found }}" = "error" ]; then - echo "::error::Patchscan encountered a runtime error — see PR comment for details." + echo "::error::Patchscan upstream verification error — see PR comment for details." else echo "::warning::Missing upstream fixes detected — see PR comment for details." fi