Skip to content

Commit 730f77b

Browse files
authored
{CI} Optimize codegen report to support module data and run on manual and Batch CI triggers due to increased execution time (#31660)
1 parent 9b83b33 commit 730f77b

2 files changed

Lines changed: 110 additions & 10 deletions

File tree

azure-pipelines.yml

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,8 +1134,9 @@ jobs:
11341134
exit 1
11351135
fi
11361136
1137-
11381137
- job: CodegenCoverage
1138+
condition: in(variables['Build.Reason'], 'BatchedCI', 'IndividualCI')
1139+
timeoutInMinutes: 180
11391140
displayName: "Codegen Coverage"
11401141
continueOnError: true
11411142
pool:
@@ -1155,14 +1156,29 @@ jobs:
11551156
azdev extension repo add ./azure-cli-extensions
11561157
pip install setuptools==70.0.0 wheel==0.30.0
11571158
azdev extension add "*"
1159+
pip install msrestazure markupsafe==2.0.1
11581160
# Some extension will change the dependence, so run `azdev setup` again after all extensions installed.
1159-
azdev setup -c $CLI_REPO_PATH -r ./azure-cli-extensions
1160-
# CLI repo only
1161-
azdev statistics list-command-table CLI --statistics-only
1162-
# CLI + EXT repos
1163-
pip install jinja2 -U
1164-
azdev statistics list-command-table --statistics-only > /tmp/codegen_report.json
1165-
python s/scripts/ci/codegen_report.py
1161+
azdev setup -c ./s -r ./azure-cli-extensions
1162+
1163+
mkdir -p /tmp/module_stats
1164+
1165+
find /mnt/vss/_work/1/s/src/azure-cli/azure/cli/command_modules/ -mindepth 1 -maxdepth 1 -type d -printf "%f\n" | grep -v '^__pycache__$' > /mnt/vss/_work/1/s/scripts/ci/core_modules.txt
1166+
echo "=== Core Modules ==="
1167+
cat /mnt/vss/_work/1/s/scripts/ci/core_modules.txt
1168+
1169+
find /mnt/vss/_work/1/azure-cli-extensions/src/ -mindepth 1 -maxdepth 1 -type d -printf "%f\n" | grep -v '^__pycache__$' > /mnt/vss/_work/1/s/scripts/ci/extension_modules.txt
1170+
echo "=== Extension Modules ==="
1171+
cat /mnt/vss/_work/1/s/scripts/ci/extension_modules.txt
1172+
1173+
for module in $(cat /mnt/vss/_work/1/s/scripts/ci/core_modules.txt); do
1174+
azdev statistics list-command-table $module --statistics-only > /tmp/module_stats/${module}.json || true
1175+
done
1176+
1177+
for module in $(cat /mnt/vss/_work/1/s/scripts/ci/extension_modules.txt); do
1178+
azdev statistics list-command-table $module --statistics-only > /tmp/module_stats/${module}.json || true
1179+
done
1180+
azdev statistics list-command-table --statistics-only > /tmp/codegen_report.json || true
1181+
python /mnt/vss/_work/1/s/scripts/ci/codegen_report.py
11661182
env:
11671183
BUILD_ID: $(Build.BuildId)
11681184
BUILD_BRANCH: $(Build.SourceBranchName)

scripts/ci/codegen_report.py

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,88 @@
1919
BUILD_ID = os.environ.get('BUILD_ID', None)
2020
BUILD_BRANCH = os.environ.get('BUILD_BRANCH', None)
2121

22+
def load_module_stats():
23+
stats_dir = "/tmp/module_stats"
24+
all_stats = {}
25+
26+
with open("/mnt/vss/_work/1/s/scripts/ci/core_modules.txt", "r") as f:
27+
core_modules = [line.strip() for line in f.readlines()]
28+
29+
with open("/mnt/vss/_work/1/s/scripts/ci/extension_modules.txt", "r") as f:
30+
extension_modules = [line.strip() for line in f.readlines()]
31+
32+
for module in core_modules + extension_modules:
33+
stats_file = os.path.join(stats_dir, f"{module}.json")
34+
if os.path.exists(stats_file):
35+
with open(stats_file, "r") as f:
36+
try:
37+
stats = json.load(f)
38+
codegenV1 = stats.get("codegenV1", 0)
39+
codegenV2 = stats.get("codegenV2", 0)
40+
total = stats.get("total", 0)
41+
manual = total - codegenV1 - codegenV2
42+
all_stats[module] = {
43+
"codegenV1": codegenV1,
44+
"codegenV2": codegenV2,
45+
"manual": manual,
46+
"total": total,
47+
"type": "core" if module in core_modules else "extension"
48+
}
49+
except json.JSONDecodeError:
50+
logger.info(f"Warning: Could not parse {stats_file}")
51+
return all_stats
52+
53+
def analyze_stats(all_stats):
54+
counters = {
55+
"manual": {"core": 0, "extension": 0},
56+
"mixed": {"core": 0, "extension": 0},
57+
"codegen": {"core": 0, "extension": 0},
58+
"codegenV1": {"core": 0, "extension": 0},
59+
"total": {"core": 0, "extension": 0}
60+
}
61+
for _, stats in all_stats.items():
62+
module_type = stats["type"]
63+
counters["total"][module_type] += 1
64+
if stats["manual"] > 0 and (stats["codegenV1"] > 0 or stats["codegenV2"] > 0):
65+
counters["mixed"][module_type] += 1
66+
if stats["codegenV1"] > 0 or stats["codegenV2"] > 0:
67+
counters["codegen"][module_type] += 1
68+
if stats["codegenV1"] > 0:
69+
counters["codegenV1"][module_type] += 1
70+
counters["manual"]["core"] = counters["total"]["core"] - counters["codegen"]["core"]
71+
counters["manual"]["extension"] = counters["total"]["extension"] - counters["codegen"]["extension"]
72+
return counters
73+
74+
def print_results(counters):
75+
logger.info("\n===== Codegen Coverage Report =====")
76+
logger.info("\n1. Manual Modules:")
77+
logger.info(f" Core: {counters['manual']['core']}")
78+
logger.info(f" Extension: {counters['manual']['extension']}")
79+
logger.info("\n2. Mixed Modules:")
80+
logger.info(f" Core: {counters['mixed']['core']}")
81+
logger.info(f" Extension: {counters['mixed']['extension']}")
82+
logger.info("\n3. Codegen Modules:")
83+
logger.info(f" Core: {counters['codegen']['core']}")
84+
logger.info(f" Extension: {counters['codegen']['extension']}")
85+
logger.info("\n4. CodegenV1 Modules:")
86+
logger.info(f" Core: {counters['codegenV1']['core']}")
87+
logger.info(f" Extension: {counters['codegenV1']['extension']}")
88+
logger.info("\n5. Total Modules:")
89+
logger.info(f" Core: {counters['total']['core']}")
90+
logger.info(f" Extension: {counters['total']['extension']}")
91+
92+
def analyze_and_report():
93+
all_stats = load_module_stats()
94+
counters = analyze_stats(all_stats)
95+
print_results(counters)
96+
output = {
97+
"detailed_stats": all_stats,
98+
"summary": counters
99+
}
100+
logger.info("\n=== Detailed JSON Output ===")
101+
logger.info(json.dumps(output, indent=2))
102+
with open("/tmp/module_stats_summary.json", "w") as f:
103+
json.dump(output, f, indent=2)
22104

23105
def generate_csv():
24106
data = []
@@ -31,9 +113,11 @@ def generate_csv():
31113
is_release = True if BUILD_BRANCH == 'release' else False
32114
date = (datetime.datetime.utcnow() + datetime.timedelta(hours=8)).strftime("%Y-%m-%d")
33115
data.append([BUILD_ID, manual, codegenv1, codegenv2, total, is_release, date])
34-
logger.info(f'Finish generate data for codegen report: {data}')
116+
logger.info('Finish generate data for codegen report:')
117+
logger.info("BUILD_ID, manual, codegenv1, codegenv2, total, is_release, date")
118+
logger.info(f'{data}')
35119
return data
36120

37-
38121
if __name__ == '__main__':
122+
analyze_and_report()
39123
generate_csv()

0 commit comments

Comments
 (0)