From 26319ca50f820923cbbe04ebcf002eed8cbd4398 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 13:29:49 -0400 Subject: [PATCH 1/7] update generate_showcase.sh to use librarian --- java-showcase/scripts/generate_showcase.sh | 84 ++++++++-------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/java-showcase/scripts/generate_showcase.sh b/java-showcase/scripts/generate_showcase.sh index 84e7f31f8570..9bcebc74655b 100755 --- a/java-showcase/scripts/generate_showcase.sh +++ b/java-showcase/scripts/generate_showcase.sh @@ -1,6 +1,5 @@ #!/bin/bash -# Generates the showcase library using the docker image, which is built -# from the current state of the repo in order to test local changes. +# Generates the showcase library using librarian. set -ex echo "******** Generating Showcase ********" @@ -12,11 +11,8 @@ pushd "${ROOT_DIR}" source "${ROOT_DIR}/java-showcase/scripts/showcase_utilities.sh" cleanup() { - if [[ -z "${api_def_dir}" ]]; then - rm -rf "${api_def_dir}" - fi - if [[ -z "${showcase_def_dir}" ]]; then - rm -rf "${showcase_def_dir}" + if [[ -n "${generated_files_dir}" && "${replace}" != "true" ]]; then + rm -rf "${generated_files_dir}" fi } @@ -39,58 +35,40 @@ if [ -z "${replace}" ]; then replace="false" fi - -# download api definitions from googleapis repository -googleapis_commitish=$(grep googleapis_commitish generation_config.yaml | cut -d ":" -f 2 | xargs) -api_def_dir=$(mktemp -d) -git clone https://github.com/googleapis/googleapis.git "${api_def_dir}" - -pushd "${api_def_dir}" -git checkout "${googleapis_commitish}" -# for local setups, we avoid permission issues when the docker image -# performs version-dependent operations. -rm -rf ".git/" -popd - -append_showcase_to_api_defs "${api_def_dir}" - -if [[ -f "image-id" ]]; then - echo "image already exists:" - cat image-id +if command -v librarian &> /dev/null; then + LIBRARIAN_CMD="librarian" else - echo "building docker image" - DOCKER_BUILDKIT=1 docker build --file sdk-platform-java/.cloudbuild/library_generation/library_generation.Dockerfile --iidfile image-id . + LIBRARIAN_CMD="go run github.com/googleapis/librarian/cmd/librarian@latest" fi if [[ "${replace}" == "true" ]]; then - generated_files_dir="${ROOT_DIR}" + echo "generating showcase in place" + $LIBRARIAN_CMD generate showcase else export generated_files_dir=$(mktemp -d) - # here we store the generated library location for upstream scripts to use - # it. + echo "Temp generation directory: ${generated_files_dir}" + + # store the generated library location for verify.sh echo "${generated_files_dir}/java-showcase" > "${ROOT_DIR}/generated-showcase-location" - # we prepare the temp folder with the minimal setup to perform an incremental - # generation. - pushd "${ROOT_DIR}" - cp -r generation_config.yaml java-showcase/ versions.txt "${generated_files_dir}" - popd #ROOT_DIR + + # Symlink all contents of root directory except java-showcase and librarian.yaml + for item in "${ROOT_DIR}"/*; do + name=$(basename "$item") + if [[ "$name" != "java-showcase" && "$name" != "librarian.yaml" ]]; then + ln -s "$item" "${generated_files_dir}/${name}" + fi + done + + # Copy librarian.yaml and java-showcase to the temp directory + cp -r "${ROOT_DIR}/librarian.yaml" "${ROOT_DIR}/java-showcase" "${generated_files_dir}/" + + # Convert local paths in librarian.yaml to absolute paths + sed -i "s|local_path: sdk-platform-java|local_path: ${ROOT_DIR}/sdk-platform-java|g" "${generated_files_dir}/librarian.yaml" + + # Run librarian generate from the temp workspace + pushd "${generated_files_dir}" + $LIBRARIAN_CMD generate showcase + popd fi -pushd sdk-platform-java -GENERATOR_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout -pl gapic-generator-java) -popd - -echo "generating showcase" -workspace_name="/workspace" -docker run \ - --rm \ - -u "$(id -u):$(id -g)" \ - -v "${generated_files_dir}:${workspace_name}" \ - -v "${api_def_dir}:${workspace_name}/googleapis" \ - -e GENERATOR_VERSION="${GENERATOR_VERSION}" \ - "$(cat image-id)" \ - --generation-config-path="${workspace_name}/generation_config.yaml" \ - --library-names="showcase" \ - --api-definitions-path="${workspace_name}/googleapis" - -echo "generated showcase library in ${generated_files_dir}" +echo "generated showcase library" From 0379c8eb3513b5c5db591b9e1da9b1ab9e80b769 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 13:56:09 -0400 Subject: [PATCH 2/7] update workflow and readme --- .github/workflows/showcase.yaml | 23 +++++++++++++++++ java-showcase/README.md | 30 ++++++++++++++++++---- java-showcase/scripts/generate_showcase.sh | 3 +++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/.github/workflows/showcase.yaml b/.github/workflows/showcase.yaml index bb9901619966..cbef4e59e829 100644 --- a/.github/workflows/showcase.yaml +++ b/.github/workflows/showcase.yaml @@ -115,6 +115,29 @@ jobs: env: BUILD_SUBDIR: sdk-platform-java JOB_TYPE: install + - uses: actions/setup-go@v5 + with: + go-version: 'stable' + - name: Install protoc + run: | + set -e + VERSION="33.2" + curl -fsSL --retry 5 --retry-delay 15 -o /tmp/protoc.zip "https://github.com/protocolbuffers/protobuf/releases/download/v$VERSION/protoc-$VERSION-linux-x86_64.zip" + cd /usr/local + sudo unzip -o /tmp/protoc.zip + protoc --version + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: 'pip' + - name: Install Librarian and tools + env: + PYTHONPATH: ${{ github.workspace }}/sdk-platform-java/hermetic_build/library_generation/owlbot + run: | + V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) + echo "Installing librarian version $V" + go install github.com/googleapis/librarian/cmd/librarian@$V + librarian install - name: Showcase golden tests working-directory: java-showcase run: | diff --git a/java-showcase/README.md b/java-showcase/README.md index 0c0fd75acd2f..a91a3e5cf8f6 100644 --- a/java-showcase/README.md +++ b/java-showcase/README.md @@ -7,7 +7,8 @@ the Showcase API which can communicate with a local Showcase server to perform i ## Requirements -* Install [Go](https://go.dev) in your `PATH`. +* Install [Go](https://go.dev) in your `PATH` (version 1.20 or later). +* Install the [protoc](https://github.com/protocolbuffers/protobuf/releases) compiler in your `PATH`. ## Installing the Server @@ -73,8 +74,26 @@ mvn verify -P enable-integration-tests ## Running the Golden tests -**NOTE** This requires Docker to be installed in your machine. -Open a new terminal window in the root project directory. +This verify check compares the current checked-in files in `java-showcase` against a newly generated client. + +### Prerequisites (One-time Setup) +Make sure you have **Go** and **protoc** installed and available in your `PATH` (see the [Requirements](#requirements) section), then run the following setup steps from the repository root: + +```shell +# Setup and activate Python virtual environment +python -m venv .venv +source .venv/bin/activate + +# Configure pip for external sources +pip config set global.extra-index-url https://pypi.org/simple + +# Install and configure Java tools (takes around 5 mins) +V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) +go run github.com/googleapis/librarian/cmd/librarian@${V} install +``` + +### Running the tests +Once the prerequisites are installed and the virtual environment is activated, run: ```shell cd java-showcase @@ -84,8 +103,9 @@ mvn verify -P enable-golden-tests ## Update the Golden Showcase Files -**NOTE** This requires Docker to be installed in your machine. -Open a new terminal window in the root project directory. +To regenerate the showcase library files and update them in place: + +Make sure the Python virtual environment is activated, then run: ```shell # In repository's root directory diff --git a/java-showcase/scripts/generate_showcase.sh b/java-showcase/scripts/generate_showcase.sh index 9bcebc74655b..8eecdfeb16f6 100755 --- a/java-showcase/scripts/generate_showcase.sh +++ b/java-showcase/scripts/generate_showcase.sh @@ -7,6 +7,7 @@ echo "******** Generating Showcase ********" trap cleanup ERR readonly ROOT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/../.." +export PYTHONPATH="${ROOT_DIR}/sdk-platform-java/hermetic_build/library_generation/owlbot" pushd "${ROOT_DIR}" source "${ROOT_DIR}/java-showcase/scripts/showcase_utilities.sh" @@ -44,6 +45,8 @@ fi if [[ "${replace}" == "true" ]]; then echo "generating showcase in place" $LIBRARIAN_CMD generate showcase + # Discard changes to root POM and BOM POM files modified by Librarian's Java post-processor + git restore "${ROOT_DIR}/pom.xml" "${ROOT_DIR}/gapic-libraries-bom/pom.xml" || true else export generated_files_dir=$(mktemp -d) echo "Temp generation directory: ${generated_files_dir}" From accd37133c51ab7ef2651ff7fe63396d10b94a0f Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 14:47:34 -0400 Subject: [PATCH 3/7] simplify scripts by removing flag --- java-showcase/pom.xml | 2 - java-showcase/scripts/generate_showcase.sh | 72 +++------------------- java-showcase/scripts/verify.sh | 21 +++---- 3 files changed, 17 insertions(+), 78 deletions(-) diff --git a/java-showcase/pom.xml b/java-showcase/pom.xml index c6a9a0352f57..73ba577a62d1 100644 --- a/java-showcase/pom.xml +++ b/java-showcase/pom.xml @@ -251,8 +251,6 @@ bash scripts/generate_showcase.sh - --replace - true diff --git a/java-showcase/scripts/generate_showcase.sh b/java-showcase/scripts/generate_showcase.sh index 8eecdfeb16f6..6b3d962c79b4 100755 --- a/java-showcase/scripts/generate_showcase.sh +++ b/java-showcase/scripts/generate_showcase.sh @@ -4,74 +4,16 @@ set -ex echo "******** Generating Showcase ********" -trap cleanup ERR - readonly ROOT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/../.." +# Export PYTHONPATH so that owlbot.py scripts run by Librarian +# can resolve local synthtool under the hermetic build directory. export PYTHONPATH="${ROOT_DIR}/sdk-platform-java/hermetic_build/library_generation/owlbot" -pushd "${ROOT_DIR}" -source "${ROOT_DIR}/java-showcase/scripts/showcase_utilities.sh" - -cleanup() { - if [[ -n "${generated_files_dir}" && "${replace}" != "true" ]]; then - rm -rf "${generated_files_dir}" - fi -} - -while [[ $# -gt 0 ]]; do -key="$1" -case "${key}" in - --replace) - replace="$2" - shift - ;; - *) - echo "Invalid option: [$1]" - exit 1 - ;; -esac -shift -done - -if [ -z "${replace}" ]; then - replace="false" -fi +cd "${ROOT_DIR}" -if command -v librarian &> /dev/null; then - LIBRARIAN_CMD="librarian" -else - LIBRARIAN_CMD="go run github.com/googleapis/librarian/cmd/librarian@latest" -fi +readonly LIBRARIAN_VER=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) +readonly LIBRARIAN_CMD="go run github.com/googleapis/librarian/cmd/librarian@${LIBRARIAN_VER}" -if [[ "${replace}" == "true" ]]; then - echo "generating showcase in place" - $LIBRARIAN_CMD generate showcase - # Discard changes to root POM and BOM POM files modified by Librarian's Java post-processor - git restore "${ROOT_DIR}/pom.xml" "${ROOT_DIR}/gapic-libraries-bom/pom.xml" || true -else - export generated_files_dir=$(mktemp -d) - echo "Temp generation directory: ${generated_files_dir}" - - # store the generated library location for verify.sh - echo "${generated_files_dir}/java-showcase" > "${ROOT_DIR}/generated-showcase-location" - - # Symlink all contents of root directory except java-showcase and librarian.yaml - for item in "${ROOT_DIR}"/*; do - name=$(basename "$item") - if [[ "$name" != "java-showcase" && "$name" != "librarian.yaml" ]]; then - ln -s "$item" "${generated_files_dir}/${name}" - fi - done - - # Copy librarian.yaml and java-showcase to the temp directory - cp -r "${ROOT_DIR}/librarian.yaml" "${ROOT_DIR}/java-showcase" "${generated_files_dir}/" - - # Convert local paths in librarian.yaml to absolute paths - sed -i "s|local_path: sdk-platform-java|local_path: ${ROOT_DIR}/sdk-platform-java|g" "${generated_files_dir}/librarian.yaml" - - # Run librarian generate from the temp workspace - pushd "${generated_files_dir}" - $LIBRARIAN_CMD generate showcase - popd -fi +echo "generating showcase in place" +$LIBRARIAN_CMD generate showcase echo "generated showcase library" diff --git a/java-showcase/scripts/verify.sh b/java-showcase/scripts/verify.sh index 4a75ceb6e777..f21f8d5a4f68 100755 --- a/java-showcase/scripts/verify.sh +++ b/java-showcase/scripts/verify.sh @@ -1,21 +1,20 @@ #!/bin/sh -# This script generates showcase in a temporary/untracked folder and compares -# its contents with the actual showcase libraries. +# This script generates showcase in place and checks for git diffs to verify. echo "******** Verifying Showcase ********" set -oxe readonly SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) readonly ROOT_DIR="${SCRIPT_DIR}/../.." -source "${SCRIPT_DIR}/showcase_utilities.sh" readonly SHOWCASE_DIR="${SCRIPT_DIR}/.." +readonly GENERATED_DIRS="${SHOWCASE_DIR}/gapic-showcase/src/main ${SHOWCASE_DIR}/grpc-gapic-showcase-v1beta1/src/main ${SHOWCASE_DIR}/proto-gapic-showcase-v1beta1/src/main" -# generate sources -bash "${SCRIPT_DIR}/generate_showcase.sh" --replace "false" +# generate sources in place +bash "${SCRIPT_DIR}/generate_showcase.sh" -generated_library_location=$(cat "${ROOT_DIR}/generated-showcase-location") - -# compare library -diff -ru "${SHOWCASE_DIR}/" "${generated_library_location}" - -cleanup $SCRIPT_DIR +# check if there are changes in generated directories +if [ -n "$(git status --porcelain ${GENERATED_DIRS})" ]; then + git diff ${GENERATED_DIRS} + echo "Error: Showcase generated files are out of sync. Please run 'mvn compile -P update' inside java-showcase to update them." + exit 1 +fi From a77c2ebe74937050755211469b8d9c254d5a9320 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 15:22:14 -0400 Subject: [PATCH 4/7] fix verify.sh --- java-showcase/scripts/verify.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-showcase/scripts/verify.sh b/java-showcase/scripts/verify.sh index f21f8d5a4f68..cda360c98e3b 100755 --- a/java-showcase/scripts/verify.sh +++ b/java-showcase/scripts/verify.sh @@ -1,9 +1,9 @@ -#!/bin/sh +#!/bin/bash # This script generates showcase in place and checks for git diffs to verify. echo "******** Verifying Showcase ********" -set -oxe +set -ex readonly SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) readonly ROOT_DIR="${SCRIPT_DIR}/../.." readonly SHOWCASE_DIR="${SCRIPT_DIR}/.." From f497c9e114ea81cca7e131d9903e661cceebd929 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 16:49:44 -0400 Subject: [PATCH 5/7] use java 17 for code generation --- .github/workflows/showcase.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/showcase.yaml b/.github/workflows/showcase.yaml index cbef4e59e829..ba670a1fa5cf 100644 --- a/.github/workflows/showcase.yaml +++ b/.github/workflows/showcase.yaml @@ -138,6 +138,11 @@ jobs: echo "Installing librarian version $V" go install github.com/googleapis/librarian/cmd/librarian@$V librarian install + - name: Setup Java 17 for Golden Tests + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin - name: Showcase golden tests working-directory: java-showcase run: | @@ -145,6 +150,11 @@ jobs: -P enable-golden-tests \ --batch-mode \ --no-transfer-progress + - name: Restore Matrix Java + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: temurin - name: Parse showcase version working-directory: java-showcase/gapic-showcase run: echo "SHOWCASE_VERSION=$(mvn help:evaluate -Dexpression=gapic-showcase.version -q -DforceStdout)" >> "$GITHUB_ENV" From 81b12c67dfb6d134fa9327e9be194b93a2847857 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 16:55:30 -0400 Subject: [PATCH 6/7] restrict pip config to active virtual environment --- java-showcase/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-showcase/README.md b/java-showcase/README.md index a91a3e5cf8f6..3edf3fd28e84 100644 --- a/java-showcase/README.md +++ b/java-showcase/README.md @@ -85,7 +85,7 @@ python -m venv .venv source .venv/bin/activate # Configure pip for external sources -pip config set global.extra-index-url https://pypi.org/simple +pip config --venv set global.extra-index-url https://pypi.org/simple # Install and configure Java tools (takes around 5 mins) V=$(go run github.com/googleapis/librarian/cmd/librarian@latest config get version) From a4e488e7bf0facb960745189c40f9e1803a53c4a Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 29 Jun 2026 17:20:30 -0400 Subject: [PATCH 7/7] check all java-showcase in test and clarify need clean git tree in README --- java-showcase/README.md | 2 ++ java-showcase/scripts/verify.sh | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java-showcase/README.md b/java-showcase/README.md index 3edf3fd28e84..5c9d2b0b0f95 100644 --- a/java-showcase/README.md +++ b/java-showcase/README.md @@ -100,6 +100,8 @@ cd java-showcase mvn verify -P enable-golden-tests ``` +> [!IMPORTANT] +> The golden tests run the generator and compare the entire `java-showcase` directory against the newly generated state using `git diff`. For these tests to pass, you must have a completely clean git tree within the `java-showcase` directory before running them. Any uncommitted changes or untracked files will cause the tests to fail. ## Update the Golden Showcase Files diff --git a/java-showcase/scripts/verify.sh b/java-showcase/scripts/verify.sh index cda360c98e3b..213b1de9165d 100755 --- a/java-showcase/scripts/verify.sh +++ b/java-showcase/scripts/verify.sh @@ -7,14 +7,12 @@ set -ex readonly SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) readonly ROOT_DIR="${SCRIPT_DIR}/../.." readonly SHOWCASE_DIR="${SCRIPT_DIR}/.." -readonly GENERATED_DIRS="${SHOWCASE_DIR}/gapic-showcase/src/main ${SHOWCASE_DIR}/grpc-gapic-showcase-v1beta1/src/main ${SHOWCASE_DIR}/proto-gapic-showcase-v1beta1/src/main" - # generate sources in place bash "${SCRIPT_DIR}/generate_showcase.sh" -# check if there are changes in generated directories -if [ -n "$(git status --porcelain ${GENERATED_DIRS})" ]; then - git diff ${GENERATED_DIRS} +# check if there are changes in java-showcase directory +if [ -n "$(git status --porcelain ${SHOWCASE_DIR})" ]; then + git diff ${SHOWCASE_DIR} echo "Error: Showcase generated files are out of sync. Please run 'mvn compile -P update' inside java-showcase to update them." exit 1 fi