Skip to content

Commit f17294a

Browse files
Precommit check to validate check_for_running_build step in build yamls (GoogleCloudPlatform#4903)
2 parents e8b8b76 + b49963a commit f17294a

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ repos:
7474
files: 'tools/cloud-build/daily-tests/builds/.*\.yaml'
7575
pass_filenames: false
7676
require_serial: true
77+
- id: validate-daily-test-builds
78+
name: validate-daily-test-builds
79+
entry: tools/cloud-build/daily-tests/validate_daily_test_builds.py
80+
language: python
81+
language_version: python3
82+
additional_dependencies: ['pyyaml']
83+
files: 'tools/cloud-build/daily-tests/builds/.*\.(yaml|yml)'
84+
pass_filenames: true
85+
require_serial: true
7786
- id: pytest-check
7887
name: pytest-check
7988
entry: python -m pytest
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2025 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import argparse
17+
import sys
18+
from pathlib import Path
19+
20+
import yaml
21+
22+
def validate_build_file(file_path: Path) -> bool:
23+
"""Validates a daily test build file.
24+
25+
Args:
26+
file_path: The path to the build file.
27+
28+
Returns:
29+
True if the file is valid, False otherwise.
30+
"""
31+
try:
32+
with open(file_path, "r") as f:
33+
data = yaml.safe_load(f)
34+
except yaml.YAMLError as e:
35+
print(f"Error parsing YAML file {file_path}: {e}", file=sys.stderr)
36+
return False
37+
38+
if not isinstance(data, dict):
39+
print(f"Error: {file_path} is not a valid YAML dictionary.", file=sys.stderr)
40+
return False
41+
42+
steps = data.get("steps")
43+
if not isinstance(steps, list):
44+
print(f"Error: 'steps' not found or not a list in {file_path}", file=sys.stderr)
45+
return False
46+
47+
for step in steps:
48+
if isinstance(step, dict) and step.get("id") == "check_for_running_build":
49+
script = step.get("script")
50+
if not script:
51+
print(
52+
f"Error: 'script' not found in 'check_for_running_build' step in {file_path}",
53+
file=sys.stderr,
54+
)
55+
return False
56+
expected_script = f"tools/cloud-build/check_running_build.sh {file_path}"
57+
if script != expected_script:
58+
print(
59+
f"Error: Invalid 'script' in 'check_for_running_build' step in {file_path}",
60+
file=sys.stderr,
61+
)
62+
print(f" Expected: {expected_script}", file=sys.stderr)
63+
print(f" Got: {script}", file=sys.stderr)
64+
return False
65+
return True
66+
67+
print(
68+
f"Error: 'check_for_running_build' step not found in {file_path}",
69+
file=sys.stderr,
70+
)
71+
return False
72+
73+
74+
def main():
75+
parser = argparse.ArgumentParser(
76+
description="Validates daily test build files."
77+
)
78+
parser.add_argument(
79+
"filenames",
80+
nargs="*",
81+
help="The files to validate.",
82+
)
83+
args = parser.parse_args()
84+
85+
results = [validate_build_file(Path(filename)) for filename in args.filenames]
86+
if not all(results):
87+
sys.exit(1)
88+
89+
90+
if __name__ == "__main__":
91+
main()

0 commit comments

Comments
 (0)