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