Skip to content

Commit edc5352

Browse files
authored
ci: run Python checks on ARC runners (#234)
2 parents c119607 + ca7ea14 commit edc5352

17 files changed

Lines changed: 1257 additions & 11935 deletions

.github/workflows/generate_workflows.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,21 @@
99

1010
tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini")
1111
workflows_directory_path = Path(__file__).parent
12+
arc_runner_label = "loongsuite-python-arc"
1213

13-
generate_test_workflow(tox_ini_path, workflows_directory_path, "ubuntu-latest")
14-
generate_lint_workflow(tox_ini_path, workflows_directory_path)
14+
generate_test_workflow(
15+
tox_ini_path,
16+
workflows_directory_path,
17+
arc_runner_label,
18+
batch_size=4,
19+
parallelism=4,
20+
)
21+
generate_lint_workflow(
22+
tox_ini_path,
23+
workflows_directory_path,
24+
arc_runner_label,
25+
batch_size=4,
26+
parallelism=4,
27+
)
1528
generate_misc_workflow(tox_ini_path, workflows_directory_path)
1629
generate_contrib_workflow(workflows_directory_path)

.github/workflows/generate_workflows_lib/src/generate_workflows_lib/__init__.py

Lines changed: 130 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@
1616
_tox_contrib_env_regex = re_compile(
1717
r"py39-test-(?P<name>[-\w]+\w)-?(?P<contrib_requirements>\d+)?"
1818
)
19+
_OS_ALIASES = {
20+
"ubuntu-latest": "Ubuntu",
21+
"windows-latest": "Windows",
22+
"loongsuite-python-arc": "ARC",
23+
}
24+
25+
26+
def _slug(value: str) -> str:
27+
return (
28+
str(value).lower().replace(".", "").replace("-", "_").replace(" ", "_")
29+
)
1930

2031

2132
def _get_job_package_name(name: str, package_names=None) -> str:
@@ -59,8 +70,6 @@ def get_test_job_datas(
5970
operating_systems: list,
6071
package_names=None,
6172
) -> list:
62-
os_alias = {"ubuntu-latest": "Ubuntu", "windows-latest": "Windows"}
63-
6473
python_version_alias = {
6574
"pypy3": "pypy-3.9",
6675
"pypy310": "pypy-3.10",
@@ -103,7 +112,7 @@ def get_test_job_datas(
103112
f"{groups['name']}"
104113
f"{test_requirements}"
105114
f"{aliased_python_version} "
106-
f"{os_alias[operating_system]}"
115+
f"{_OS_ALIASES[operating_system]}"
107116
),
108117
"package": _get_job_package_name(
109118
groups["name"],
@@ -193,9 +202,80 @@ def get_misc_job_datas(tox_envs: list) -> list:
193202
return misc_job_datas
194203

195204

205+
def _batch_job_datas(
206+
job_datas: list,
207+
batch_size: int,
208+
parallelism: int,
209+
group_keys=(),
210+
) -> list:
211+
if batch_size < 1:
212+
raise ValueError("batch_size must be >= 1")
213+
214+
if parallelism < 1:
215+
raise ValueError("parallelism must be >= 1")
216+
217+
grouped_job_datas = {}
218+
for job_data in job_datas:
219+
key = tuple(job_data.get(group_key) for group_key in group_keys)
220+
grouped_job_datas.setdefault(key, []).append(job_data)
221+
222+
batched_job_datas = []
223+
batch_index = 0
224+
225+
for group in grouped_job_datas.values():
226+
for chunk_start in range(0, len(group), batch_size):
227+
chunk = group[chunk_start : chunk_start + batch_size]
228+
first_job_data = chunk[0]
229+
tox_envs = [job_data["tox_env"] for job_data in chunk]
230+
231+
if len(chunk) == 1:
232+
batched_job_data = dict(first_job_data)
233+
batched_job_data["tox_envs"] = tox_envs
234+
batched_job_data["parallelism"] = 1
235+
batched_job_data["env_count"] = 1
236+
batched_job_datas.append(batched_job_data)
237+
continue
238+
239+
batch_index += 1
240+
name_parts = [
241+
_slug(first_job_data[group_key])
242+
for group_key in group_keys
243+
if group_key in first_job_data
244+
]
245+
name_suffix = "_".join(name_parts) if name_parts else "tox"
246+
247+
if "python_version" in first_job_data and "os" in first_job_data:
248+
ui_prefix = (
249+
f"{first_job_data['python_version']} "
250+
f"{_OS_ALIASES.get(first_job_data['os'], first_job_data['os'])}"
251+
)
252+
else:
253+
ui_prefix = "tox"
254+
255+
batched_job_data = dict(first_job_data)
256+
batched_job_data["name"] = f"batch_{batch_index:03d}_{name_suffix}"
257+
batched_job_data["ui_name"] = (
258+
f"{ui_prefix} batch {batch_index:03d} ({len(chunk)} envs)"
259+
)
260+
batched_job_data["tox_env"] = tox_envs[0]
261+
batched_job_data["tox_envs"] = tox_envs
262+
batched_job_data["parallelism"] = min(parallelism, len(chunk))
263+
batched_job_data["env_count"] = len(chunk)
264+
batched_job_datas.append(batched_job_data)
265+
266+
return batched_job_datas
267+
268+
196269
def _generate_workflow(
197-
job_datas: list, name: str, workflow_directory_path: Path, max_jobs=250
270+
job_datas: list,
271+
name: str,
272+
workflow_directory_path: Path,
273+
max_jobs=250,
274+
runner="ubuntu-latest",
198275
):
276+
for stale_workflow_path in workflow_directory_path.glob(f"{name}_*.yml"):
277+
stale_workflow_path.unlink()
278+
199279
# Github seems to limit the amount of jobs in a workflow file, that is why
200280
# they are split in groups of 250 per workflow file.
201281
for file_number, job_datas in enumerate(
@@ -210,16 +290,32 @@ def _generate_workflow(
210290
test_yml_file.write(
211291
Environment(loader=FileSystemLoader(Path(__file__).parent))
212292
.get_template(f"{name}.yml.j2")
213-
.render(job_datas=job_datas, file_number=file_number)
293+
.render(
294+
job_datas=job_datas,
295+
file_number=file_number,
296+
runner=runner,
297+
)
214298
)
215299
test_yml_file.write("\n")
216300

217301

218302
def generate_test_workflow(
219-
tox_ini_path: Path, workflow_directory_path: Path, *operating_systems
303+
tox_ini_path: Path,
304+
workflow_directory_path: Path,
305+
*operating_systems,
306+
batch_size=1,
307+
parallelism=1,
220308
) -> None:
309+
job_datas = get_test_job_datas(
310+
get_tox_envs(tox_ini_path), operating_systems
311+
)
221312
_generate_workflow(
222-
get_test_job_datas(get_tox_envs(tox_ini_path), operating_systems),
313+
_batch_job_datas(
314+
job_datas,
315+
batch_size=batch_size,
316+
parallelism=parallelism,
317+
group_keys=("os", "python_version"),
318+
),
223319
"test",
224320
workflow_directory_path,
225321
)
@@ -228,11 +324,20 @@ def generate_test_workflow(
228324
def generate_lint_workflow(
229325
tox_ini_path: Path,
230326
workflow_directory_path: Path,
327+
runner="ubuntu-latest",
328+
batch_size=1,
329+
parallelism=1,
231330
) -> None:
331+
job_datas = get_lint_job_datas(get_tox_envs(tox_ini_path))
232332
_generate_workflow(
233-
get_lint_job_datas(get_tox_envs(tox_ini_path)),
333+
_batch_job_datas(
334+
job_datas,
335+
batch_size=batch_size,
336+
parallelism=parallelism,
337+
),
234338
"lint",
235339
workflow_directory_path,
340+
runner=runner,
236341
)
237342

238343

@@ -293,6 +398,7 @@ def generate_extension_test_workflow(
293398
workflow_directory_path: Path,
294399
additional_config_path: Path,
295400
*operating_systems,
401+
control_runner="ubuntu-latest",
296402
) -> None:
297403
loongsuite_envs = get_loongsuite_tox_envs(additional_config_path)
298404
if not loongsuite_envs:
@@ -310,13 +416,16 @@ def generate_extension_test_workflow(
310416
"loongsuite_test",
311417
"loongsuite_test",
312418
workflow_directory_path,
419+
control_runner=control_runner,
313420
)
314421

315422

316423
def generate_extension_lint_workflow(
317424
tox_ini_path: Path,
318425
workflow_directory_path: Path,
319426
additional_config_path: Path,
427+
runner="ubuntu-latest",
428+
control_runner="ubuntu-latest",
320429
) -> None:
321430
loongsuite_envs = get_loongsuite_tox_envs(additional_config_path)
322431
if not loongsuite_envs:
@@ -327,6 +436,8 @@ def generate_extension_lint_workflow(
327436
"loongsuite_lint",
328437
"loongsuite_lint",
329438
workflow_directory_path,
439+
runner=runner,
440+
control_runner=control_runner,
330441
)
331442

332443

@@ -353,6 +464,8 @@ def _generate_workflow_with_template(
353464
template_name: str,
354465
workflow_directory_path: Path,
355466
max_jobs=250,
467+
runner="ubuntu-latest",
468+
control_runner="ubuntu-latest",
356469
):
357470
if (
358471
name in {"loongsuite_lint", "loongsuite_test"}
@@ -364,6 +477,9 @@ def _generate_workflow_with_template(
364477
"cross-workflow aggregate before allowing generated chunks."
365478
)
366479

480+
for stale_workflow_path in workflow_directory_path.glob(f"{name}_*.yml"):
481+
stale_workflow_path.unlink()
482+
367483
# Github seems to limit the amount of jobs in a workflow file, that is why
368484
# they are split in groups of 250 per workflow file.
369485
for file_number, job_datas in enumerate(
@@ -378,6 +494,11 @@ def _generate_workflow_with_template(
378494
test_yml_file.write(
379495
Environment(loader=FileSystemLoader(Path(__file__).parent))
380496
.get_template(f"{template_name}.yml.j2")
381-
.render(job_datas=job_datas, file_number=file_number)
497+
.render(
498+
job_datas=job_datas,
499+
file_number=file_number,
500+
runner=runner,
501+
control_runner=control_runner,
502+
)
382503
)
383504
test_yml_file.write("\n")

.github/workflows/generate_workflows_lib/src/generate_workflows_lib/lint.yml.j2

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ name: Lint {{ file_number }}
55

66
on:
77
push:
8-
branches-ignore:
9-
- 'release/*'
10-
- 'otelbot/*'
8+
branches:
9+
- main
1110
pull_request:
1211

1312
permissions:
1413
contents: read
1514

1615
concurrency:
17-
group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %}
16+
group: ${% raw %}{{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref || github.run_id }}{% endraw %}
1817
cancel-in-progress: true
1918

2019
env:
@@ -36,7 +35,7 @@ jobs:
3635

3736
{{ job_data.name }}:
3837
name: {{ job_data.ui_name }}
39-
runs-on: ubuntu-latest
38+
runs-on: {{ runner }}
4039
timeout-minutes: 30
4140
steps:
4241
- name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %}
@@ -51,5 +50,9 @@ jobs:
5150
run: pip install tox-uv
5251

5352
- name: Run tests
54-
run: tox -e {{ job_data.tox_env }}
53+
{%- if job_data.env_count == 1 %}
54+
run: tox -e {{ job_data.tox_envs[0] }}
55+
{%- else %}
56+
run: tox run-parallel -p {{ job_data.parallelism }} -e {{ job_data.tox_envs | join(',') }}
57+
{%- endif %}
5558
{%- endfor %}

.github/workflows/generate_workflows_lib/src/generate_workflows_lib/loongsuite_lint.yml.j2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ permissions:
1515
contents: read
1616

1717
concurrency:
18-
group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %}
18+
group: ${% raw %}{{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref || github.run_id }}{% endraw %}
1919
cancel-in-progress: true
2020

2121
env:
@@ -34,7 +34,7 @@ env:
3434
jobs:
3535
loongsuite_changes:
3636
name: LoongSuite changed packages
37-
runs-on: ubuntu-latest
37+
runs-on: {{ control_runner }}
3838
outputs:
3939
full: ${% raw %}{{ steps.detect.outputs.full }}{% endraw %}
4040
packages: ${% raw %}{{ steps.detect.outputs.packages }}{% endraw %}
@@ -105,7 +105,7 @@ jobs:
105105
name: LoongSuite ${% raw %}{{ matrix.ui_name }}{% endraw %}
106106
needs: loongsuite_changes
107107
if: ${% raw %}{{ needs.loongsuite_changes.outputs.has_jobs == 'true' }}{% endraw %}
108-
runs-on: ubuntu-latest
108+
runs-on: {{ runner }}
109109
timeout-minutes: 30
110110
strategy:
111111
fail-fast: false
@@ -131,7 +131,7 @@ jobs:
131131
- loongsuite_changes
132132
- loongsuite_lint
133133
if: ${% raw %}{{ always() }}{% endraw %}
134-
runs-on: ubuntu-latest
134+
runs-on: {{ control_runner }}
135135
steps:
136136
- name: Check LoongSuite lint result
137137
shell: bash

.github/workflows/generate_workflows_lib/src/generate_workflows_lib/loongsuite_misc.yml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ permissions:
1515
contents: read
1616

1717
concurrency:
18-
group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %}
18+
group: ${% raw %}{{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref || github.run_id }}{% endraw %}
1919
cancel-in-progress: true
2020

2121
env:

.github/workflows/generate_workflows_lib/src/generate_workflows_lib/loongsuite_test.yml.j2

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ permissions:
1515
contents: read
1616

1717
concurrency:
18-
group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %}
18+
group: ${% raw %}{{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref || github.run_id }}{% endraw %}
1919
cancel-in-progress: true
2020

2121
env:
@@ -34,7 +34,7 @@ env:
3434
jobs:
3535
loongsuite_changes:
3636
name: LoongSuite changed packages
37-
runs-on: ubuntu-latest
37+
runs-on: {{ control_runner }}
3838
outputs:
3939
full: ${% raw %}{{ steps.detect.outputs.full }}{% endraw %}
4040
packages: ${% raw %}{{ steps.detect.outputs.packages }}{% endraw %}
@@ -137,7 +137,7 @@ jobs:
137137
- loongsuite_changes
138138
- loongsuite_test
139139
if: ${% raw %}{{ always() }}{% endraw %}
140-
runs-on: ubuntu-latest
140+
runs-on: {{ control_runner }}
141141
steps:
142142
- name: Check LoongSuite test result
143143
shell: bash

.github/workflows/generate_workflows_lib/src/generate_workflows_lib/misc.yml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ permissions:
1414
contents: read
1515

1616
concurrency:
17-
group: ${% raw %}{{ github.workflow }}-${{ github.head_ref || github.run_id }}{% endraw %}
17+
group: ${% raw %}{{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref || github.run_id }}{% endraw %}
1818
cancel-in-progress: true
1919

2020
env:

0 commit comments

Comments
 (0)