diff --git a/.cloudbuild/library_generation/library_generation.Dockerfile b/.cloudbuild/library_generation/library_generation.Dockerfile index e086e961d4..5dc0502e74 100644 --- a/.cloudbuild/library_generation/library_generation.Dockerfile +++ b/.cloudbuild/library_generation/library_generation.Dockerfile @@ -22,7 +22,7 @@ COPY . . ENV DOCKER_GAPIC_GENERATOR_VERSION="2.45.1-SNAPSHOT" # {x-version-update-end} -RUN mvn install -DskipTests -Dclirr.skip -Dcheckstyle.skip +RUN mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip RUN cp "/root/.m2/repository/com/google/api/gapic-generator-java/${DOCKER_GAPIC_GENERATOR_VERSION}/gapic-generator-java-${DOCKER_GAPIC_GENERATOR_VERSION}.jar" \ "./gapic-generator-java.jar" diff --git a/.github/scripts/action.yaml b/.github/scripts/action.yaml new file mode 100644 index 0000000000..cf6a9f6360 --- /dev/null +++ b/.github/scripts/action.yaml @@ -0,0 +1,60 @@ +# Copyright 2024 Google LLC +# +# Licensed 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. +# GitHub action job to test core java library features on +# downstream client libraries before they are released. + +# This composite action should be used in google-cloud-java and handwritten +# libraries to generate changed libraries. +# This composite action serves as a source of truth of scripts that run +# library generation and create pull requests. +name: Hermetic library generation +description: Runs hermetic library generation to produce changed libraries +inputs: + base_ref: + description: base branch + required: true + head_ref: + description: head branch + required: true + image_tag: + description: the tag of hermetic build image + required: false + token: + description: Personal Access Token + required: true + +runs: + using: "composite" + steps: + - name: Copy shell script + shell: bash + run: | + cd ${{ github.action_path }} + cp hermetic_library_generation.sh $GITHUB_WORKSPACE + - name: Generate changed libraries + shell: bash + run: | + set -x + [ -z "$(git config user.email)" ] && git config --global user.email "cloud-java-bot@google.com" + [ -z "$(git config user.name)" ] && git config --global user.name "cloud-java-bot" + cd "${GITHUB_WORKSPACE}" + bash hermetic_library_generation.sh \ + --target_branch "${BASE_REF}" \ + --current_branch "${HEAD_REF}" \ + --image_tag "${IMAGE_TAG}" + env: + BASE_REF: ${{ inputs.base_ref }} + HEAD_REF: ${{ inputs.head_ref }} + IMAGE_TAG: ${{ inputs.image_tag }} + GH_TOKEN: ${{ inputs.token }} diff --git a/.github/scripts/hermetic_library_generation.sh b/.github/scripts/hermetic_library_generation.sh index 861f28d9bd..9294d4f3eb 100755 --- a/.github/scripts/hermetic_library_generation.sh +++ b/.github/scripts/hermetic_library_generation.sh @@ -22,7 +22,8 @@ set -e # The parameters of this script is: # 1. target_branch, the branch into which the pull request is merged. # 2. current_branch, the branch with which the pull request is associated. -# 3. [optional] generation_config, the path to the generation configuration, +# 3. [optional] image_tag, the tag of gcr.io/cloud-devrel-public-resources/java-library-generation. +# 4. [optional] generation_config, the path to the generation configuration, # the default value is generation_config.yaml in the repository root. while [[ $# -gt 0 ]]; do key="$1" @@ -35,6 +36,10 @@ case "${key}" in current_branch="$2" shift ;; + --image_tag) + image_tag="$2" + shift + ;; --generation_config) generation_config="$2" shift @@ -62,7 +67,10 @@ if [ -z "${generation_config}" ]; then echo "Use default generation config: ${generation_config}" fi -image_tag=local +if [ -z "${image_tag}" ]; then + image_tag=$(grep "gapic_generator_version" "${generation_config}" | cut -d ':' -f 2 | xargs) +fi + workspace_name="/workspace" baseline_generation_config="baseline_generation_config.yaml" message="chore: generate libraries at $(date)" @@ -73,31 +81,23 @@ git checkout "${current_branch}" # copy generation configuration from target branch to current branch. git show "${target_branch}":"${generation_config}" > "${baseline_generation_config}" -generator_version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout -pl gapic-generator-java) -echo "Local generator version: ${generator_version}" - -# install generator locally since we're using a SNAPSHOT version. -mvn -V -B -ntp clean install -DskipTests +# get .m2 folder so it's mapped into the docker container +m2_folder=$(dirname "$(mvn help:evaluate -Dexpression=settings.localRepository -q -DforceStdout)") -# build image locally since we want to include latest change. -docker build \ - -f .cloudbuild/library_generation/library_generation.Dockerfile \ - -t gcr.io/cloud-devrel-public-resources/java-library-generation:"${image_tag}" \ - . # run hermetic code generation docker image. docker run \ --rm \ -u "$(id -u):$(id -g)" \ -v "$(pwd):${workspace_name}" \ - -v "$HOME"/.m2:/home/.m2 \ - -e GENERATOR_VERSION="${generator_version}" \ + -v "${m2_folder}":/home/.m2 \ + -e GENERATOR_VERSION="${image_tag}" \ gcr.io/cloud-devrel-public-resources/java-library-generation:"${image_tag}" \ --baseline-generation-config-path="${workspace_name}/${baseline_generation_config}" \ --current-generation-config-path="${workspace_name}/${generation_config}" # commit the change to the pull request. rm -rdf output googleapis "${baseline_generation_config}" -git add --all -- ':!pr_description.txt' +git add --all -- ':!pr_description.txt' ':!hermetic_library_generation.sh' changed_files=$(git diff --cached --name-only) if [[ "${changed_files}" == "" ]]; then echo "There is no generated code change." diff --git a/.github/workflows/hermetic_library_generation.yaml b/.github/workflows/hermetic_library_generation.yaml index 9a2cf40d03..ea29373da3 100644 --- a/.github/workflows/hermetic_library_generation.yaml +++ b/.github/workflows/hermetic_library_generation.yaml @@ -24,24 +24,41 @@ jobs: library_generation: runs-on: ubuntu-latest steps: + - name: Determine whether the pull request comes from a fork + run: | + if [[ "${GITHUB_REPOSITORY}" != "${REPO_FULL_NAME}" ]]; then + echo "This PR comes from a fork. Skip library generation." + echo "SHOULD_RUN=false" >> $GITHUB_ENV + else + echo "SHOULD_RUN=true" >> $GITHUB_ENV + fi - uses: actions/checkout@v4 + if: env.SHOULD_RUN == 'true' with: fetch-depth: 0 token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} - - name: Generate changed libraries + - name: Install Maven modules + if: env.SHOULD_RUN == 'true' shell: bash run: | - set -x - if [[ "${GITHUB_REPOSITORY}" != "${REPO_FULL_NAME}" ]]; then - echo "This PR comes from a fork. Skip library generation." - exit 0 - fi - [ -z "$(git config user.email)" ] && git config --global user.email "cloud-java-bot@google.com" - [ -z "$(git config user.name)" ] && git config --global user.name "cloud-java-bot" - bash .github/scripts/hermetic_library_generation.sh \ - --target_branch "${base_ref}" \ - --current_branch "${head_ref}" + git checkout "${HEAD_REF}" + mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip env: + HEAD_REF: ${{ github.head_ref }} + - name: Build image + if: env.SHOULD_RUN == 'true' + shell: bash + run: | + GENERATOR_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout -pl gapic-generator-java) + echo "GENERATOR_VERSION=${GENERATOR_VERSION}" >> "$GITHUB_ENV" + docker build \ + -f .cloudbuild/library_generation/library_generation.Dockerfile \ + -t gcr.io/cloud-devrel-public-resources/java-library-generation:"${GENERATOR_VERSION}" \ + . + - uses: ./.github/scripts + if: env.SHOULD_RUN == 'true' + with: base_ref: ${{ github.base_ref }} head_ref: ${{ github.head_ref }} - GH_TOKEN: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} + image_tag: ${{ env.GENERATOR_VERSION }} + token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}