Skip to content

Commit 415c94f

Browse files
authored
infra: move generate_workflows_lib from contrib to core (open-telemetry#4326)
1 parent 715ec63 commit 415c94f

File tree

6 files changed

+351
-17
lines changed

6 files changed

+351
-17
lines changed
Lines changed: 200 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,205 @@
1+
from collections import defaultdict
12
from pathlib import Path
3+
from re import compile as re_compile
24

3-
from generate_workflows_lib import (
4-
generate_lint_workflow,
5-
generate_misc_workflow,
6-
generate_test_workflow,
5+
from jinja2 import Environment, FileSystemLoader
6+
from tox.config.cli.parse import get_options
7+
from tox.config.sets import CoreConfigSet
8+
from tox.config.source.tox_ini import ToxIni
9+
from tox.session.state import State
10+
11+
_tox_test_env_regex = re_compile(
12+
r"(?P<python_version>py\w+)-test-"
13+
r"(?P<name>[-\w]+\w)-?(?P<test_requirements>\d+)?"
14+
)
15+
_tox_lint_env_regex = re_compile(r"lint-(?P<name>[-\w]+)")
16+
_tox_contrib_env_regex = re_compile(
17+
r"py38-test-(?P<name>[-\w]+\w)-?(?P<contrib_requirements>\d+)?"
718
)
819

9-
tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini")
10-
workflows_directory_path = Path(__file__).parent
1120

12-
generate_test_workflow(
13-
tox_ini_path,
14-
workflows_directory_path,
15-
"ubuntu-latest",
16-
"windows-latest",
17-
)
18-
generate_lint_workflow(tox_ini_path, workflows_directory_path)
19-
generate_misc_workflow(tox_ini_path, workflows_directory_path)
21+
def get_tox_envs(tox_ini_path: Path) -> list:
22+
tox_ini = ToxIni(tox_ini_path)
23+
24+
conf = State(get_options(), []).conf
25+
26+
tox_section = next(tox_ini.sections())
27+
28+
core_config_set = CoreConfigSet(
29+
conf, tox_section, tox_ini_path.parent, tox_ini_path
30+
)
31+
32+
(
33+
core_config_set.loaders.extend(
34+
tox_ini.get_loaders(
35+
tox_section,
36+
base=[],
37+
override_map=defaultdict(list, {}),
38+
conf=core_config_set,
39+
)
40+
)
41+
)
42+
43+
return core_config_set.load("env_list")
44+
45+
46+
def get_test_job_datas(tox_envs: list, operating_systems: list) -> list:
47+
os_alias = {"ubuntu-latest": "Ubuntu", "windows-latest": "Windows"}
48+
49+
python_version_alias = {
50+
"pypy3": "pypy-3.8",
51+
"py38": "3.8",
52+
"py39": "3.9",
53+
"py310": "3.10",
54+
"py311": "3.11",
55+
"py312": "3.12",
56+
}
57+
58+
test_job_datas = []
59+
60+
for operating_system in operating_systems:
61+
for tox_env in tox_envs:
62+
tox_test_env_match = _tox_test_env_regex.match(tox_env)
63+
64+
if tox_test_env_match is None:
65+
continue
66+
67+
groups = tox_test_env_match.groupdict()
68+
69+
aliased_python_version = python_version_alias[
70+
groups["python_version"]
71+
]
72+
tox_env = tox_test_env_match.string
73+
74+
test_requirements = groups["test_requirements"]
75+
76+
if test_requirements is None:
77+
test_requirements = " "
78+
79+
else:
80+
test_requirements = f"-{test_requirements} "
81+
82+
test_job_datas.append(
83+
{
84+
"name": f"{tox_env}_{operating_system}",
85+
"ui_name": (
86+
f"{groups['name']}"
87+
f"{test_requirements}"
88+
f"{aliased_python_version} "
89+
f"{os_alias[operating_system]}"
90+
),
91+
"python_version": aliased_python_version,
92+
"tox_env": tox_env,
93+
"os": operating_system,
94+
}
95+
)
96+
97+
return test_job_datas
98+
99+
100+
def get_lint_job_datas(tox_envs: list) -> list:
101+
lint_job_datas = []
102+
103+
for tox_env in tox_envs:
104+
tox_lint_env_match = _tox_lint_env_regex.match(tox_env)
105+
106+
if tox_lint_env_match is None:
107+
continue
108+
109+
tox_env = tox_lint_env_match.string
110+
111+
lint_job_datas.append(
112+
{
113+
"name": f"{tox_env}",
114+
"ui_name": f"{tox_lint_env_match.groupdict()['name']}",
115+
"tox_env": tox_env,
116+
}
117+
)
118+
119+
return lint_job_datas
120+
121+
122+
def get_misc_job_datas(tox_envs: list) -> list:
123+
regex_patterns = [
124+
_tox_test_env_regex,
125+
_tox_lint_env_regex,
126+
_tox_contrib_env_regex,
127+
re_compile(r"benchmark.+"),
128+
]
129+
130+
return [
131+
tox_env
132+
for tox_env in tox_envs
133+
if not any(pattern.match(tox_env) for pattern in regex_patterns)
134+
]
135+
136+
137+
def _generate_workflow(
138+
job_datas: list,
139+
template_name: str,
140+
output_dir: Path,
141+
max_jobs: int = 250,
142+
):
143+
# Github seems to limit the amount of jobs in a workflow file, that is why
144+
# they are split in groups of 250 per workflow file.
145+
for file_number, job_datas in enumerate(
146+
[
147+
job_datas[index : index + max_jobs]
148+
for index in range(0, len(job_datas), max_jobs)
149+
]
150+
):
151+
with open(
152+
output_dir.joinpath(f"{template_name}_{file_number}.yml"), "w"
153+
) as test_yml_file:
154+
test_yml_file.write(
155+
Environment(
156+
loader=FileSystemLoader(
157+
Path(__file__).parent.joinpath("templates")
158+
)
159+
)
160+
.get_template(f"{template_name}.yml.j2")
161+
.render(job_datas=job_datas, file_number=file_number)
162+
)
163+
test_yml_file.write("\n")
164+
165+
166+
def generate_test_workflow(
167+
tox_ini_path: Path, workflow_directory_path: Path, operating_systems
168+
) -> None:
169+
_generate_workflow(
170+
get_test_job_datas(get_tox_envs(tox_ini_path), operating_systems),
171+
"test",
172+
workflow_directory_path,
173+
)
174+
175+
176+
def generate_lint_workflow(
177+
tox_ini_path: Path,
178+
workflow_directory_path: Path,
179+
) -> None:
180+
_generate_workflow(
181+
get_lint_job_datas(get_tox_envs(tox_ini_path)),
182+
"lint",
183+
workflow_directory_path,
184+
)
185+
186+
187+
def generate_misc_workflow(
188+
tox_ini_path: Path,
189+
workflow_directory_path: Path,
190+
) -> None:
191+
_generate_workflow(
192+
get_misc_job_datas(get_tox_envs(tox_ini_path)),
193+
"misc",
194+
workflow_directory_path,
195+
)
196+
197+
198+
if __name__ == "__main__":
199+
tox_ini_path = Path(__file__).parent.parent.parent.joinpath("tox.ini")
200+
output_dir = Path(__file__).parent
201+
generate_test_workflow(
202+
tox_ini_path, output_dir, ["ubuntu-latest", "windows-latest"]
203+
)
204+
generate_lint_workflow(tox_ini_path, output_dir)
205+
generate_misc_workflow(tox_ini_path, output_dir)

.github/workflows/misc_0.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ jobs:
233233
- name: Run tests
234234
run: tox -e generate-workflows
235235

236-
- name: Check workflows are up to date
236+
- name: Check github workflows are up to date
237237
run: git diff --exit-code || (echo 'Generated workflows are out of date, run "tox -e generate-workflows" and commit the changes in this PR.' && exit 1)
238238

239239
ruff:
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Do not edit this file.
2+
# This file is generated automatically by executing tox -e generate-workflows
3+
4+
name: Lint {{ file_number }}
5+
6+
on:
7+
push:
8+
branches-ignore:
9+
- 'release/*'
10+
pull_request:
11+
12+
env:
13+
CORE_REPO_SHA: main
14+
CONTRIB_REPO_SHA: main
15+
PIP_EXISTS_ACTION: w
16+
17+
jobs:
18+
{%- for job_data in job_datas %}
19+
20+
{{ job_data.name }}:
21+
name: {{ job_data.ui_name }}
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %}
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Python 3.12
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: "3.12"
31+
32+
- name: Install tox
33+
run: pip install tox
34+
35+
- name: Run tests
36+
run: tox -e {{ job_data.tox_env }}
37+
{%- endfor %}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Do not edit this file.
2+
# This file is generated automatically by executing tox -e generate-workflows
3+
4+
name: Misc {{ file_number }}
5+
6+
on:
7+
push:
8+
branches-ignore:
9+
- 'release/*'
10+
pull_request:
11+
12+
env:
13+
CORE_REPO_SHA: main
14+
CONTRIB_REPO_SHA: main
15+
PIP_EXISTS_ACTION: w
16+
17+
jobs:
18+
{%- for job_data in job_datas %}
19+
20+
{{ job_data }}:
21+
name: {{ job_data }}
22+
runs-on: ubuntu-latest
23+
{%- if job_data == "generate-workflows" %}
24+
if: |
25+
!contains(github.event.pull_request.labels.*.name, 'Skip generate-workflows')
26+
&& github.event.pull_request.user.login != 'opentelemetrybot' && github.event_name == 'pull_request'
27+
{%- endif %}
28+
{%- if job_data == "public-symbols-check" %}
29+
if: |
30+
!contains(github.event.pull_request.labels.*.name, 'Approve Public API check')
31+
&& github.actor != 'opentelemetrybot' && github.event_name == 'pull_request'
32+
{%- endif %}
33+
{%- if job_data == "docs" %}
34+
if: |
35+
github.event.pull_request.user.login != 'opentelemetrybot' && github.event_name == 'pull_request'
36+
{%- endif %}
37+
steps:
38+
- name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %}
39+
uses: actions/checkout@v4
40+
{%- if job_data == "public-symbols-check" %}
41+
with:
42+
fetch-depth: 0
43+
44+
- name: Checkout main
45+
run: git checkout main
46+
47+
- name: Pull origin
48+
run: git pull --rebase=false origin main
49+
50+
- name: Checkout pull request
51+
run: git checkout ${% raw %}{{ github.event.pull_request.head.sha }}{% endraw %}
52+
{%- endif %}
53+
54+
- name: Set up Python 3.11
55+
uses: actions/setup-python@v5
56+
with:
57+
python-version: "3.11"
58+
59+
- name: Install tox
60+
run: pip install tox
61+
62+
- name: Run tests
63+
run: tox -e {{ job_data }}
64+
{%- if job_data == "generate-workflows" %}
65+
66+
- name: Check github workflows are up to date
67+
run: git diff --exit-code || (echo 'Generated workflows are out of date, run "tox -e generate-workflows" and commit the changes in this PR.' && exit 1)
68+
{%- endif %}
69+
{%- endfor %}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Do not edit this file.
2+
# This file is generated automatically by executing tox -e generate-workflows
3+
4+
name: Test {{ file_number }}
5+
6+
on:
7+
push:
8+
branches-ignore:
9+
- 'release/*'
10+
pull_request:
11+
12+
env:
13+
CORE_REPO_SHA: main
14+
CONTRIB_REPO_SHA: main
15+
PIP_EXISTS_ACTION: w
16+
17+
jobs:
18+
{%- for job_data in job_datas %}
19+
20+
{{ job_data.name }}:
21+
name: {{ job_data.ui_name }}
22+
runs-on: {{ job_data.os }}
23+
steps:
24+
- name: Checkout repo @ SHA - ${% raw %}{{ github.sha }}{% endraw %}
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Python {{ job_data.python_version }}
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: "{{ job_data.python_version }}"
31+
32+
- name: Install tox
33+
run: pip install tox
34+
{%- if job_data.os == "windows-latest" %}
35+
36+
- name: Configure git to support long filenames
37+
run: git config --system core.longpaths true
38+
{%- endif %}
39+
40+
- name: Run tests
41+
run: tox -e {{ job_data.tox_env }} -- -ra
42+
{%- endfor %}

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,9 @@ commands =
334334
python {toxinidir}/scripts/public_symbols_checker.py
335335

336336
[testenv:generate-workflows]
337-
recreate = True
338337
deps =
339-
{env:CONTRIB_REPO}\#egg=generate_workflows_lib&subdirectory=.github/workflows/generate_workflows_lib
338+
tox
339+
Jinja2
340340
commands =
341341
python {toxinidir}/.github/workflows/generate_workflows.py
342342

0 commit comments

Comments
 (0)