Skip to content

Commit 79d7c4a

Browse files
feat: automate release versioning and metadata injection for CI evaluations (#163)
1 parent 16862db commit 79d7c4a

4 files changed

Lines changed: 75 additions & 15 deletions

File tree

cloudbuild.yaml

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,52 @@ steps:
2121
- name: 'us-central1-docker.pkg.dev/cloud-db-nl2sql/evalbench/eval_server:latest'
2222
entrypoint: 'bash'
2323
# Decrypts the secret from Secret Manager into the DB_PASSWORD environment variable
24-
secretEnv: ['DB_PASSWORD']
24+
secretEnv: ['DB_PASSWORD', 'GITHUB_TOKEN']
2525
args:
2626
- '-c'
2727
- |
2828
set -e
29+
30+
# Only run on release branches
31+
if [[ "$_HEAD_BRANCH" != release-please-* ]]; then
32+
echo "Not a release-please branch. Exiting."
33+
exit 0
34+
fi
35+
echo "Release branch detected. Fetching PR data from GitHub API..."
36+
37+
# Fetch PR data and status code
38+
HTTP_STATUS=$(curl -s -o pr_data.json -w "%{http_code}" -H "Authorization: token $$GITHUB_TOKEN" \
39+
"https://api.github.com/repos/$REPO_FULL_NAME/pulls/$_PR_NUMBER")
40+
41+
if [ "$$HTTP_STATUS" -ne 200 ]; then
42+
echo "Error fetching PR data: HTTP $$HTTP_STATUS"
43+
cat pr_data.json
44+
exit 1
45+
fi
46+
47+
PR_DATA=$(cat pr_data.json)
48+
49+
# Extract labels and title from PR data (Use $$ to escape bash variables)
50+
PR_LABELS=$(echo "$$PR_DATA" | jq -r '[.labels[].name] | join(",")')
51+
PR_TITLE=$(echo "$$PR_DATA" | jq -r '.title')
52+
53+
# Determine Release Version (Use double quotes and $$ for bash variables)
54+
if [[ "$$PR_LABELS" == *"autorelease: triggered"* ]]; then
55+
if [[ "$$PR_TITLE" =~ release\ ([0-9]+\.[0-9]+\.[0-9]+) ]]; then
56+
export RELEASE_VERSION="$${BASH_REMATCH[1]}"
57+
else
58+
export RELEASE_VERSION="unknown"
59+
fi
60+
else
61+
export RELEASE_VERSION="unknown"
62+
fi
63+
2964
# Workaround for evalbench bug: settings are only applied if path basename matches extension ID
3065
ln -s /workspace /workspace/cloud-sql-postgresql
3166
cd /evalbench
3267
3368
export EVAL_GCP_PROJECT_ID=$PROJECT_ID
34-
export EVAL_GCP_PROJECT_REGION=us-central1
69+
export EVAL_GCP_PROJECT_REGION=$_CLOUD_SQL_REGION
3570
export GOOGLE_CLOUD_PROJECT=$PROJECT_ID
3671
export CLOUD_SQL_POSTGRES_PROJECT=$PROJECT_ID
3772
export CLOUD_SQL_POSTGRES_INSTANCE=$_CLOUD_SQL_INSTANCE
@@ -43,6 +78,9 @@ steps:
4378
# Maps the decrypted DB_PASSWORD to the exact variable expected by gemini_cli and extension skills
4479
export CLOUD_SQL_POSTGRES_PASSWORD=$$DB_PASSWORD
4580
81+
# Combine CI metadata with run config
82+
cat /workspace/evals/ci_metadata.yaml >> /workspace/evals/run_config.yaml
83+
4684
# Substitute environment variables in model_config.yaml
4785
python3 /workspace/evals/substitute_env.py
4886
@@ -58,3 +96,5 @@ availableSecrets:
5896
secretManager:
5997
- versionName: projects/$PROJECT_ID/secrets/daily-ci-evals-db-password/versions/latest
6098
env: 'DB_PASSWORD'
99+
- versionName: projects/$PROJECT_ID/secrets/GITHUB_TOKEN/versions/latest
100+
env: 'GITHUB_TOKEN'

evals/ci_metadata.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
############################################################
16+
### CI Metadata (Repository Specific)
17+
### Note: These fields are used for version tracking in BQ
18+
### and are not part of the core Evalbench schema.
19+
############################################################
20+
21+
extension_id: cloud-sql-postgresql
22+
release_version: ${RELEASE_VERSION}

evals/run_config.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
extension_id: cloud-sql-postgresql
16-
1715
dataset_config: /workspace/evals/dataset.json
1816
dataset_format: gemini-cli-format
1917

2018
orchestrator: geminicli
2119
model_config: /workspace/evals/model_config.yaml
22-
# You can reference default simulated user models provided by the evalbench repo:
2320
simulated_user_model_config: /workspace/evals/gemini_2.5_pro_model.yaml
2421

2522
scorers:

evals/substitute_env.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
import re
33

44
def main():
5-
yaml_path = '/workspace/evals/model_config.yaml'
6-
if os.path.exists(yaml_path):
7-
with open(yaml_path, 'r') as f:
8-
content = f.read()
9-
content = re.sub(r'\${(\w+)}', lambda m: os.environ.get(m.group(1), m.group(0)), content)
10-
with open(yaml_path, 'w') as f:
11-
f.write(content)
12-
print(f"Successfully substituted environment variables in {yaml_path}")
13-
else:
14-
print(f"File not found: {yaml_path}")
5+
yaml_paths = ['/workspace/evals/model_config.yaml', '/workspace/evals/run_config.yaml']
6+
for yaml_path in yaml_paths:
7+
if os.path.exists(yaml_path):
8+
with open(yaml_path, 'r') as f:
9+
content = f.read()
10+
content = re.sub(r'\${(\w+)}', lambda m: os.environ.get(m.group(1), m.group(0)), content)
11+
with open(yaml_path, 'w') as f:
12+
f.write(content)
13+
print(f"Successfully substituted environment variables in {yaml_path}")
14+
else:
15+
print(f"File not found: {yaml_path}")
1516

1617
if __name__ == '__main__':
1718
main()

0 commit comments

Comments
 (0)