From 4369e8cd9afe5f3b1b5ee2927b44599ea23b0437 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 8 Mar 2018 18:41:39 -0800 Subject: [PATCH] buildscripts: add Kokoro-based CI for Android APK stats (#3984) --- .../kokoro/{cronet.cfg => android.cfg} | 2 +- buildscripts/kokoro/android.sh | 95 +++++++++++++++++++ buildscripts/kokoro/cronet.sh | 8 -- buildscripts/set_github_status.py | 64 +++++++++++++ 4 files changed, 160 insertions(+), 9 deletions(-) rename buildscripts/kokoro/{cronet.cfg => android.cfg} (65%) create mode 100755 buildscripts/kokoro/android.sh delete mode 100644 buildscripts/kokoro/cronet.sh create mode 100755 buildscripts/set_github_status.py diff --git a/buildscripts/kokoro/cronet.cfg b/buildscripts/kokoro/android.cfg similarity index 65% rename from buildscripts/kokoro/cronet.cfg rename to buildscripts/kokoro/android.cfg index 10302da77c..7730b90a2b 100644 --- a/buildscripts/kokoro/cronet.cfg +++ b/buildscripts/kokoro/android.cfg @@ -1,5 +1,5 @@ # Config file for internal CI # Location of the continuous shell script in repository. -build_file: "grpc-java/buildscripts/kokoro/cronet.sh" +build_file: "grpc-java/buildscripts/kokoro/android.sh" timeout_mins: 45 diff --git a/buildscripts/kokoro/android.sh b/buildscripts/kokoro/android.sh new file mode 100755 index 0000000000..47ff54c32d --- /dev/null +++ b/buildscripts/kokoro/android.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +set -exu -o pipefail +cat /VERSION + +BASE_DIR="$(pwd)" + +# Build Cronet + +cd "$BASE_DIR/github/grpc-java/cronet" +./cronet_deps.sh +../gradlew --include-build .. build + + +# Install gRPC and codegen for the Android examples +# (a composite gradle build can't find protoc-gen-grpc-java) + +cd "$BASE_DIR/github/grpc-java" + +export GRADLE_OPTS=-Xmx512m +export PROTOBUF_VERSION=3.5.1 +export LDFLAGS=-L/tmp/protobuf/lib +export CXXFLAGS=-I/tmp/protobuf/include +export LD_LIBRARY_PATH=/tmp/protobuf/lib +export OS_NAME=$(uname) + +# Proto deps +buildscripts/make_dependencies.sh +ln -s "/tmp/protobuf-${PROTOBUF_VERSION}/$(uname -s)-$(uname -p)" /tmp/protobuf + +./gradlew install + +cd ./examples/android/clientcache +./gradlew build +cd ../routeguide +./gradlew build +cd ../helloworld +./gradlew build + + +# Skip APK size and dex count comparisons for non-PR builds + +if [[ -z "$KOKORO_GITHUB_PULL_REQUEST_COMMIT" ]]; then + echo "Skipping APK size and dex count" + exit 0 +fi + + +# Save a copy of set_github_status.py (it may differ from the base commit) + +SET_GITHUB_STATUS="$TMPDIR/set_github_status.py" +cp "$BASE_DIR/github/grpc-java/buildscripts/set_github_status.py" "$SET_GITHUB_STATUS" + + +# Collect APK size and dex count stats for the helloworld example + +read -r ignored new_dex_count < \ + <("${ANDROID_HOME}/tools/bin/apkanalyzer" dex references app/build/outputs/apk/release/app-release-unsigned.apk) + +new_apk_size="$(stat --printf=%s app/build/outputs/apk/release/app-release-unsigned.apk)" + + +# Get the APK size and dex count stats using the pull request base commit + +cd $BASE_DIR/github/grpc-java +git checkout HEAD^ +./gradlew install +cd examples/android/helloworld/ +./gradlew build + +read -r ignored old_dex_count < \ + <("${ANDROID_HOME}/tools/bin/apkanalyzer" dex references app/build/outputs/apk/release/app-release-unsigned.apk) + +old_apk_size="$(stat --printf=%s app/build/outputs/apk/release/app-release-unsigned.apk)" + +dex_count_delta="$((new_dex_count-old_dex_count))" + +apk_size_delta="$((new_apk_size-old_apk_size))" + + +# Update the statuses with the deltas + +gsutil cp gs://grpc-testing-secrets/github_credentials/oauth_token.txt ~/ + +"$SET_GITHUB_STATUS" \ + --sha1 "$KOKORO_GITHUB_PULL_REQUEST_COMMIT" \ + --state success \ + --description "New DEX reference count: $(printf "%'d" "$new_dex_count") (delta: $(printf "%'d" "$dex_count_delta"))" \ + --context android/dex_diff --oauth_file ~/oauth_token.txt + +"$SET_GITHUB_STATUS" \ + --sha1 "$KOKORO_GITHUB_PULL_REQUEST_COMMIT" \ + --state success \ + --description "New APK size in bytes: $(printf "%'d" "$new_apk_size") (delta: $(printf "%'d" "$apk_size_delta"))" \ + --context android/apk_diff --oauth_file ~/oauth_token.txt diff --git a/buildscripts/kokoro/cronet.sh b/buildscripts/kokoro/cronet.sh deleted file mode 100644 index 5097fac33b..0000000000 --- a/buildscripts/kokoro/cronet.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -set -exu -o pipefail -cat /VERSION - -cd ./github/grpc-java/cronet -./cronet_deps.sh -../gradlew --include-build .. build diff --git a/buildscripts/set_github_status.py b/buildscripts/set_github_status.py new file mode 100755 index 0000000000..e8e25930a6 --- /dev/null +++ b/buildscripts/set_github_status.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python2.7 +# +# Copyright 2018 gRPC authors. +# +# 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. + +import argparse +import json +import urllib2 + + +def run(): + argp = argparse.ArgumentParser(description='Set status on pull request') + + argp.add_argument( + '--sha1', type=str, help='SHA1 of the commit', required=True) + argp.add_argument( + '--state', + type=str, + choices=('error', 'failure', 'pending', 'success'), + help='State to set', + required=True) + argp.add_argument( + '--description', type=str, help='Status description', required=True) + argp.add_argument('--context', type=str, help='Status context', required=True) + argp.add_argument( + '--oauth_file', type=str, help='File with OAuth token', required=True) + + args = argp.parse_args() + sha1 = args.sha1 + state = args.state + description = args.description + context = args.context + oauth_file = args.oauth_file + + with open(oauth_file, 'r') as oauth_file_reader: + oauth_token = oauth_file_reader.read().replace('\n', '') + + req = urllib2.Request( + url='https://api.github.com/repos/grpc/grpc-java/statuses/%s' % sha1, + data=json.dumps({ + 'state': state, + 'description': description, + 'context': context, + }), + headers={ + 'Authorization': 'token %s' % oauth_token, + 'Content-Type': 'application/json', + }) + print urllib2.urlopen(req).read() + + +if __name__ == '__main__': + run()