summaryrefslogtreecommitdiff
path: root/chromium/third_party/androidx/bisect_androidx_pinpoint.sh
blob: bd2f658e416f17beeeca92a3e08b4d3ceeb25ab5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

#######################################################################
# See go/clank-autoroll#androidx-bisect for instructions.
#######################################################################

function abort() {
  echo "$1" >&2
  # 255 will abort the bisect. 125 marks commit as "unknown".
  exit ${2-255}
}

if [[ -z "$PERF_BENCHMARK" || -z "$PERF_BOT" || -z "$PERF_STORY" || -z "$PERF_METRIC" ]]; then
  abort 'Example Usage:
PERF_BENCHMARK="startup.mobile" \
PERF_BOT="android-pixel4-perf" \
PERF_STORY="cct_coldish_bbc" \
PERF_METRIC="messageloop_start_time" $0 "$@"
fi

# Determine Chromium src path based on script location.
CHROMIUM_SRC="$(dirname $0)/../.."
# Determine Android src path based on current directory (git bisect must be run from it).
# Allow running from superproject root, or from within frameworks/support.
if [[ -d frameworks/support ]]; then
  SUPERPROJECT_DIR="$(pwd)"
elif [[ -d ../../frameworks/support ]]; then
  SUPERPROJECT_DIR="$(pwd)/../.."
else
  abort "Expected to have been run from androidx checkout."
fi
FRAMEWORKS_SUPPORT_DIR="$SUPERPROJECT_DIR/frameworks/support"

set -x
set -o pipefail

cd "$CHROMIUM_SRC"
# Sanity checks:
pinpoint auth-info >/dev/null || abort "First run: pinpoint auth-login"
cipd auth-info >/dev/null || abort "First run: cipd auth-login"
# Needed for androidx sync.
gcertstatus -check_ssh=false || abort "First run: gcert"

# Allow //third_party/androidx/cipd.yaml to be listed.
local changes=$(git status --porcelain | grep -v cipd.yaml)
[[ -n "$changes" ]] && abort "git status reports changes present."

# Ensure we're on a non-main branch.
git_branch=$(git rev-parse --abbrev-ref HEAD)
[[ "$git_branch" = HEAD ]] && abort "Need to be on a branch"
[[ "$git_branch" = main ]] && abort "Need to be on a non-main branch"

# Use the most recent non-local commit as the diffbase.
git_base_rev=$(git merge-base origin/main HEAD)

cd "$SUPERPROJECT_DIR"
git submodule update --recursive --init || abort "AndroidX sync Failed"
cd "$FRAMEWORKS_SUPPORT_DIR"
# Creates a local maven repo in: out/dist/repository. Aborts bisect upon failure.

SNAPSHOT=true ./gradlew createArchive || abort "AndroidX Build Failed" 125
cd $CHROMIUM_SRC
third_party/androidx/fetch_all_androidx.py \
    --local-repo "$SUPERPROJECT_DIR/out/dist/repository" || abort "fetch_all_androidx.py failure"

super_rev=$(git -C "$SUPERPROJECT_DIR" rev-parse HEAD)
support_rev=$(git -C "$FRAMEWORKS_SUPPORT_DIR" rev-parse HEAD)
cipd_output=$(cipd create -pkg-def third_party/androidx/cipd.yaml \
  -tag super_rev:$super_rev \
  -tag support_rev:$support_rev | grep Instance:) || abort "cipd failure"
# E.g.: Instance: experimental/google.com/agrieve/androidx:3iiAIwUqY5nB5O9ArpioN...
cipd_output=${cipd_output#*Instance: }
cipd_package=${cipd_output%:*}  # Strip after colon.
cipd_package_escaped=${cipd_package//\//\\/}
cipd_instance=${cipd_output#*:}  # Strip before colon.
# This needs to be run only once per package, but it's simpler to run it every time.
cipd acl-edit "$cipd_package" -reader group:all || abort "cipd acl failure"
# gclient setdep does not allow changing CIPD package, so perl it is.
perl -0777 -i -pe "s/(.*src\/third_party\/androidx.*?packages.*?package': ')(.*?)('.*?version': ')(.*?)('.*)/\${1}${cipd_package_escaped}\${3}${cipd_instance}\$5/s" DEPS

git add DEPS || abort "git add failed"
git commit -m "androidx bisect super_rev=${super_rev::9} support_rev=${support_rev::9}"
EDITOR=true git cl upload --bypass-hooks --bypass-watchlists --no-autocc --message "androidx bisect review" \
    --title "super_rev=${super_rev::9} support_rev=${support_rev::9}" || abort "Upload CL failed"
review_number=$(git cl issue | grep -P --only-matching '(?<=Issue number: )(\d+)') || abort "parsing issue failed"

review_url="https://chromium-review.googlesource.com/c/chromium/src/+/$review_number"
# Returns non-zero if metric changed or if command fails.
pinpoint_job=$(pinpoint experiment-telemetry-start \
  -base-commit $git_base_rev -exp-commit $git_base_rev \
  -benchmark $PERF_BENCHMARK -cfg $PERF_BOT \
  -story $PERF_STORY -measurement $PERF_METRIC \
  -check-experiment -wait -quiet \
  -exp-patch-url "$review_url" \
  | tee /dev/stderr \
  | grep -P --only-matching '(?<=/job/)\S+')
# E.g.: Pinpoint job scheduled: https://pinpoint-dot-chromeperf.appspot.com/job/13af94f2ea0000
retcode=$?

if [[ -z "$pinpoint_job" ]]; then
  abort "Failed to parse pinpoint job"
fi
# E.g.: state:  SUCCEEDED
if ! pinpoint get-job -name $pinpoint_job | grep -q "state.*SUCCEEDED"; then
  abort "Pinpoint did not finish successfully."
fi

# Expect a significant difference for good changes.
if [[ $retcode = 0 ]]; then
  exit 1
fi
exit 0