Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add a composite action for library generation #3173

Merged
merged 60 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
076221c
chore: add a reusable workflow for library generation
JoeWang1127 Sep 6, 2024
e854d12
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 6, 2024
1148792
add a prefix
JoeWang1127 Sep 6, 2024
c80e706
change location
JoeWang1127 Sep 6, 2024
6705561
change to composite workflow
JoeWang1127 Sep 6, 2024
d31aa8f
change action path
JoeWang1127 Sep 6, 2024
3849f7d
change var
JoeWang1127 Sep 6, 2024
6263393
change path
JoeWang1127 Sep 6, 2024
3588cee
do not need local install
JoeWang1127 Sep 6, 2024
814b059
change var
JoeWang1127 Sep 6, 2024
80396c0
change mvn command
JoeWang1127 Sep 6, 2024
c17ca6f
set debug
JoeWang1127 Sep 6, 2024
838dab9
add steps
JoeWang1127 Sep 6, 2024
44a4c35
change env
JoeWang1127 Sep 6, 2024
925b7c5
do not clean
JoeWang1127 Sep 6, 2024
541964d
remove double checkout
JoeWang1127 Sep 6, 2024
e3063d7
separate logic
JoeWang1127 Sep 7, 2024
c9cb986
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 7, 2024
be7329b
map m2 folder
JoeWang1127 Sep 7, 2024
12001b0
mvn install
JoeWang1127 Sep 7, 2024
1e1dd1e
do not commit
JoeWang1127 Sep 7, 2024
490ce12
parse image tag from config
JoeWang1127 Sep 7, 2024
d061b2c
change script
JoeWang1127 Sep 7, 2024
87d771f
change comment
JoeWang1127 Sep 8, 2024
87cceb3
create a reusable workflow
JoeWang1127 Sep 8, 2024
98d34cc
change indentation
JoeWang1127 Sep 8, 2024
d2ec86c
remove env
JoeWang1127 Sep 8, 2024
da83076
remove reusable workflow
JoeWang1127 Sep 8, 2024
5e18991
change action path
JoeWang1127 Sep 9, 2024
2dc8cb9
remove debug
JoeWang1127 Sep 9, 2024
e0bec4d
change path
JoeWang1127 Sep 9, 2024
b7eadcc
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 9, 2024
f58ce70
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 9, 2024
b16e270
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 9, 2024
8f02497
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 10, 2024
904d8ad
change dir
JoeWang1127 Sep 10, 2024
8a5d21a
add inputs
JoeWang1127 Sep 10, 2024
3e912b4
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 10, 2024
8e0824c
add inputs
JoeWang1127 Sep 10, 2024
3b3a73b
combine step
JoeWang1127 Sep 10, 2024
0a5ec38
change env
JoeWang1127 Sep 10, 2024
efa2952
populate env
JoeWang1127 Sep 10, 2024
ada44f7
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 10, 2024
b09661f
use composite action
JoeWang1127 Sep 10, 2024
c5b39d2
change path
JoeWang1127 Sep 10, 2024
df5e9c7
add image tag
JoeWang1127 Sep 10, 2024
71e5613
change doc
JoeWang1127 Sep 10, 2024
fe3fb3a
remove local install
JoeWang1127 Sep 10, 2024
6aaa63b
restore local install
JoeWang1127 Sep 10, 2024
e1bcea7
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 10, 2024
0f7cc38
remove prerequisite
JoeWang1127 Sep 10, 2024
3a8fe92
change step name
JoeWang1127 Sep 10, 2024
f71f1f3
add a separate job to check the fork
JoeWang1127 Sep 10, 2024
dda2767
debug
JoeWang1127 Sep 10, 2024
e2f01e2
add output
JoeWang1127 Sep 10, 2024
bbf05a8
add comment
JoeWang1127 Sep 10, 2024
764327c
add a check step, rather than a job
JoeWang1127 Sep 11, 2024
d8f7c6b
add a if
JoeWang1127 Sep 11, 2024
ffb6463
use full name
JoeWang1127 Sep 11, 2024
f6c764f
Merge branch 'main' into chore/add-reusable-workflow
JoeWang1127 Sep 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
60 changes: 60 additions & 0 deletions .github/scripts/action.yaml
blakeli0 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -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: PAT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is PAT?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personal access token.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the full name instead of abbreviations since it's not common? See style guide.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to full name.

required: true

runs:
using: "composite"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't use reusable workflow because, even though the reusable workflow defined here, the context of the runner is associated with the caller workflow.

When a reusable workflow is triggered by a caller workflow, the github context is always associated with the caller workflow. See https://docs.github.com/en/actions/sharing-automations/reusing-workflows#overview

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So looks like we are just reusing the scripts not the workflow? If that's the case, maybe we just bake the scripts into the image?

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 }}
30 changes: 15 additions & 15 deletions .github/scripts/hermetic_library_generation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -35,6 +36,10 @@ case "${key}" in
current_branch="$2"
shift
;;
--image_tag)
image_tag="$2"
shift
;;
--generation_config)
generation_config="$2"
shift
Expand Down Expand Up @@ -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)"
Expand All @@ -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 \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need to volume m2 folder now that generator is baked in?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to remove it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So .m2 is still needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I removed this line, the build failed, please see #3173 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is a special case of sdk-platform-java because it depends on snapshot jars

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From offline discussion, we are dependent on mvn fmt:format, hence a local .m2 volumn is needed. This will be baked into the docker image soon.

-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."
Expand Down
41 changes: 29 additions & 12 deletions .github/workflows/hermetic_library_generation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,41 @@ jobs:
library_generation:
runs-on: ubuntu-latest
steps:
- name: Determine whether the pull request comes from a fork
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I keep this step to prevent this workflow runs in a fork.

The workflow will fail if it's a fork and it can prevent us from setting this workflow as required, e.g., renovate PR will be blocked by the failure.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to exit the workflow early so we don't have to pass this env to all the subsequent steps?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like another way of skipping steps is creating a separate job and make the generation job depends on that, just like what we've done in unit/integration tests.

I'll keep it as-is now.

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)
JoeWang1127 marked this conversation as resolved.
Show resolved Hide resolved
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 }}
Loading