Skip to content

Commit 9662f0f

Browse files
ejona86grpc-bot
authored andcommitted
buildscripts: Convert GAE CI to Cloud Build
The Google App Engine build now requires Java 17, because the App Engine libraries are now using Java 17 bytecode. The Kokoro environment doesn't include Java 17, and while we could make some custom pools to resolve it, it is easier to swap to Cloud Build than to fight and maintain the Kokoro images. With Cloud Build we can also restrict permissions easier, as the same workers aren't used for multiple tasks. However, the Gradle App Engine plugin doesn't support choosing a service account for GAE, so I swapped to using gcloud app deploy. Although we'll be using restricted service accounts, we'll configure Cloud Build to require a "/gcbrun" GitHub comment except for owners and collaborators of the repository, similar to the "kokoro:run" label today. I swapped the Gradle code to use project properties instead of system properties, as we really should have been using project properties to begin with and I didn't want to add new system properties. The sleep has probably been unnecessary since the turndown of GAE Java 7, when the architecture of GAE changed considerably. But today it is very possible a new instance is spun up for that request and GAE does a warmup request, so the delay seems unlikely to help anything and was excessive at 20 seconds. The Cloud Build file _doesn't_ include GAE in its name because it can do more than GAE testing and it is easy to run things in parallel in Cloud Build (although they share the worker). In particular, some of the Android tests may make sense to migrate away from Kokoro. We're using e2-standard-16 for Kokoro and it takes about 10 minutes. With the default Cloud Build worker e2-standard-2 it takes 20 minutes, and with e2-highcpu-8 it takes 10 minutes with 4 minutes spent on app deploy. The expectation is to run this with a Java-CI-specific service account, so we have configure logging ourselves. I chose CLOUD_LOGGING_ONLY because it was easy, but we'll want to configure GCS in the future to allow external contributors to see the logs.
1 parent 559e3ba commit 9662f0f

File tree

4 files changed

+85
-64
lines changed

4 files changed

+85
-64
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
substitutions:
2+
_GAE_SERVICE_ACCOUNT: [email protected]
3+
options:
4+
env:
5+
- BUILD_ID=$BUILD_ID
6+
- KOKORO_GAE_SERVICE=java-gae-interop-test
7+
- DUMMY_DEFAULT_VERSION=dummy-default
8+
- GRADLE_OPTS=-Dorg.gradle.jvmargs='-Xmx1g'
9+
- GRADLE_FLAGS=-PskipCodegen=true -PskipAndroid=true
10+
logging: CLOUD_LOGGING_ONLY
11+
machineType: E2_HIGHCPU_8
12+
13+
steps:
14+
- id: clean-stale-deploys
15+
name: gcr.io/cloud-builders/gcloud
16+
allowFailure: true
17+
script: |
18+
#!/usr/bin/env bash
19+
set -e
20+
echo "Cleaning out stale deploys from previous runs, it is ok if this part fails"
21+
# If the test fails, the deployment is leaked.
22+
# Delete all versions whose name is not 'dummy-default' and is older than 1 hour.
23+
# This expression is an ISO8601 relative date:
24+
# https://cloud.google.com/sdk/gcloud/reference/topic/datetimes
25+
(gcloud app versions list --format="get(version.id)" \
26+
--filter="service=$KOKORO_GAE_SERVICE AND NOT version : '$DUMMY_DEFAULT_VERSION' AND version.createTime<'-p1h'" \
27+
| xargs -i gcloud app services delete "$KOKORO_GAE_SERVICE" --version {} --quiet) || true
28+
29+
- name: gcr.io/cloud-builders/docker
30+
args: ['build', '-t', 'gae-build', 'buildscripts/gae-build/']
31+
32+
- id: build
33+
name: gae-build
34+
script: |
35+
#!/usr/bin/env bash
36+
exec ./gradlew $GRADLE_FLAGS :grpc-gae-interop-testing-jdk8:appengineStage
37+
38+
- id: deploy
39+
name: gcr.io/cloud-builders/gcloud
40+
args:
41+
- app
42+
- deploy
43+
- gae-interop-testing/gae-jdk8/build/staged-app/app.yaml
44+
- --service-account=$_GAE_SERVICE_ACCOUNT
45+
- --no-promote
46+
- --no-stop-previous-version
47+
- --version=cb-$BUILD_ID
48+
49+
- id: runInteropTestRemote
50+
name: eclipse-temurin:17-jdk
51+
env:
52+
- PROJECT_ID=$PROJECT_ID
53+
script: |
54+
#!/usr/bin/env bash
55+
exec ./gradlew $GRADLE_FLAGS --stacktrace -PgaeDeployVersion="cb-$BUILD_ID" \
56+
-PgaeProjectId="$PROJECT_ID" :grpc-gae-interop-testing-jdk8:runInteropTestRemote
57+
58+
- id: cleanup
59+
name: gcr.io/cloud-builders/gcloud
60+
script: |
61+
#!/usr/bin/env bash
62+
set -e
63+
echo "Performing cleanup now."
64+
gcloud app services delete "$KOKORO_GAE_SERVICE" --version "cb-$BUILD_ID" --quiet

buildscripts/gae-build/Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM eclipse-temurin:17-jdk
2+
3+
# The AppEngine Gradle plugin downloads and runs its own gcloud to get the .jar
4+
# to link against, so we need Python even if we use gcloud deploy directly
5+
# instead of using the plugin.
6+
RUN export DEBIAN_FRONTEND=noninteractive && \
7+
apt-get update && \
8+
apt-get upgrade -y && \
9+
apt-get install -y --no-install-recommends python3 && \
10+
rm -rf /var/lib/apt/lists/*

buildscripts/kokoro/gae-interop.sh

Lines changed: 0 additions & 55 deletions
This file was deleted.

gae-interop-testing/gae-jdk8/build.gradle

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def createDefaultVersion() {
5858
return new java.text.SimpleDateFormat("yyyyMMdd't'HHmmss").format(new Date())
5959
}
6060

61+
def nonShadowedProject = project
6162
// [START model]
6263
appengine {
6364
// App Engine tasks configuration
@@ -67,13 +68,13 @@ appengine {
6768

6869
deploy {
6970
// deploy configuration
70-
projectId = 'GCLOUD_CONFIG'
71+
projectId = nonShadowedProject.findProperty('gaeProjectId') ?: 'GCLOUD_CONFIG'
7172
// default - stop the current version
72-
stopPreviousVersion = System.getProperty('gaeStopPreviousVersion') ?: true
73+
stopPreviousVersion = nonShadowedProject.findProperty('gaeStopPreviousVersion') ?: true
7374
// default - do not make this the promoted version
74-
promote = System.getProperty('gaePromote') ?: false
75-
// Use -DgaeDeployVersion if set, otherwise the version is null and the plugin will generate it
76-
version = System.getProperty('gaeDeployVersion', createDefaultVersion())
75+
promote = nonShadowedProject.findProperty('gaePromote') ?: false
76+
// Use -PgaeDeployVersion if set, otherwise the version is null and the plugin will generate it
77+
version = nonShadowedProject.findProperty('gaeDeployVersion') ?: createDefaultVersion()
7778
}
7879
}
7980
// [END model]
@@ -83,6 +84,10 @@ version = '1.0-SNAPSHOT' // Version in generated output
8384

8485
/** Returns the service name. */
8586
String getGaeProject() {
87+
def configuredProjectId = appengine.deploy.projectId
88+
if (!"GCLOUD_CONFIG".equals(configuredProjectId)) {
89+
return configuredProjectId
90+
}
8691
def stream = new ByteArrayOutputStream()
8792
exec {
8893
executable 'gcloud'
@@ -110,11 +115,8 @@ String getAppUrl(String project, String service, String version) {
110115
}
111116

112117
tasks.register("runInteropTestRemote") {
113-
dependsOn appengineDeploy
118+
mustRunAfter appengineDeploy
114119
doLast {
115-
// give remote app some time to settle down
116-
sleep(20000)
117-
118120
def appUrl = getAppUrl(
119121
getGaeProject(),
120122
getService(project.getProjectDir().toPath()),

0 commit comments

Comments
 (0)