blob: bd2f658e416f17beeeca92a3e08b4d3ceeb25ab5 [file] [log] [blame]
Andrew Grieve1f1f3802022-08-25 20:52:461#!/bin/bash
Avi Drissman3f1ea442022-09-08 15:42:012# Copyright 2022 The Chromium Authors
Andrew Grieve1f1f3802022-08-25 20:52:463# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6#######################################################################
7# See go/clank-autoroll#androidx-bisect for instructions.
8#######################################################################
9
10function abort() {
11 echo "$1" >&2
12 # 255 will abort the bisect. 125 marks commit as "unknown".
13 exit ${2-255}
14}
15
16if [[ -z "$PERF_BENCHMARK" || -z "$PERF_BOT" || -z "$PERF_STORY" || -z "$PERF_METRIC" ]]; then
17 abort 'Example Usage:
18PERF_BENCHMARK="startup.mobile" \
19PERF_BOT="android-pixel4-perf" \
20PERF_STORY="cct_coldish_bbc" \
Andrew Grieve7fed47f2022-08-29 16:07:3421PERF_METRIC="messageloop_start_time" $0 "$@"
Andrew Grieve1f1f3802022-08-25 20:52:4622fi
23
24# Determine Chromium src path based on script location.
25CHROMIUM_SRC="$(dirname $0)/../.."
26# Determine Android src path based on current directory (git bisect must be run from it).
27# Allow running from superproject root, or from within frameworks/support.
28if [[ -d frameworks/support ]]; then
29 SUPERPROJECT_DIR="$(pwd)"
30elif [[ -d ../../frameworks/support ]]; then
31 SUPERPROJECT_DIR="$(pwd)/../.."
32else
33 abort "Expected to have been run from androidx checkout."
34fi
35FRAMEWORKS_SUPPORT_DIR="$SUPERPROJECT_DIR/frameworks/support"
36
37set -x
38set -o pipefail
39
40cd "$CHROMIUM_SRC"
41# Sanity checks:
42pinpoint auth-info >/dev/null || abort "First run: pinpoint auth-login"
43cipd auth-info >/dev/null || abort "First run: cipd auth-login"
44# Needed for androidx sync.
45gcertstatus -check_ssh=false || abort "First run: gcert"
46
47# Allow //third_party/androidx/cipd.yaml to be listed.
48local changes=$(git status --porcelain | grep -v cipd.yaml)
49[[ -n "$changes" ]] && abort "git status reports changes present."
50
51# Ensure we're on a non-main branch.
52git_branch=$(git rev-parse --abbrev-ref HEAD)
53[[ "$git_branch" = HEAD ]] && abort "Need to be on a branch"
54[[ "$git_branch" = main ]] && abort "Need to be on a non-main branch"
55
56# Use the most recent non-local commit as the diffbase.
57git_base_rev=$(git merge-base origin/main HEAD)
58
59cd "$SUPERPROJECT_DIR"
60git submodule update --recursive --init || abort "AndroidX sync Failed"
61cd "$FRAMEWORKS_SUPPORT_DIR"
62# Creates a local maven repo in: out/dist/repository. Aborts bisect upon failure.
63
64SNAPSHOT=true ./gradlew createArchive || abort "AndroidX Build Failed" 125
65cd $CHROMIUM_SRC
66third_party/androidx/fetch_all_androidx.py \
67 --local-repo "$SUPERPROJECT_DIR/out/dist/repository" || abort "fetch_all_androidx.py failure"
68
69super_rev=$(git -C "$SUPERPROJECT_DIR" rev-parse HEAD)
70support_rev=$(git -C "$FRAMEWORKS_SUPPORT_DIR" rev-parse HEAD)
71cipd_output=$(cipd create -pkg-def third_party/androidx/cipd.yaml \
72 -tag super_rev:$super_rev \
73 -tag support_rev:$support_rev | grep Instance:) || abort "cipd failure"
74# E.g.: Instance: experimental/google.com/agrieve/androidx:3iiAIwUqY5nB5O9ArpioN...
75cipd_output=${cipd_output#*Instance: }
76cipd_package=${cipd_output%:*} # Strip after colon.
77cipd_package_escaped=${cipd_package//\//\\/}
78cipd_instance=${cipd_output#*:} # Strip before colon.
79# This needs to be run only once per package, but it's simpler to run it every time.
80cipd acl-edit "$cipd_package" -reader group:all || abort "cipd acl failure"
81# gclient setdep does not allow changing CIPD package, so perl it is.
82perl -0777 -i -pe "s/(.*src\/third_party\/androidx.*?packages.*?package': ')(.*?)('.*?version': ')(.*?)('.*)/\${1}${cipd_package_escaped}\${3}${cipd_instance}\$5/s" DEPS
83
84git add DEPS || abort "git add failed"
85git commit -m "androidx bisect super_rev=${super_rev::9} support_rev=${support_rev::9}"
86EDITOR=true git cl upload --bypass-hooks --bypass-watchlists --no-autocc --message "androidx bisect review" \
87 --title "super_rev=${super_rev::9} support_rev=${support_rev::9}" || abort "Upload CL failed"
88review_number=$(git cl issue | grep -P --only-matching '(?<=Issue number: )(\d+)') || abort "parsing issue failed"
89
90review_url="https://chromium-review.googlesource.com/c/chromium/src/+/$review_number"
91# Returns non-zero if metric changed or if command fails.
92pinpoint_job=$(pinpoint experiment-telemetry-start \
93 -base-commit $git_base_rev -exp-commit $git_base_rev \
94 -benchmark $PERF_BENCHMARK -cfg $PERF_BOT \
95 -story $PERF_STORY -measurement $PERF_METRIC \
96 -check-experiment -wait -quiet \
97 -exp-patch-url "$review_url" \
98 | tee /dev/stderr \
99 | grep -P --only-matching '(?<=/job/)\S+')
100# E.g.: Pinpoint job scheduled: https://pinpoint-dot-chromeperf.appspot.com/job/13af94f2ea0000
101retcode=$?
102
103if [[ -z "$pinpoint_job" ]]; then
104 abort "Failed to parse pinpoint job"
105fi
106# E.g.: state: SUCCEEDED
107if ! pinpoint get-job -name $pinpoint_job | grep -q "state.*SUCCEEDED"; then
108 abort "Pinpoint did not finish successfully."
109fi
110
111# Expect a significant difference for good changes.
112if [[ $retcode = 0 ]]; then
113 exit 1
114fi
115exit 0