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 e098da78c501 fix(ci): make the source-release binary-file check 
actually run (#19267)
e098da78c501 is described below

commit e098da78c501072e20da4cef4212ed84c3918cf6
Author: Vova Kolmakov <[email protected]>
AuthorDate: Wed Jul 15 20:04:41 2026 +0700

    fix(ci): make the source-release binary-file check actually run (#19267)
    
    * fix(ci): make the source-release binary-file check actually run
    
    validate_source_binary_files.sh pipes every file through `file -I`, the
    BSD/macOS spelling of the MIME option. GNU file rejects it, printing usage
    to stderr and nothing to stdout, so the pipeline's `wc -l` always counts
    zero. errexit does not catch it because the pipeline sits in a command
    substitution and pipefail is not set. The check has therefore never fired on
    Linux, which is every CI runner.
    
    Ask libmagic for the charset instead of the MIME type. `file --mime` is the
    long option for both GNU's `-i` and BSD's `-I`, and its charset=binary field
    answers the question directly, without depending on libmagic's growing type
    vocabulary: the previous MIME allowlist already yields five false positives
    on master, where libmagic labels the JSON test data application/x-ndjson and
    misdetects one .java source as application/javascript. Empty files, which
    libmagic also reports as charset=binary, are exempted alongside the existing
    release/ and src/test/ exemptions.
    
    Add pipefail so a broken `file` invocation fails loudly rather than reading
    as "no binary files found", run `file` once over a batched find/xargs 
instead
    of one process per path, and build the report from that single pass.
    
    Run the check where it is meant to run. Its contract is the root of a source
    release tree, which is how validate_staged_release.sh invokes it, but the
    validate-source job ran it against the raw checkout, where rfc/, 
docker/images/,
    hudi-notebooks/ and .idea/ still exist. bot.yml now creates the source 
release
    directory once and runs both the binary and the copyright check inside it.
    
    Closes #19266
    
    * addressed review comments: make binary-file grep chain byte-safe and pin 
the release/ exemption to top level
    
    ---------
    
    Co-authored-by: Vova Kolmakov <[email protected]>
---
 .github/workflows/bot.yml                       | 11 +++++++--
 scripts/release/validate_source_binary_files.sh | 33 ++++++++++++++++++++++---
 2 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml
index 160822b26d7e..a8d0fbb47c25 100644
--- a/.github/workflows/bot.yml
+++ b/.github/workflows/bot.yml
@@ -80,11 +80,18 @@ jobs:
           # wins the write. This one only runs `mvn apache-rat:check`, 
finishes in well under a
           # minute, and would seal a ~10 MB local repo that every build job 
then has to discard and
           # re-download from Maven Central.
+      # Both checks describe the source release, not the git checkout, so they 
run inside the
+      # directory create_source_directory.sh produces - the same way 
validate_staged_release.sh
+      # runs them inside an extracted source tarball. On the raw checkout they 
would see the
+      # images under rfc/, docker/images/ and hudi-notebooks/, which the 
source release excludes.
+      - name: Create source release directory
+        run: ./scripts/release/create_source_directory.sh hudi-tmp-repo
       - name: Check Binary Files
-        run: ./scripts/release/validate_source_binary_files.sh
+        run: |
+          cd hudi-tmp-repo
+          ./scripts/release/validate_source_binary_files.sh
       - name: Check Copyright
         run: |
-          ./scripts/release/create_source_directory.sh hudi-tmp-repo
           cd hudi-tmp-repo
           ./scripts/release/validate_source_copyright.sh
       - name: RAT check
diff --git a/scripts/release/validate_source_binary_files.sh 
b/scripts/release/validate_source_binary_files.sh
index e4ce431c71b9..80769c34d3b7 100755
--- a/scripts/release/validate_source_binary_files.sh
+++ b/scripts/release/validate_source_binary_files.sh
@@ -19,16 +19,41 @@
 # under the License.
 #
 
-# fail immediately
+# Run this from the root of a source release tree, i.e. the output of
+# create_source_directory.sh (see the validate-source job in bot.yml) or an
+# extracted source tarball (see validate_staged_release.sh). Paths that never
+# reach the source release are excluded by create_source_directory.sh, not 
here.
+
+# fail immediately; pipefail so that a broken `file` invocation can never again
+# yield an empty pipeline that reads as "no binary files found"
 set -o errexit
 set -o nounset
+set -o pipefail
 
 echo "Checking for binary files in the source files"
-numBinaryFiles=`find . -iname '*' | xargs -I {} file -I {} | grep -va 
directory | grep -v "release/" | grep -v "/src/test/" | grep -va 
'application/json' | grep -va 'text/' | grep -va 'application/xml' | grep -va 
'application/json' | wc -l | sed -e s'/ //g'`
 
-if [ "$numBinaryFiles" -gt "0" ]; then
+# `--mime` is the long option for both GNU file's `-i` and BSD file's `-I`, so 
it
+# is the only spelling that works on Linux CI and on a release manager's macOS.
+# Its charset field answers the question directly: libmagic reports
+# charset=binary for anything that is not text. Matching on the charset rather
+# than on a list of permitted MIME types keeps this robust against libmagic's
+# growing type vocabulary, which already labels the JSON test data
+# application/x-ndjson and misdetects at least one .java source as
+# application/javascript.
+mimeTypes=$(find . -type f -print0 | xargs -0 file --mime)
+
+# An empty file reports as inode/x-empty; charset=binary, and is neither 
binary nor
+# a licensing concern. The top-level release/ holds the release guide's 
screenshot;
+# src/test/ holds the binary fixtures (parquet, avro, hfile) that tests read. 
Every
+# stage carries -a so a non-UTF-8 filename can never flip a grep into binary 
mode and
+# drop a line. release/ is anchored to the top-level dir; src/test/ stays a 
substring
+# because those fixtures live under every module's src/test/.
+binaryFiles=$(echo "$mimeTypes" | grep -a 'charset=binary' | grep -av 
'inode/x-empty' \
+  | grep -av '^\./release/' | grep -av '/src/test/' || true)
+
+if [ -n "$binaryFiles" ]; then
   echo -e "There were non-text files in source release. [ERROR]\n Please check 
below\n"
-  find . -iname '*' | xargs -I {} file -I {} | grep -va directory | grep -v 
"release/release_guide" | grep -v "/src/test/" | grep -va 'application/json' | 
grep -va 'text/' |  grep -va 'application/xml'
+  echo "$binaryFiles"
   exit 1
 fi
 echo -e "\t\tNo Binary Files in the source files? - [OK]\n"

Reply via email to