feat: enable hermetic library generation (#2515) · googleapis/java-bigquerystorage@e1b14c1
1+#!/bin/bash
2+set -e
3+# This script should be run at the root of the repository.
4+# This script is used to, when a pull request changes the generation
5+# configuration (generation_config.yaml by default):
6+# 1. Find whether the last commit in this pull request contains changes to
7+# the generation configuration and exit early if it doesn't have such a change
8+# since the generation result would be the same.
9+# 2. Compare generation configurations in the current branch (with which the
10+# pull request associated) and target branch (into which the pull request is
11+# merged);
12+# 3. Generate changed libraries using library_generation image;
13+# 4. Commit the changes to the pull request, if any.
14+# 5. Edit the PR body with generated pull request description, if applicable.
15+16+# The following commands need to be installed before running the script:
17+# 1. git
18+# 2. gh
19+# 3. docker
20+21+# The parameters of this script is:
22+# 1. target_branch, the branch into which the pull request is merged.
23+# 2. current_branch, the branch with which the pull request is associated.
24+# 3. [optional] generation_config, the path to the generation configuration,
25+# the default value is generation_config.yaml in the repository root.
26+while [[ $# -gt 0 ]]; do
27+key="$1"
28+case "${key}" in
29+ --target_branch)
30+ target_branch="$2"
31+shift
32+ ;;
33+ --current_branch)
34+ current_branch="$2"
35+shift
36+ ;;
37+ --generation_config)
38+ generation_config="$2"
39+shift
40+ ;;
41+*)
42+echo "Invalid option: [$1]"
43+exit 1
44+ ;;
45+esac
46+shift
47+done
48+49+if [ -z "${target_branch}" ]; then
50+echo "missing required argument --target_branch"
51+exit 1
52+fi
53+54+if [ -z "${current_branch}" ]; then
55+echo "missing required argument --current_branch"
56+exit 1
57+fi
58+59+if [ -z "${generation_config}" ]; then
60+ generation_config=generation_config.yaml
61+echo "Using default generation config: ${generation_config}"
62+fi
63+64+workspace_name="/workspace"
65+baseline_generation_config="baseline_generation_config.yaml"
66+message="chore: generate libraries at $(date)"
67+68+git checkout "${target_branch}"
69+git checkout "${current_branch}"
70+# if the last commit doesn't contain changes to generation configuration,
71+# do not generate again as the result will be the same.
72+change_of_last_commit="$(git diff-tree --no-commit-id --name-only HEAD~1..HEAD -r)"
73+if [[ ! ("${change_of_last_commit}" == *"${generation_config}"*) ]]; then
74+echo "The last commit doesn't contain any changes to the generation_config.yaml, skipping the whole generation process." || true
75+exit 0
76+fi
77+# copy generation configuration from target branch to current branch.
78+git show "${target_branch}":"${generation_config}" > "${baseline_generation_config}"
79+config_diff=$(diff "${generation_config}" "${baseline_generation_config}" || true)
80+81+# parse image tag from the generation configuration.
82+image_tag=$(grep "gapic_generator_version" "${generation_config}" | cut -d ':' -f 2 | xargs)
83+84+# run hermetic code generation docker image.
85+docker run \
86+ --rm \
87+ -u "$(id -u):$(id -g)" \
88+ -v "$(pwd):${workspace_name}" \
89+ gcr.io/cloud-devrel-public-resources/java-library-generation:"${image_tag}" \
90+ --baseline-generation-config-path="${workspace_name}/${baseline_generation_config}" \
91+ --current-generation-config-path="${workspace_name}/${generation_config}"
92+93+94+# commit the change to the pull request.
95+if [[ $(basename $(pwd)) == "google-cloud-java" ]]; then
96+ git add java-* pom.xml gapic-libraries-bom/pom.xml versions.txt
97+else
98+# The image leaves intermediate folders and files it works with. Here we remove them
99+ rm -rdf output googleapis "${baseline_generation_config}"
100+ git add --all -- ':!pr_description.txt'
101+fi
102+changed_files=$(git diff --cached --name-only)
103+if [[ "${changed_files}" == "" ]]; then
104+echo "There is no generated code change with the generation config change ${config_diff}."
105+echo "Skip committing to the pull request."
106+exit 0
107+fi
108+109+echo "Configuration diff:"
110+echo "${config_diff}"
111+git commit -m "${message}"
112+git push
113+# set pr body if pr_description.txt is generated.
114+if [[ -f "pr_description.txt" ]]; then
115+ pr_num=$(gh pr list -s open -H "${current_branch}" -q . --json number | jq ".[] | .number")
116+ gh pr edit "${pr_num}" --body "$(cat pr_description.txt)"
117+fi