Skip to content

Commit 1be510a

Browse files
committed
update matrix script
1 parent fdbdd49 commit 1be510a

1 file changed

Lines changed: 40 additions & 74 deletions

File tree

Lines changed: 40 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,60 @@
11
import os
22
import json
33
import argparse
4-
from typing import List, Dict
54

6-
# ---------------------------------------------------------
7-
# THE VIP LIST: These will get their own dedicated isolated VMs
8-
# ---------------------------------------------------------
9-
MAMMOTH_OVERRIDES = {
10-
"google-cloud-spanner": 9999,
11-
"google-cloud-compute": 9999,
12-
"google-cloud-compute-v1beta": 9999,
13-
"google-cloud-discoveryengine": 9999
5+
VIPS = {
6+
"google-cloud-spanner",
7+
"google-cloud-compute",
8+
"google-cloud-compute-v1beta",
9+
"google-cloud-discoveryengine"
1410
}
1511

16-
def calculate_package_weight(pkg_path: str) -> int:
17-
pkg_name = os.path.basename(os.path.normpath(pkg_path))
18-
if pkg_name in MAMMOTH_OVERRIDES:
19-
return MAMMOTH_OVERRIDES[pkg_name]
12+
def get_valid_packages(directories):
13+
return [p for p in directories if os.path.isfile(os.path.join(p, "noxfile.py"))]
2014

21-
base_weight = 1
22-
meta_path = os.path.join(pkg_path, ".repo-metadata.json")
23-
if os.path.isfile(meta_path):
24-
try:
25-
with open(meta_path, 'r') as f:
26-
if json.load(f).get("library_type") == "GAPIC_AUTO":
27-
return base_weight
28-
except Exception:
29-
pass
30-
31-
test_dir = os.path.join(pkg_path, "tests")
32-
if os.path.isdir(test_dir):
33-
for root, _, files in os.walk(test_dir):
34-
base_weight += sum(1 for f in files if f.endswith(".py"))
35-
36-
return base_weight
37-
38-
def create_balanced_buckets(packages: List[str], max_buckets: int) -> List[Dict]:
39-
valid_pkgs = [p for p in packages if os.path.isfile(os.path.join(p, "noxfile.py"))]
40-
if not valid_pkgs:
41-
return []
42-
43-
pkg_weights = [(pkg, calculate_package_weight(pkg)) for pkg in valid_pkgs]
44-
pkg_weights.sort(key=lambda x: x[1], reverse=True)
45-
46-
num_buckets = min(len(valid_pkgs), max_buckets)
47-
buckets = [{"id": i + 1, "packages": [], "total_weight": 0} for i in range(num_buckets)]
15+
def distribute_packages(packages, max_buckets):
16+
# VIPs jump to the front of the line
17+
packages.sort(key=lambda p: os.path.basename(p) not in VIPS)
4818

49-
for pkg, weight in pkg_weights:
50-
lightest = min(buckets, key=lambda b: b["total_weight"])
51-
lightest["packages"].append(pkg)
52-
lightest["total_weight"] += weight
53-
54-
# Build the final output payload
55-
final_output = []
56-
for b in buckets:
57-
if not b["packages"]:
58-
continue
59-
60-
# Clean UI labels for isolated VIPs
61-
first_pkg_name = os.path.basename(os.path.normpath(b["packages"][0]))
62-
if first_pkg_name in MAMMOTH_OVERRIDES:
63-
ui_label = first_pkg_name.replace("google-cloud-", "")
64-
else:
65-
ui_label = f"Bucket {b['id']}"
66-
67-
final_output.append({
68-
"id": ui_label,
69-
"packages": " ".join(b["packages"])
70-
})
71-
72-
return final_output
19+
buckets = [{"weight": 0, "pkgs": []} for _ in range(min(len(packages), max_buckets))]
20+
21+
for pkg in packages:
22+
# Find the bucket with the lowest weight, add the package, and update its weight
23+
lightest = min(buckets, key=lambda b: b["weight"])
24+
lightest["pkgs"].append(pkg)
25+
lightest["weight"] += 9999 if os.path.basename(pkg) in VIPS else 1
26+
27+
return [b["pkgs"] for b in buckets]
28+
29+
def build_github_actions_jobs(buckets):
30+
jobs = []
31+
for bucket in buckets:
32+
# Create a clean UI label for the GitHub presubmit check
33+
base_name = os.path.basename(bucket[0]).replace("google-cloud-", "")
34+
job_label = f"{base_name} + {len(bucket) - 1}" if len(bucket) > 1 else base_name
35+
jobs.append({"id": job_label, "packages": " ".join(bucket)})
36+
return jobs
7337

7438
def main():
7539
parser = argparse.ArgumentParser()
7640
parser.add_argument("--matrix-multiplier", type=int, required=True)
77-
parser.add_argument("--max-vms", type=int, default=40)
41+
parser.add_argument("--max-vms", type=int, default=20)
7842
args = parser.parse_args()
7943

80-
safe_github_limit = 250 // args.matrix_multiplier
81-
max_allowed_buckets = min(safe_github_limit, args.max_vms)
44+
packages = get_valid_packages(os.environ.get("CHANGED_DIRS", "").split())
45+
if not packages:
46+
return
8247

83-
changed_dirs = os.environ.get("CHANGED_DIRS", "").split()
84-
buckets = create_balanced_buckets(changed_dirs, max_allowed_buckets)
48+
max_buckets = min(250 // args.matrix_multiplier, args.max_vms)
49+
buckets = distribute_packages(packages, max_buckets)
8550

86-
github_output = os.environ.get("GITHUB_OUTPUT")
87-
if github_output:
88-
with open(github_output, "a") as f:
89-
f.write(f"buckets={json.dumps(buckets)}\n")
51+
jobs_json = json.dumps(build_github_actions_jobs(buckets))
52+
53+
if "GITHUB_OUTPUT" in os.environ:
54+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
55+
f.write(f"buckets={jobs_json}\n")
9056
else:
91-
print(json.dumps(buckets, indent=2))
57+
print(jobs_json)
9258

9359
if __name__ == "__main__":
9460
main()

0 commit comments

Comments
 (0)