Skip to content

Commit 68cff18

Browse files
authored
GItHub CI: Run linux amd64+aarch64 retagger weekly jobs and enable auto tests on PR
Summary: What this does: - Build python-svm and upload it so next jobs can use it. - Run {RETAGGER_SPLIT} retaggers batches and upload each JSON reports using the {MX_REPORT_SUFFIX} suffix. - Merge all reports, run the merge-tags-from-reports from runner.py Uploaded artifacts: - graalpy_standalone jvm and native => used by next jobs to speed up the process - retagger-report.json files => used by the merger - report_diff => git diff that contains all the tagges unittests changes This commit only support Linux amd64?aarch64 atm, darwin and windows are WIP.
1 parent 5304b47 commit 68cff18

File tree

189 files changed

+26588
-26651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+26588
-26651
lines changed

.github/scripts/extract_matrix.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"GITHUB_CI": "true"
1919
}
2020

21+
PR_JOBS='^(?=.*python)(?!.*(retagger|dsl)).*$'
2122

2223
# If any of these terms are in the job json, they do not run in public
2324
# infrastructure
@@ -208,6 +209,7 @@ def download_artifact(self) -> Artifact | None:
208209
pattern = self.common_glob([a["name"] for a in artifacts])
209210
return Artifact(pattern, os.path.normpath(artifacts[0].get("dir", ".")))
210211
return None
212+
211213

212214
@staticmethod
213215
def flatten_command(args: list[str | list[str]]) -> list[str]:
@@ -293,6 +295,8 @@ def get_tagged_jobs(buildspec, target, filter=None):
293295

294296

295297
def main(jsonnet_bin, ci_jsonnet, target, filter=None, indent=False):
298+
if not filter: filter = PR_JOBS
299+
296300
result = subprocess.check_output([jsonnet_bin, ci_jsonnet], text=True)
297301
buildspec = json.loads(result)
298302
tagged_jobs = get_tagged_jobs(buildspec, target, filter=filter)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# ================================
2+
#
3+
# This script is used by ci to merge several retagger report JSON files, which is then used
4+
# by running python3 runner.py merge-tags-from-reports reports-merged.json
5+
#
6+
# ================================
7+
8+
import os
9+
import sys
10+
import json
11+
import glob
12+
import argparse
13+
from dataclasses import dataclass
14+
15+
# status we want to focus on
16+
EXPORT_STATUS = ["FAILED"]
17+
18+
@dataclass
19+
class Test:
20+
name: str
21+
status: str
22+
duration: str
23+
24+
25+
def read_report(path: str) -> list[Test]:
26+
tests = []
27+
with open(path) as f:
28+
data = json.load(f)
29+
for result in data:
30+
name, status, duration = result.values()
31+
if status in EXPORT_STATUS: tests.append(Test(f"{name}", status, duration))
32+
33+
return tests
34+
35+
def merge_tests(report: list[Test], merged: dict[str, dict]):
36+
for test in report:
37+
if test.name not in merged:
38+
merged[test.name] = test.__dict__
39+
40+
def export_reports(merged: dict[str, dict], outfile: str):
41+
with open(outfile, "w") as f:
42+
json.dump(list(merged.values()), f)
43+
print(f"=== Exported {len(merged)} ({EXPORT_STATUS}) tests to {f.name} ===")
44+
45+
def merge_reports(reports: list[str], outfile: str):
46+
merged_reports = {}
47+
for report in reports:
48+
report_tests = read_report(report)
49+
merge_tests(report_tests, merged_reports)
50+
51+
export_reports(merged_reports, outfile)
52+
53+
def main(outfile: str, source_dir: str, pattern: str):
54+
path = f"{source_dir}/{pattern}"
55+
files = glob.glob(path)
56+
if len(files) == 0: raise FileNotFoundError("No report file found")
57+
58+
files = [file for file in files if file.endswith(".json")]
59+
merge_reports(files, outfile)
60+
61+
62+
if __name__ == "__main__":
63+
parser = argparse.ArgumentParser(description="Merge unittest retagger report JSON files")
64+
parser.add_argument("--outfile", help="Output file name (optional)", default="reports-merged.json")
65+
parser.add_argument("--dir", help="Reports files directory (optional)", default=".")
66+
parser.add_argument("--pattern", default="*", help="Pattern matching for input files (optional)")
67+
68+
args = parser.parse_args()
69+
main(
70+
outfile=args.outfile,
71+
source_dir=args.dir,
72+
pattern=args.pattern
73+
)

.github/workflows/ci-matrix-gen.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ on:
77
type: string
88
description: Job selection (Python regex)
99
required: false
10+
pull_request:
11+
schedule:
12+
- cron: '0 0 * * 1'
1013

1114
jobs:
1215
generate-tier1:
@@ -15,7 +18,7 @@ jobs:
1518
matrix: ${{ steps.set-matrix.outputs.matrix }}
1619
env:
1720
TARGET: tier1
18-
JOBS: ${{ inputs.jobs_to_run }}
21+
JOBS: ${{ inputs.jobs_to_run || (github.event_name == 'schedule' && 'python-svm-build-gate-linux|python-unittest-retagger|python-unittest-retagger-merge') || ''}}
1922
steps: &generate_matrix
2023
- uses: actions/checkout@v4
2124
- name: Download sjsonnet
@@ -153,9 +156,10 @@ jobs:
153156
uses: actions/download-artifact@v5
154157
if: ${{ matrix.require_artifact }}
155158
with:
156-
name: ${{ matrix.require_artifact[0] }}
159+
pattern: ${{ matrix.require_artifact[0] }}
157160
merge-multiple: true
158161
continue-on-error: true
162+
159163
- name: Export artifact paths Linux
160164
if: ${{ matrix.require_artifact }}
161165
run: |
@@ -203,8 +207,8 @@ jobs:
203207
shell: bash
204208
working-directory: main
205209
run: |
206-
tar cf ${{ matrix.provide_artifact[0] }}.tar ${{ matrix.provide_artifact[1] }}
207210
ls && pwd
211+
tar cf ${{ matrix.provide_artifact[0] }}.tar ${{ matrix.provide_artifact[1] }}
208212
- name: Upload artifacts
209213
if: ${{ matrix.provide_artifact }}
210214
uses: actions/upload-artifact@v5

ci.jsonnet

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
local GRAAL_JDK_LATEST = "graal-jdk-latest",
102102
local TAGGED_UNITTESTS_SPLIT = 8,
103103
local COVERAGE_SPLIT = 3,
104-
local RETAGGER_SPLIT = 8,
104+
local RETAGGER_SPLIT = 12,
105105

106106
// -----------------------------------------------------------------------------------------------------------------
107107
// gates
@@ -242,8 +242,8 @@
242242
"linux:amd64:jdk-latest" : tier1,
243243
}),
244244
"python-unittest-retagger": ut_retagger + platform_spec(no_jobs) + batches(RETAGGER_SPLIT) + platform_spec({
245-
"linux:amd64:jdk-latest" : tier3,
246-
"linux:aarch64:jdk-latest" : weekly + t("20:00:00"),
245+
"linux:amd64:jdk-latest" : tier2 + require(GPY_NATIVE_STANDALONE),
246+
"linux:aarch64:jdk-latest" : tier3 + require(GPY_NATIVE_STANDALONE),
247247
"darwin:aarch64:jdk-latest" : weekly + t("20:00:00"),
248248
"windows:amd64:jdk-latest" : weekly + t("20:00:00"),
249249
}),
@@ -548,6 +548,37 @@
548548
["git", "push", "--force", "origin", "published"],
549549
]
550550
},
551+
{
552+
name: "python-unittest-retagger-merge",
553+
targets: ["tier3"],
554+
capabilities: ["linux", "amd64"],
555+
packages: {
556+
mx: "7.34.1",
557+
python3: "==3.12.8",
558+
},
559+
requireArtifacts: [
560+
{
561+
name: "python-unittest-retagger*",
562+
dir: ".",
563+
}
564+
],
565+
publishArtifacts: [
566+
{
567+
name: "retagger.diff",
568+
dir: ".",
569+
patterns: ["diff_reports"]
570+
}
571+
],
572+
run: [
573+
["mkdir", "-p", "../retagger-reports"],
574+
["sh", "-c", "mv retagger-report*.json ../retagger-reports"],
575+
["cd", "../retagger-reports"],
576+
["python3", "../main/.github/scripts/merge_retagger_results.py"],
577+
["cd", "../main"],
578+
["python3", "./graalpython/com.oracle.graal.python.test/src/runner.py", "merge-tags-from-report", "../retagger-reports/reports-merged.json"],
579+
["sh", "-c", "git diff >> diff_reports"],
580+
]
581+
},
551582
],
552583
}
553584

ci/python-gate.libsonnet

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@
340340
task_spec({
341341
environment+: {
342342
TAGGED_UNITTEST_PARTIAL: "%d/%d" % [i, num],
343+
RETAGGER_BATCH_NO: i,
344+
MX_REPORT_SUFFIX: "_batch_%d" % [i],
343345
},
344346
variations+::["batch" + i]
345347
}),
@@ -510,11 +512,11 @@
510512
# The default timeout is very generous to allow for infrastructure flakiness,
511513
# but we don't want to auto tag tests that take a long time
512514
"--timeout-factor", "0.3",
513-
"--mx-report", "report.json",
515+
"--mx-report", "retagger-report.json",
514516
"--exit-success-on-failures",
515517
],
516518
],
517-
logs+: ["*/*/report.json"],
519+
logs+: ["main/retagger-report*.json"],
518520
}),
519521

520522
coverage_gate:: $.graalpy_gate + task_spec({

graalpython/com.oracle.graal.python.test/src/runner.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ def run_tests(self, tests: list['TestSuite']):
446446
self.display_summary()
447447

448448
def generate_mx_report(self, path: str):
449+
# Some reports may be split when ran on github, this sets different file names
450+
report_suffix = os.environ.get("MX_REPORT_SUFFIX")
451+
if report_suffix:
452+
tmppath, ext = os.path.splitext(path)
453+
path = f"{tmppath}{report_suffix}{ext}"
454+
449455
report_data = []
450456
for result in self.results:
451457
# Skip synthetic results for failed class setups and such
@@ -496,6 +502,7 @@ def update_tags(test_file: 'TestFile', results: list[TestResult], tag_platform:
496502
tag_by_id[tag.test_id] = tag
497503

498504
for test_id, status in status_by_id.items():
505+
499506
if tag := tag_by_id.get(test_id):
500507
if status == TestStatus.SUCCESS:
501508
tag_by_id[test_id] = tag.with_key(tag_platform)
@@ -1349,7 +1356,7 @@ def main_merge_tags(args):
13491356
test_file,
13501357
results,
13511358
tag_platform=args.platform,
1352-
untag_failed=False,
1359+
untag_failed= os.environ.get("GITHUB_CI") is not None,
13531360
untag_skipped=True,
13541361
untag_missing=True,
13551362
)
@@ -1509,7 +1516,7 @@ def main():
15091516
# merge-tags-from-report command declaration
15101517
merge_tags_parser = subparsers.add_parser('merge-tags-from-report', help="Merge tags from automated retagger")
15111518
merge_tags_parser.set_defaults(main=main_merge_tags)
1512-
merge_tags_parser.add_argument('platform')
1519+
merge_tags_parser.add_argument('--platform', default=CURRENT_PLATFORM)
15131520
merge_tags_parser.add_argument('report_path')
15141521

15151522
# run the appropriate command

0 commit comments

Comments
 (0)