From d703206cb39f69277a16048721c1b40a03ea4fbe Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 26 Feb 2026 17:07:23 -0500 Subject: [PATCH 1/3] ci: Run the fmt plugin on in the Java source files --- .kokoro/build.sh | 57 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 7afa8f3b6f26..baaef9d29a87 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -194,12 +194,17 @@ case ${JOB_TYPE} in echo "Running in subdir: ${BUILD_SUBDIR}" pushd "${BUILD_SUBDIR}" fi + + MODULE_FILTER="" + if [ -n "${BASE_SHA}" ] && [ -n "${HEAD_SHA}" ]; then + # Optimize the build by identifying ONLY the Maven modules that contain changed Java source files. + # Format those specific modules instead of the entire codebase. changed_file_list=$(git diff --name-only "${BASE_SHA}" "${HEAD_SHA}") echo "${changed_file_list}" - + has_code_change="false" - + while IFS= read -r changed_file; do # Checks if the line is not empty AND if it matches a .java file if [ -n "${changed_file}" ] && [[ "${changed_file}" == *.java ]]; then @@ -208,19 +213,57 @@ case ${JOB_TYPE} in break fi done <<< "${changed_file_list}" - + if [ "${has_code_change}" == "false" ]; then echo "No java modules affected. Skipping linter check." exit 0 fi + + # Compute list of changed Maven modules from changed Java files. + # We walk each changed .java file up to its nearest pom.xml to find the correct module. + # e.g., if "java-asset/google-cloud-asset/src/main/java/Foo.java" is changed, + # it traverses upward until finding "java-asset/google-cloud-asset/pom.xml" and adds that module. + changed_modules=() + while IFS= read -r changed_file; do + if [ -n "${changed_file}" ] && [[ "${changed_file}" == *.java ]]; then + dir=$(dirname "${changed_file}") + while [ "${dir}" != "." ] && [ ! -f "${dir}/pom.xml" ]; do + dir=$(dirname "${dir}") + done + if [ -f "${dir}/pom.xml" ] && [ "${dir}" != "." ]; then + # Filter out samples, directories with no Java source code, and generated protobuf/gRPC code + if [[ "${dir}" != *"samples"* ]] && \ + [[ "$(basename "${dir}")" != "proto-google-"* ]] && \ + [[ "$(basename "${dir}")" != "grpc-google-"* ]] && \ + [[ "$(basename "${dir}")" != *"-bom" ]] && \ + [[ "$(basename "${dir}")" != "google-cloud-pom-parent" ]] && \ + [[ "$(basename "${dir}")" != "google-cloud-jar-parent" ]]; then + + changed_modules+=("${dir}") + fi + fi + fi + done <<< "${changed_file_list}" + + echo "Changed Modules: ${changed_modules[*]}" + + # Deduplicate the modules using sort -u, so that we pass a concise list of unique modules + # via the Maven `-pl` argument. + if [ ${#changed_modules[@]} -gt 0 ]; then + unique_modules=$(printf '%s\n' "${changed_modules[@]}" | sort -u | paste -sd ',' -) + MODULE_FILTER="-pl ${unique_modules}" + echo "Formatting only changed modules: ${unique_modules}" + fi else - echo "BASE_SHA or HEAD_SHA is empty. Skipping file difference check." + echo "BASE_SHA or HEAD_SHA is empty. Cannot continue linting." + exit 1 fi - + mvn -B -ntp \ - -T 1.5C \ + -T 1C \ + ${MODULE_FILTER} \ com.spotify.fmt:fmt-maven-plugin:check - mvn -B -ntp checkstyle:check@checkstyle + mvn -B -ntp ${MODULE_FILTER} checkstyle:check@checkstyle if [[ -n "${BUILD_SUBDIR}" ]] then From 42303cacecb9494fd3d0fe2402bdf1f8cd87d561 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 26 Feb 2026 17:52:13 -0500 Subject: [PATCH 2/3] ci: inject BASE_SHA and HEAD_SHA into downstream lint jobs and exclude tutorials --- .github/workflows/java-bigquerystorage-ci.yaml | 2 ++ .github/workflows/java-datastore-ci.yaml | 2 ++ .github/workflows/java-logging-ci.yaml | 2 ++ .github/workflows/java-logging-logback-ci.yaml | 2 ++ .kokoro/build.sh | 8 ++++++-- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/java-bigquerystorage-ci.yaml b/.github/workflows/java-bigquerystorage-ci.yaml index d81017876bc3..cc18ae18ca03 100644 --- a/.github/workflows/java-bigquerystorage-ci.yaml +++ b/.github/workflows/java-bigquerystorage-ci.yaml @@ -122,3 +122,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.github/workflows/java-datastore-ci.yaml b/.github/workflows/java-datastore-ci.yaml index 0b080099fabd..a7d612f99595 100644 --- a/.github/workflows/java-datastore-ci.yaml +++ b/.github/workflows/java-datastore-ci.yaml @@ -145,3 +145,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.github/workflows/java-logging-ci.yaml b/.github/workflows/java-logging-ci.yaml index 3cc5805d0eeb..d2c3a6429fe7 100644 --- a/.github/workflows/java-logging-ci.yaml +++ b/.github/workflows/java-logging-ci.yaml @@ -137,3 +137,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.github/workflows/java-logging-logback-ci.yaml b/.github/workflows/java-logging-logback-ci.yaml index 10cf71dfd943..032524284d24 100644 --- a/.github/workflows/java-logging-logback-ci.yaml +++ b/.github/workflows/java-logging-logback-ci.yaml @@ -137,3 +137,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.kokoro/build.sh b/.kokoro/build.sh index baaef9d29a87..ce34727bf1a4 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -199,7 +199,7 @@ case ${JOB_TYPE} in if [ -n "${BASE_SHA}" ] && [ -n "${HEAD_SHA}" ]; then # Optimize the build by identifying ONLY the Maven modules that contain changed Java source files. - # Format those specific modules instead of the entire codebase. + # Format those specific modules instead of the entire codebase, reducing format check time. changed_file_list=$(git diff --name-only "${BASE_SHA}" "${HEAD_SHA}") echo "${changed_file_list}" @@ -231,8 +231,12 @@ case ${JOB_TYPE} in dir=$(dirname "${dir}") done if [ -f "${dir}/pom.xml" ] && [ "${dir}" != "." ]; then - # Filter out samples, directories with no Java source code, and generated protobuf/gRPC code + # Filter out directories not participating in the default formatting reactor: + # - samples/tutorials are wrapped in the include-samples profile + # - proto-*/grpc-* are generated code and should not be formatted manually + # - *-bom/parents are POM-only and contain no Java source if [[ "${dir}" != *"samples"* ]] && \ + [[ "${dir}" != *"tutorials"* ]] && \ [[ "$(basename "${dir}")" != "proto-google-"* ]] && \ [[ "$(basename "${dir}")" != "grpc-google-"* ]] && \ [[ "$(basename "${dir}")" != *"-bom" ]] && \ From 41a14f55c4c1e72f809433306b1a735e5c8fc3e1 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 26 Feb 2026 17:52:13 -0500 Subject: [PATCH 3/3] ci: inject BASE_SHA and HEAD_SHA into downstream lint jobs and exclude tutorials --- .github/workflows/java-bigquerystorage-ci.yaml | 4 ++++ .github/workflows/java-datastore-ci.yaml | 4 ++++ .github/workflows/java-logging-ci.yaml | 4 ++++ .github/workflows/java-logging-logback-ci.yaml | 4 ++++ .kokoro/build.sh | 8 ++++++-- 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/java-bigquerystorage-ci.yaml b/.github/workflows/java-bigquerystorage-ci.yaml index d81017876bc3..2f536ad941fc 100644 --- a/.github/workflows/java-bigquerystorage-ci.yaml +++ b/.github/workflows/java-bigquerystorage-ci.yaml @@ -114,6 +114,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 - uses: actions/setup-java@v2 with: distribution: temurin @@ -122,3 +124,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.github/workflows/java-datastore-ci.yaml b/.github/workflows/java-datastore-ci.yaml index 0b080099fabd..6d9017e8f31f 100644 --- a/.github/workflows/java-datastore-ci.yaml +++ b/.github/workflows/java-datastore-ci.yaml @@ -137,6 +137,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: actions/setup-java@v4 with: distribution: temurin @@ -145,3 +147,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.github/workflows/java-logging-ci.yaml b/.github/workflows/java-logging-ci.yaml index 3cc5805d0eeb..4a357adba8a6 100644 --- a/.github/workflows/java-logging-ci.yaml +++ b/.github/workflows/java-logging-ci.yaml @@ -129,6 +129,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: actions/setup-java@v4 with: distribution: temurin @@ -137,3 +139,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.github/workflows/java-logging-logback-ci.yaml b/.github/workflows/java-logging-logback-ci.yaml index 10cf71dfd943..7d6493242b27 100644 --- a/.github/workflows/java-logging-logback-ci.yaml +++ b/.github/workflows/java-logging-logback-ci.yaml @@ -129,6 +129,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: actions/setup-java@v4 with: distribution: temurin @@ -137,3 +139,5 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: lint + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} diff --git a/.kokoro/build.sh b/.kokoro/build.sh index baaef9d29a87..ce34727bf1a4 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -199,7 +199,7 @@ case ${JOB_TYPE} in if [ -n "${BASE_SHA}" ] && [ -n "${HEAD_SHA}" ]; then # Optimize the build by identifying ONLY the Maven modules that contain changed Java source files. - # Format those specific modules instead of the entire codebase. + # Format those specific modules instead of the entire codebase, reducing format check time. changed_file_list=$(git diff --name-only "${BASE_SHA}" "${HEAD_SHA}") echo "${changed_file_list}" @@ -231,8 +231,12 @@ case ${JOB_TYPE} in dir=$(dirname "${dir}") done if [ -f "${dir}/pom.xml" ] && [ "${dir}" != "." ]; then - # Filter out samples, directories with no Java source code, and generated protobuf/gRPC code + # Filter out directories not participating in the default formatting reactor: + # - samples/tutorials are wrapped in the include-samples profile + # - proto-*/grpc-* are generated code and should not be formatted manually + # - *-bom/parents are POM-only and contain no Java source if [[ "${dir}" != *"samples"* ]] && \ + [[ "${dir}" != *"tutorials"* ]] && \ [[ "$(basename "${dir}")" != "proto-google-"* ]] && \ [[ "$(basename "${dir}")" != "grpc-google-"* ]] && \ [[ "$(basename "${dir}")" != *"-bom" ]] && \