Skip to content

Commit

Permalink
ci: add downstream compatibility checks (#1909)
Browse files Browse the repository at this point in the history
* ci: add downstream compatibility checks

* ci: add downstream compatibility github actions job

* ci: install xmllint

* ci: install xmllint

* ci: install xmllint

* ci: provide default REPOS_UNDER_TEST value

* ci: exit script in google-cloud-java directory

* ci: split downstream compatibility into parallel tests

* ci: reduce log noise from sdk-platform-java install step

* ci: don't fail fast in downstream testing

* ci: perform downstream testing on last release, not HEAD

* chore: improve comments

* ci: add tests for helper scripts
  • Loading branch information
burkedavison authored Aug 17, 2023
1 parent a18fe80 commit f86eca2
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 41 deletions.
38 changes: 37 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ jobs:
mvn clirr:check -B -ntp -Dclirr.skip=false -DcomparisonVersion=$SHOWCASE_CLIENT_VERSION
gapic-generator-java-bom:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
Expand All @@ -285,3 +285,39 @@ jobs:
uses: googleapis/java-cloud-bom/tests/[email protected]
with:
bom-path: gapic-generator-java-bom/pom.xml

downstream-compatibility:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
repo:
- google-cloud-java
- java-bigtable
- java-bigquery
- java-bigquerystorage
- java-datastore
- java-firestore
- java-logging
- java-logging-logback
- java-pubsub
- java-pubsublite
- java-spanner-jdbc
- java-spanner
- java-storage
- java-storage-nio
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
java-version: 17
distribution: temurin
- run: mvn -version
- name: Install xmllint
run: |
sudo apt-get update
sudo apt-get -y install libxml2-utils
- name: Test helper scripts
run: ./.kokoro/presubmit/common_test.sh
- name: Perform downstream compatibility testing
run: REPOS_UNDER_TEST="${{ matrix.repo }}" ./.kokoro/presubmit/downstream-compatibility.sh
89 changes: 89 additions & 0 deletions .kokoro/presubmit/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash
# Copyright 2023 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.

# In the given directory ($1),
# update the pom.xml's dependency on the given artifact ($2) to the given version ($3)
# ex: update_dependency google-cloud-java/google-cloud-jar-parent google-cloud-shared-dependencies 1.2.3
function update_pom_dependency {
pushd "$1" || exit 1
xmllint --shell pom.xml &>/dev/null <<EOF
setns x=http://maven.apache.org/POM/4.0.0
cd .//x:artifactId[text()="$2"]
cd ../x:version
set $3
save pom.xml
EOF
popd || exit 1
}

# Find all pom.xml files that declare a specific version for the given artifact ($1)
function find_all_poms_with_versioned_dependency {
poms=($(find . -name pom.xml))
for pom in "${poms[@]}"; do
if xmllint --xpath "//*[local-name()='artifactId' and text()='$1']/following-sibling::*[local-name()='version']" "$pom" &>/dev/null; then
found+=("$pom")
fi
done
POMS=(${found[@]})
unset found
export POMS
}

# In the given directory ($1),
# find and update all pom.xmls' dependencies on the given artifact ($2) to the given version ($3)
# ex: update_all_poms_dependency google-cloud-java google-cloud-shared-dependencies 1.2.3
function update_all_poms_dependency {
pushd "$1" || exit 1
find_all_poms_with_versioned_dependency "$2"
for pom in $POMS; do
update_pom_dependency "$(dirname "$pom")" "$2" "$3"
done
git diff
popd || exit 1
}

# Parse the version of the pom.xml file in the given directory ($1)
# ex: VERSION=$(parse_pom_version java-shared-dependencies)
function parse_pom_version {
# Namespace (xmlns) prevents xmllint from specifying tag names in XPath
result=$(sed -e 's/xmlns=".*"//' "$1/pom.xml" | xmllint --xpath '/project/version/text()' -)

if [ -z "${result}" ]; then
echo "Version is not found in $1"
exit 1
fi
echo "$result"
}

# ex: find_last_release_version java-bigtable
# ex: find_last_release_version java-storage 2.22.x
function find_last_release_version {
branch=${2-"main"} # Default to using main branch
curl -s -o "versions_$1.txt" "https://raw.githubusercontent.com/googleapis/$1/$branch/versions.txt"

# First check to see if there's an entry for the overall repo. Used for google-cloud-java.
primary_artifact=$(grep -E "^$1" "versions_$1.txt" | head -n 1)
if [ -z "$primary_artifact" ]; then
# Otherwise, use the first google-cloud-* artifact's version.
primary_artifact=$(grep -E "^google-cloud-" "versions_$1.txt" | head -n 1)
fi
if [ -z "$primary_artifact" ]; then
echo "Unable to identify primary artifact for $1"
exit 1
fi

parts=($(echo "$primary_artifact" | tr ":" "\n"))
echo "${parts[1]}"
}
80 changes: 80 additions & 0 deletions .kokoro/presubmit/common_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/bin/bash
# Copyright 2023 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.

scriptDir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
cd "${scriptDir}/../.." # cd to the root of this repo
source "$scriptDir/common.sh"
mkdir -p target
cd target

function test_find_all_poms_with_versioned_dependency {
mkdir -p test_find_all_poms_with_dependency
pushd test_find_all_poms_with_dependency
cp ../../showcase/gapic-showcase/pom.xml pom.xml

find_all_poms_with_versioned_dependency 'truth'
if [ "${#POMS[@]}" != 1 ]; then
echo 'find_all_poms_with_versioned_dependency did not find the expected pom'
exit 1
elif [ "${POMS[0]}" != './pom.xml' ]; then
echo "find_all_poms_with_versioned_dependency found ${POMS[0]} instead of expected ./pom.xml"
exit 1
fi

find_all_poms_with_versioned_dependency 'gax-grpc' # Versioned by shared-deps
if [ "${#POMS[@]}" != 0 ]; then
echo 'find_all_poms_with_versioned_dependency found unexpected pom'
exit 1
fi

popd
}

function test_update_pom_dependency {
mkdir -p test_update_pom_dependency
pushd test_update_pom_dependency
cp ../../showcase/gapic-showcase/pom.xml pom.xml

update_pom_dependency . truth "99.88.77"

xmllint --shell pom.xml &>/dev/null <<EOF
setns x=http://maven.apache.org/POM/4.0.0
cd .//x:artifactId[text()="truth"]
cd ../x:version
write found-version.txt
EOF
if ! grep 99.88.77 found-version.txt &>/dev/null; then
echo "update_pom_dependency failed to change version to expected value."
exit 1
fi
rm found-version.txt
popd
}

function test_parse_pom_version {
mkdir -p test_parse_pom_version
pushd test_parse_pom_version
cp ../../showcase/gapic-showcase/pom.xml pom.xml

VERSION=$(parse_pom_version .)
if [ "$VERSION" != "0.0.1-SNAPSHOT" ]; then
echo "parse_pom_version failed to read expected version of gapic-showcase."
fi
popd
}

test_find_all_poms_with_versioned_dependency
test_update_pom_dependency
test_parse_pom_version
61 changes: 21 additions & 40 deletions .kokoro/presubmit/downstream-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@

set -eo pipefail

## Get the directory of the build script
scriptDir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
## cd to the parent directory, i.e. the root of the git repo
cd "${scriptDir}/../.."

if [ -z "${MODULES_UNDER_TEST}" ]; then
echo "MODULES_UNDER_TEST must be set to run downstream-build.sh"
exit 1
fi
# Use default value for REPOS_UNDER_TEST if unset. If set to empty string, maintain empty string.
#
# java-storage is currently the only downstream repo that doesn't require cloud resources for its
# GraalVM integration tests.
REPOS_UNDER_TEST=${REPOS_UNDER_TEST-"java-storage"}

## Get the directory of the build script
scriptDir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
cd "${scriptDir}/../.." # git repo root
source "$scriptDir/common.sh"

# Use GCP Maven Mirror
mkdir -p "${HOME}/.m2"
Expand All @@ -34,60 +39,36 @@ cp settings.xml "${HOME}/.m2"
mvn -B -ntp install --projects '!gapic-generator-java' \
-Dcheckstyle.skip -Dfmt.skip -DskipTests

# Read the shared dependencies version
# Namespace (xmlns) prevents xmllint from specifying tag names in XPath
SHARED_DEPS_VERSION=$(sed -e 's/xmlns=".*"//' java-shared-dependencies/pom.xml | xmllint --xpath '/project/version/text()' -)

if [ -z "${SHARED_DEPS_VERSION}" ]; then
echo "Shared dependencies version is not found in pom.xml"
exit 1
fi

### Round 2
# Update the shared-dependencies version in google-cloud-jar-parent
git clone "https://github.com/googleapis/google-cloud-java.git" --depth=1
pushd google-cloud-java/google-cloud-jar-parent
xmllint --shell pom.xml <<EOF
setns x=http://maven.apache.org/POM/4.0.0
cd .//x:artifactId[text()="google-cloud-shared-dependencies"]
cd ../x:version
set ${SHARED_DEPS_VERSION}
save pom.xml
EOF
SHARED_DEPS_VERSION=$(parse_pom_version java-shared-dependencies)

echo "Modifications to java-shared-dependencies:"
git diff
echo
popd

### Round 3
# Run showcase tests in GraalVM
### Round 2 : Run showcase integration tests in GraalVM
pushd showcase/gapic-showcase
SHOWCASE_VERSION=$(mvn help:evaluate -Dexpression=gapic-showcase.version -q -DforceStdout)
popd

# Start showcase server
mkdir -p /usr/src/showcase
curl --location https://github.com/googleapis/gapic-showcase/releases/download/v"${SHOWCASE_VERSION}"/gapic-showcase-"${SHOWCASE_VERSION}"-linux-amd64.tar.gz --output /usr/src/showcase/showcase-"${SHOWCASE_VERSION}"-linux-amd64.tar.gz
pushd /usr/src/showcase/
tar -xf showcase-*
./gapic-showcase run &
popd

# Run showcase tests with `native` profile
pushd showcase
mvn test -Pnative,-showcase -Denforcer.skip=true -ntp -B
popd

### Round 3
# Update the shared-dependencies version in google-cloud-jar-parent
git clone "https://github.com/googleapis/google-cloud-java.git" --depth=1
update_all_poms_dependency google-cloud-java google-cloud-shared-dependencies "$SHARED_DEPS_VERSION"

### Round 4
# Run the updated java-shared-dependencies BOM against google-cloud-java
pushd google-cloud-java
# Run the updated java-shared-dependencies BOM against google-cloud-java integration tests
cd google-cloud-java
source ./.kokoro/common.sh
RETURN_CODE=0
setup_application_credentials
setup_cloud "$MODULES_UNDER_TEST"
run_graalvm_tests "$MODULES_UNDER_TEST"



exit $RETURN_CODE
# Exit must occur in google-cloud-java directory to correctly destroy IT resources
exit "$RETURN_CODE"
49 changes: 49 additions & 0 deletions .kokoro/presubmit/downstream-compatibility.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash
# Copyright 2023 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.

set -eo pipefail

# Comma-delimited list of repos to test with the local java-shared-dependencies
if [ -z "${REPOS_UNDER_TEST}" ]; then
echo "REPOS_UNDER_TEST must be set to run downstream-compatibility.sh"
exit 1
fi

# Get the directory of the build script
scriptDir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
cd "${scriptDir}/../.." # cd to the root of this repo
source "$scriptDir/common.sh"

echo "Setup maven mirror"
mkdir -p "${HOME}/.m2"
cp settings.xml "${HOME}/.m2"

echo "Installing this repo's modules to local maven."
mvn -q -B -ntp install --projects '!gapic-generator-java' \
-Dcheckstyle.skip -Dfmt.skip -DskipTests -T 1C
SHARED_DEPS_VERSION=$(parse_pom_version java-shared-dependencies)
echo "Install complete. java-shared-dependencies = $SHARED_DEPS_VERSION"

pushd java-shared-dependencies/target
for repo in ${REPOS_UNDER_TEST//,/ }; do # Split on comma
# Perform testing on last release, not HEAD
last_release=$(find_last_release_version "$repo")
git clone "https://github.com/googleapis/$repo.git" --depth=1 --branch "v$last_release"
update_all_poms_dependency "$repo" google-cloud-shared-dependencies "$SHARED_DEPS_VERSION"
pushd "$repo"
JOB_TYPE="test" ./.kokoro/build.sh
popd
done
popd

0 comments on commit f86eca2

Please sign in to comment.