Skip to content

Commit df596e0

Browse files
committed
build: add automated PGO profile update script
This adds a unified TeamCity script that automates the entire PGO profile update workflow into a single job. The script orchestrates the following steps: 1. Runs baseline tpcc-nowait benchmarks with the current PGO profile 2. Generates a new PGO profile and uploads it to GCS 3. Updates the WORKSPACE file with the new profile URL and SHA256 4. Rebuilds with the new profile and runs benchmarks again 5. Compares before/after performance using benchstat 6. Creates a pull request with the changes and benchmark comparison Epic: none Release note: none
1 parent c484d09 commit df596e0

File tree

3 files changed

+221
-55
lines changed

3 files changed

+221
-55
lines changed

build/teamcity/cockroach/nightlies/roachtest_gce_validate_profile.sh

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

build/teamcity/internal/cockroach/build/ci/generate-profile-impl.sh

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2025 The Cockroach Authors.
4+
#
5+
# Use of this software is governed by the CockroachDB Software License
6+
# included in the /LICENSE file.
7+
8+
set -exuo pipefail
9+
10+
dir="$(dirname $(dirname $(dirname $(dirname "${0}"))))"
11+
12+
source "$dir/teamcity-support.sh" # For $root
13+
source "$dir/teamcity-bazel-support.sh" # For run_bazel
14+
15+
cleanup() {
16+
rm -f ~/.config/gcloud/application_default_credentials.json
17+
}
18+
trap cleanup EXIT
19+
20+
21+
# Install `gh` CLI tool if not already available
22+
tc_start_block "Install gh CLI"
23+
if ! command -v gh &> /dev/null; then
24+
echo "Installing gh CLI tool..."
25+
wget -O /tmp/gh.tar.gz https://github.com/cli/cli/releases/download/v2.13.0/gh_2.13.0_linux_amd64.tar.gz
26+
echo "9e833e02428cd49e0af73bc7dc4cafa329fe3ecba1bfe92f0859bf5b11916401 /tmp/gh.tar.gz" | sha256sum -c -
27+
tar --strip-components 1 -xf /tmp/gh.tar.gz -C /tmp
28+
export PATH=/tmp/bin:$PATH
29+
echo "gh CLI installed successfully"
30+
fi
31+
tc_end_block "Install gh CLI"
32+
33+
tc_start_block "Configuration"
34+
export TESTS="${TESTS:-tpcc-nowait/literal/w=1000/nodes=5/cpu=16}"
35+
export COUNT="${COUNT:-20}"
36+
export CLOUD="${CLOUD:-gce}"
37+
# Do not use spot instances for PGO profile generation to ensure consistent
38+
# performance and random VM preemptions.
39+
export USE_SPOT="${USE_SPOT:-never}"
40+
41+
docker_env_args=(
42+
SELECT_PROBABILITY=1.0
43+
ARM_PROBABILITY=0.0
44+
COCKROACH_EA_PROBABILITY=0.0
45+
FIPS_PROBABILITY=0.0
46+
LITERAL_ARTIFACTS_DIR=$root/artifacts
47+
BUILD_VCS_NUMBER
48+
CLOUD
49+
COCKROACH_DEV_LICENSE
50+
COCKROACH_RANDOM_SEED
51+
COUNT
52+
EXPORT_OPENMETRICS
53+
GITHUB_API_TOKEN
54+
GITHUB_ORG
55+
GITHUB_REPO
56+
GOOGLE_CREDENTIALS_ASSUME_ROLE
57+
GOOGLE_EPHEMERAL_CREDENTIALS
58+
GOOGLE_KMS_KEY_A
59+
GOOGLE_KMS_KEY_B
60+
GOOGLE_SERVICE_ACCOUNT
61+
GRAFANA_SERVICE_ACCOUNT_AUDIENCE
62+
GRAFANA_SERVICE_ACCOUNT_JSON
63+
ROACHPERF_OPENMETRICS_CREDENTIALS
64+
ROACHTEST_ASSERTIONS_ENABLED_SEED
65+
ROACHTEST_FORCE_RUN_INVALID_RELEASE_BRANCH
66+
SELECTIVE_TESTS
67+
SLACK_TOKEN
68+
SNOWFLAKE_PVT_KEY
69+
SNOWFLAKE_USER
70+
TC_BUILDTYPE_ID
71+
TC_BUILD_BRANCH
72+
TC_BUILD_ID
73+
TC_SERVER_URL
74+
TESTS
75+
USE_SPOT
76+
)
77+
BAZEL_SUPPORT_EXTRA_DOCKER_ARGS="$(printf -- "-e %s " "${docker_env_args[@]}")"
78+
79+
benchstat_before="artifacts/benchstat_before.txt"
80+
benchstat_after="artifacts/benchstat_after.txt"
81+
tc_end_block "Configuration"
82+
83+
tc_start_block "Baseline tpcc-nowait tests"
84+
85+
BAZEL_SUPPORT_EXTRA_DOCKER_ARGS="$BAZEL_SUPPORT_EXTRA_DOCKER_ARGS" \
86+
run_bazel build/teamcity/cockroach/nightlies/roachtest_nightly_impl.sh
87+
88+
# Benchmark results are zipped in artifacts; extract them for analysis in a temp dir.
89+
tmp_artifacts_before="$(mktemp -d)"
90+
find "${root}/artifacts" -type f -name "artifacts.zip" -exec sh -c '
91+
src="$1"
92+
dest="'"$tmp_artifacts_before"'"
93+
base="'"${root}/artifacts"'"
94+
rel="${src#$base/}"
95+
rel_dir="$(dirname "$rel")"
96+
outdir="$dest/$rel_dir"
97+
mkdir -p "$outdir"
98+
unzip -o "$src" -d "$outdir"
99+
' _ {} \;
100+
101+
bash -xe ./scripts/tpcc_results.sh "$tmp_artifacts_before" > "$benchstat_before"
102+
rm -rf "$tmp_artifacts_before"
103+
104+
echo "=== Baseline benchstat saved to $benchstat_before ==="
105+
tc_end_block "Baseline tpcc-nowait tests"
106+
107+
tc_start_block "Generate new PGO profile"
108+
echo "=== Step 2: Generating new PGO profile ==="
109+
filename="$(date +"%Y%m%d%H%M%S")-$(git rev-parse HEAD).pb.gz"
110+
bazel build //pkg/cmd/run-pgo-build
111+
"$(bazel info bazel-bin)"/pkg/cmd/run-pgo-build/run-pgo-build_/run-pgo-build -out "artifacts/$filename"
112+
sha256_hash=$(shasum -a 256 "artifacts/$filename" | awk '{print $1}')
113+
114+
# Upload to GCS
115+
google_credentials="$GCS_GOOGLE_CREDENTIALS" log_into_gcloud
116+
gcs_url="gs://cockroach-profiles/$filename"
117+
gsutil cp "artifacts/$filename" "$gcs_url"
118+
119+
# Convert GCS URL to HTTPS URL for WORKSPACE
120+
https_url="https://storage.googleapis.com/cockroach-profiles/$filename"
121+
122+
echo "=== PGO profile uploaded to $gcs_url ==="
123+
echo "=== SHA256: $sha256_hash ==="
124+
125+
# Use sed to update the sha256 and url in the pgo_profile block
126+
# This is more robust than string replacement
127+
sed -i.bak -e '/pgo_profile(/,/)/ {
128+
s|sha256 = ".*"|sha256 = "'"$sha256_hash"'"|
129+
s|url = ".*"|url = "'"$https_url"'"|
130+
}' WORKSPACE
131+
rm -f WORKSPACE.bak
132+
133+
tc_end_block "Generate new PGO profile"
134+
135+
tc_start_block "Rebuild with new PGO profile"
136+
# Clear build cache to ensure new profile is used
137+
bazel clean
138+
rm -rf "artifacts/tpcc-nowait"
139+
140+
# Run the same tests again with the new PGO profile
141+
BAZEL_SUPPORT_EXTRA_DOCKER_ARGS="$BAZEL_SUPPORT_EXTRA_DOCKER_ARGS" \
142+
run_bazel build/teamcity/cockroach/nightlies/roachtest_nightly_impl.sh
143+
144+
# Benchmark results are zipped in artifacts; extract them for analysis in a temp dir.
145+
tmp_artifacts_after="$(mktemp -d)"
146+
find "${root}/artifacts" -type f -name "artifacts.zip" -exec sh -c '
147+
src="$1"
148+
dest="'"$tmp_artifacts_after"'"
149+
base="'"${root}/artifacts"'"
150+
rel="${src#$base/}"
151+
rel_dir="$(dirname "$rel")"
152+
outdir="$dest/$rel_dir"
153+
mkdir -p "$outdir"
154+
unzip -o "$src" -d "$outdir"
155+
' _ {} \;
156+
157+
bash -xe ./scripts/tpcc_results.sh "$tmp_artifacts_after" > "$benchstat_after"
158+
rm -rf "$tmp_artifacts_after"
159+
160+
echo "=== Post-PGO benchstat saved to $benchstat_after ==="
161+
tc_end_block "Rebuild with new PGO profile"
162+
163+
tc_start_block "Benchstat comparison"
164+
# Run benchstat comparison using bazel and save to file
165+
benchstat_comparison="artifacts/benchstat_comparison.txt"
166+
167+
bazel build @org_golang_x_perf//cmd/benchstat
168+
"$(bazel info bazel-bin)"/external/org_golang_x_perf/cmd/benchstat/benchstat_/benchstat \
169+
"$benchstat_before" "$benchstat_after" | tee "$benchstat_comparison"
170+
tc_end_block "Benchstat comparison"
171+
172+
tc_start_block "Create PR"
173+
export GIT_AUTHOR_NAME="Justin Beaver"
174+
export GIT_COMMITTER_NAME="Justin Beaver"
175+
export GIT_AUTHOR_EMAIL="[email protected]"
176+
export GIT_COMMITTER_EMAIL="[email protected]"
177+
gh_username="cockroach-teamcity"
178+
179+
# Create a new branch for the PR
180+
branch_name="pgo-profile-update-$(date +"%Y%m%d%H%M%S")"
181+
git checkout -b "$branch_name"
182+
183+
# Stage the WORKSPACE file changes
184+
git add WORKSPACE
185+
186+
# Create commit with descriptive message
187+
# Note: Full benchstat comparison is in the PR description, not in commit message
188+
commit_message="build: update PGO profile to $filename
189+
190+
This commit updates the PGO profile used for building CockroachDB.
191+
192+
The new profile was generated from tpcc-nowait benchmarks.
193+
See PR description for full benchmark comparison results.
194+
195+
Epic: none
196+
Release note: none"
197+
198+
git commit -m "$commit_message"
199+
set +x
200+
git push "https://$gh_username:$GH_TOKEN@github.com/$gh_username/cockroach.git" "$branch_name"
201+
set -x
202+
203+
# Create PR using gh CLI
204+
pr_body="This PR updates the PGO (Profile-Guided Optimization) profile used for building CockroachDB.
205+
206+
The new profile was validated using tpcc-nowait benchmarks. Results comparing the old profile (before) vs new profile (after):
207+
208+
\`\`\`
209+
$(cat "$benchstat_comparison")
210+
\`\`\`
211+
212+
Epic: none
213+
Release note: none"
214+
215+
gh pr create \
216+
--head "$gh_username:$branch_name" \
217+
--title "build: update PGO profile to $filename" \
218+
--body "$pr_body" \
219+
--reviewer "cockroachdb/release-eng-prs" \
220+
--base master | tee artifacts/pgo_profile_pr_url.txt
221+
tc_end_block "Create PR"

0 commit comments

Comments
 (0)