This is an automated email from the ASF dual-hosted git repository.
voonhous pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git
The following commit(s) were added to refs/heads/master by this push:
new 62bae026d55f chore(ci): show pr_compliance.py self-test failures
(#20422)
62bae026d55f is described below
commit 62bae026d55fa926d66dade6b5f4f44ebdb43d78
Author: voonhous <[email protected]>
AuthorDate: Sat Oct 24 11:28:39 2026 +0800
chore(ci): show pr_compliance.py self-test failures (#20422)
* chore(ci): show pr_compliance.py self-test failures
The failure path echoed the whole test log behind one ::error::, so the
annotation carried only the first log line (a PASSED test) and the
rest landed in the step log unlabelled. Print the log plainly and put
the names of the failed tests in the annotation.
Follow-up to review on #20421.
* chore(ci): split failed self-test names on semicolons
Review feedback. Test names such as "Swapped sections: 0, 1" contain
commas, so join them with "; ". A crash before any test reports
lists no names; the annotation then points at the step log.
* chore(ci): name the offending commit or file in annotations
Review feedback: the co-author, binary, copyright and RAT steps
annotated only "Process completed with exit code 1", so the run
summary did not say what to fix. Each now emits an ::error:: naming
the commit or file; the source-check ones are file annotations, so
they also show inline in the PR diff. The release scripts are
unchanged, since release managers run them too.
---
.github/workflows/validate_source.yml | 57 ++++++++++++++++++++++++++++++++---
1 file changed, 52 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/validate_source.yml
b/.github/workflows/validate_source.yml
index ba60a804da59..3b6b92a228bc 100644
--- a/.github/workflows/validate_source.yml
+++ b/.github/workflows/validate_source.yml
@@ -48,10 +48,20 @@ jobs:
# Seconds of stdlib-only unit tests, so they run on every PR instead of
path-filtering
# on scripts/pr_compliance.py. The log goes to the runner temp dir: the
source checks below
- # copy and scan the workspace, and a stray test.log has no license
header.
+ # copy and scan the workspace, and a stray test.log has no license
header. A passing run
+ # stays quiet; a failing one prints the full log and names the failed
tests in the annotation.
- name: Test pr_compliance.py
if: ${{ !cancelled() && env.CHECK_PR_METADATA == 'true' }}
- run: python3 scripts/pr_compliance.py run-tests >
"$RUNNER_TEMP/test.log" || { echo "::error::pr_compliance.py $(cat
"$RUNNER_TEMP/test.log")" && exit 1; }
+ run: |
+ log="$RUNNER_TEMP/test.log"
+ if ! python3 scripts/pr_compliance.py run-tests > "$log"; then
+ cat "$log"
+ # Test names can contain commas, so join with "; ". A crash before
any test reports
+ # (traceback, or one of the script's own exit() calls) lists none,
so point at the log.
+ failed=$(sed -n 's/ - FAILED$//p' "$log" | awk 'NR > 1 { printf ";
" } { printf "%s", $0 }')
+ echo "::error::pr_compliance.py self-tests failed: ${failed:-see
the step log}"
+ exit 1
+ fi
- name: Check for legacy PR title format using JIRA or MINOR
id: check-legacy-format
@@ -126,6 +136,7 @@ jobs:
echo "Commits must not credit Claude as a co-author."
echo "Remove the 'Co-authored-by: Claude ...' trailer from the
commit message(s),"
echo "e.g., by amending the commit or rebasing, and force-push the
branch."
+ echo "::error::Commits with a Claude co-author trailer: $(echo
"$flagged" | paste -sd ' ' -). Remove the trailer (amend or rebase) and
force-push."
exit 1
fi
@@ -161,16 +172,52 @@ jobs:
id: source-dir
if: ${{ !cancelled() }}
run: ./scripts/release/create_source_directory.sh "${{ runner.temp
}}/hudi-tmp-repo"
+ #
+ # The release scripts print plain text because release managers run them
too. On failure the
+ # steps below turn each offending file into a file annotation, so the
run summary and the PR
+ # diff name the file and the fix. The source release mirrors the repo
layout, so its paths
+ # are repo paths. If a failure names no file, the step log has the
details.
- name: Check Binary Files
if: ${{ !cancelled() && steps.source-dir.outcome == 'success' }}
run: |
cd "${{ runner.temp }}/hudi-tmp-repo"
- ./scripts/release/validate_source_binary_files.sh
+ log="$RUNNER_TEMP/binary.log"
+ status=0
+ ./scripts/release/validate_source_binary_files.sh > "$log" 2>&1 ||
status=$?
+ cat "$log"
+ if [ "$status" -ne 0 ]; then
+ sed -n 's|^\./\([^:]*\):.*|\1|p' "$log" | while read -r f; do
+ echo "::error file=$f::Binary file in the source release. Binary
files are only allowed under src/test/ as test fixtures."
+ done
+ exit 1
+ fi
- name: Check Copyright
if: ${{ !cancelled() && steps.source-dir.outcome == 'success' }}
run: |
cd "${{ runner.temp }}/hudi-tmp-repo"
- ./scripts/release/validate_source_copyright.sh
+ log="$RUNNER_TEMP/copyright.log"
+ status=0
+ ./scripts/release/validate_source_copyright.sh > "$log" 2>&1 ||
status=$?
+ cat "$log"
+ if [ "$status" -ne 0 ]; then
+ sed -n 's|^\./||p' "$log" | while read -r f; do
+ echo "::error file=$f::Missing the ASF license header. Copy it
from an existing file of the same type."
+ done
+ exit 1
+ fi
- name: RAT check
if: ${{ !cancelled() }}
- run: ./scripts/release/validate_source_rat.sh
+ run: |
+ log="$RUNNER_TEMP/rat.log"
+ status=0
+ ./scripts/release/validate_source_rat.sh > "$log" 2>&1 || status=$?
+ cat "$log"
+ if [ "$status" -ne 0 ]; then
+ if [ -f target/rat.txt ]; then
+ awk '/^Files with unapproved licenses:/ { f = 1; next } f &&
/^\*/ { exit } f && NF { sub(/^ +/, ""); print }' target/rat.txt \
+ | while read -r f; do
+ echo "::error file=$f::RAT found no approved license header.
Copy the ASF header from an existing file of the same type."
+ done
+ fi
+ exit 1
+ fi