This is an automated email from the ASF dual-hosted git repository.

Fokko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/parquet-java.git


The following commit(s) were added to refs/heads/master by this push:
     new ed6aa0594 MINOR: Verify LICENSE and NOTICE in published JARs (#3689)
ed6aa0594 is described below

commit ed6aa0594d6fafbe12c55da0ee31c25d25f722c0
Author: Kevin Liu <[email protected]>
AuthorDate: Mon Jul 27 15:45:02 2026 -0400

    MINOR: Verify LICENSE and NOTICE in published JARs (#3689)
---
 .github/workflows/ci-hadoop3.yml    |   7 +++
 dev/check-jar-license-and-notice.sh | 120 ++++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)

diff --git a/.github/workflows/ci-hadoop3.yml b/.github/workflows/ci-hadoop3.yml
index c3304df13..938d370f6 100644
--- a/.github/workflows/ci-hadoop3.yml
+++ b/.github/workflows/ci-hadoop3.yml
@@ -59,3 +59,10 @@ jobs:
           EXTRA_JAVA_TEST_ARGS=$(./mvnw help:evaluate 
-Dexpression=extraJavaTestArgs -q -DforceStdout)
           export MAVEN_OPTS="$MAVEN_OPTS $EXTRA_JAVA_TEST_ARGS"
           ./mvnw verify --batch-mode javadoc:javadoc
+      - name: generate published JARs and verify LICENSE and NOTICE
+        if: matrix.java.setup == '17'
+        run: |
+          # Ensure all JARs published by the release are created before 
checking LICENSE and NOTICE.
+          ./mvnw --batch-mode process-resources source:jar-no-fork javadoc:jar
+          # Verify every published JAR contains LICENSE and NOTICE.
+          ./dev/check-jar-license-and-notice.sh
diff --git a/dev/check-jar-license-and-notice.sh 
b/dev/check-jar-license-and-notice.sh
new file mode 100755
index 000000000..7b6498c0f
--- /dev/null
+++ b/dev/check-jar-license-and-notice.sh
@@ -0,0 +1,120 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -euo pipefail
+
+# ASF release policy requires every distributed JAR to include LICENSE and 
NOTICE
+# in META-INF: 
https://www.apache.org/legal/release-policy.html#licensing-documentation
+# This script expects the JARs to have already been built.
+readonly -a required_entries=(META-INF/LICENSE META-INF/NOTICE)
+
+search_roots=("$@")
+if [[ ${#search_roots[@]} -eq 0 ]]; then
+  search_roots=(.)
+fi
+
+should_check_jar() {
+  local jar_file=$1
+  local jar_name
+
+  # Only check JARs directly under a module's target directory.
+  [[ $(basename "$(dirname "$jar_file")") == "target" ]] || return 1
+
+  jar_name=$(basename "$jar_file")
+  case "$jar_name" in
+    original-*.jar)
+      # Maven Shade backups are build intermediates and are not deployed.
+      return 1
+      ;;
+    parquet-benchmarks.jar)
+      # This local-only JMH uber-JAR is not deployed. Maven publishes the
+      # versioned parquet-benchmarks artifact instead.
+      return 1
+      ;;
+  esac
+
+  return 0
+}
+
+# Populates the global jar_files array.
+find_jar_candidates() {
+  local jar_paths_file=$1
+  shift
+  local jar_file
+
+  if ! find "$@" -type f -name "*.jar" -print0 >"$jar_paths_file"; then
+    printf '%s\n' "Unable to complete the search for published JAR 
candidates." >&2
+    return 1
+  fi
+
+  jar_files=()
+  while IFS= read -r -d '' jar_file; do
+    if should_check_jar "$jar_file"; then
+      jar_files+=("$jar_file")
+    fi
+  done <"$jar_paths_file"
+}
+
+check_jar() {
+  local jar_file=$1
+  local jar_listing_file=$2
+  local has_missing_entry=0
+  local required_entry
+
+  if ! jar tf "$jar_file" >"$jar_listing_file"; then
+    printf 'Unable to read JAR: %s\n' "$jar_file" >&2
+    return 1
+  fi
+
+  for required_entry in "${required_entries[@]}"; do
+    if ! grep -Fqx "$required_entry" "$jar_listing_file"; then
+      printf 'Missing %s: %s\n' "$required_entry" "$jar_file" >&2
+      has_missing_entry=1
+    fi
+  done
+
+  return "$has_missing_entry"
+}
+
+jar_paths_file=$(mktemp)
+jar_listing_file=$(mktemp)
+trap 'rm -f "$jar_paths_file" "$jar_listing_file"' EXIT
+
+jar_files=()
+find_jar_candidates "$jar_paths_file" "${search_roots[@]}"
+
+jar_count=${#jar_files[@]}
+if [[ $jar_count -eq 0 ]]; then
+  printf '%s\n' "No published JAR candidates found directly under module 
target directories." >&2
+  exit 1
+fi
+
+has_failures=0
+verified_count=0
+for jar_file in "${jar_files[@]}"; do
+  if check_jar "$jar_file" "$jar_listing_file"; then
+    verified_count=$((verified_count + 1))
+  else
+    has_failures=1
+  fi
+done
+
+printf 'Successfully verified %d of %d JAR(s).\n' "$verified_count" 
"$jar_count"
+exit "$has_failures"

Reply via email to