Skip to content

Commit b2f1fd2

Browse files
committed
Refactor make_github_ci into a class.
1 parent 0bddbb4 commit b2f1fd2

File tree

1 file changed

+166
-76
lines changed

1 file changed

+166
-76
lines changed

repo_helper/files/ci_cd.py

Lines changed: 166 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
# stdlib
2727
import pathlib
28-
from typing import List
28+
from typing import Iterator, List
2929

3030
# 3rd party
3131
import jinja2
@@ -47,6 +47,7 @@
4747
"ensure_bumpversion",
4848
"make_actions_deploy_conda",
4949
"make_conda_actions_ci",
50+
"ActionsManager",
5051
]
5152

5253

@@ -92,100 +93,189 @@ def make_github_ci(repo_path: pathlib.Path, templates: jinja2.Environment) -> Li
9293

9394
# Matrix of OSs: https://youtu.be/KKJL8bM4cis?t=536
9495

95-
# TODO: Allowed failure for -dev versions
96+
manager = ActionsManager(repo_path, templates)
9697

97-
actions = templates.get_template("github_ci.yml")
98+
return [
99+
manager.make_windows().relative_to(repo_path).as_posix(),
100+
manager.make_macos().relative_to(repo_path).as_posix(),
101+
manager.make_linux().relative_to(repo_path).as_posix(),
102+
]
98103

99-
workflows_dir = PathPlus(repo_path / ".github" / "workflows")
100-
workflows_dir.maybe_make(parents=True)
101104

102-
windows_ci_file = workflows_dir / "python_ci.yml"
103-
macos_ci_file = workflows_dir / "python_ci_macos.yml"
104-
linux_ci_file = workflows_dir / "python_ci_linux.yml"
105+
class ActionsManager:
106+
"""
107+
Responsible for creating, updating and removing GitHub Actions workflows.
108+
109+
:param repo_path: Path to the repository root.
110+
:param templates:
111+
112+
.. versionadded:: 2020.12.18
113+
"""
114+
115+
def __init__(self, repo_path: pathlib.Path, templates: jinja2.Environment):
116+
self.repo_path = repo_path
117+
self.templates = templates
118+
119+
self.actions = templates.get_template("github_ci.yml")
120+
121+
self.workflows_dir = PathPlus(repo_path / ".github" / "workflows")
122+
self.workflows_dir.maybe_make(parents=True)
123+
124+
def make_windows(self) -> PathPlus:
125+
"""
126+
Create, update or remove the Windows action, as appropriate.
127+
"""
128+
129+
platform_name = "Windows"
130+
ci_file = self.workflows_dir / "python_ci.yml"
131+
132+
if platform_name in self.templates.globals["platforms"]:
133+
ci_file.write_clean(
134+
self.actions.render(
135+
no_dev_versions=no_dev_versions,
136+
ci_platform=platform_ci_names[platform_name],
137+
ci_name=platform_name,
138+
python_versions=set_gh_actions_versions(self.get_windows_ci_versions()),
139+
dependency_lines=self.get_windows_ci_requirements(),
140+
)
141+
)
142+
elif ci_file.is_file():
143+
ci_file.unlink()
144+
145+
return ci_file
146+
147+
def make_macos(self) -> PathPlus:
148+
"""
149+
Create, update or remove the macOS action, as appropriate.
150+
"""
151+
152+
platform_name = "macOS"
153+
ci_file = self.workflows_dir / f"python_ci_{platform_name.lower()}.yml"
154+
155+
if platform_name in self.templates.globals["platforms"]:
156+
ci_file.write_clean(
157+
self.actions.render(
158+
no_dev_versions=no_dev_versions,
159+
ci_platform=platform_ci_names[platform_name],
160+
ci_name=platform_name,
161+
python_versions=set_gh_actions_versions(self.get_macos_ci_versions()),
162+
dependency_lines=self.get_macos_ci_requirements(),
163+
)
164+
)
165+
elif ci_file.is_file():
166+
ci_file.unlink()
167+
168+
return ci_file
169+
170+
def make_linux(self) -> PathPlus:
171+
"""
172+
Create, update or remove the Linux action, as appropriate.
173+
"""
174+
175+
platform_name = "Linux"
176+
ci_file = self.workflows_dir / f"python_ci_{platform_name.lower()}.yml"
177+
178+
if platform_name in self.templates.globals["platforms"]:
179+
ci_file.write_clean(
180+
self.actions.render(
181+
no_dev_versions=no_dev_versions,
182+
python_versions=set_gh_actions_versions(self.get_linux_ci_versions()),
183+
ci_platform=platform_ci_names[platform_name],
184+
ci_name=platform_name,
185+
dependency_lines=self.get_linux_ci_requirements(),
186+
)
187+
)
188+
elif ci_file.is_file():
189+
ci_file.unlink()
190+
191+
return ci_file
192+
193+
def get_windows_ci_versions(self) -> List[str]:
194+
"""
195+
Returns the Python versions to run tests for on Windows.
196+
"""
197+
198+
py_versions: List[str] = self.templates.globals["python_versions"][:]
199+
200+
if not self.templates.globals["pure_python"] and "3.8" in py_versions:
201+
py_versions.remove("3.8") # FIXME: Python 3.8 tests fail on Windows for native wheels.
202+
if "pypy3" in py_versions:
203+
# FIXME: PyPy3 tests fail on Windows.
204+
# https://github.com/domdfcoding/flake8-sphinx-links/runs/1276871725?check_suite_focus=true
205+
py_versions.remove("pypy3")
206+
207+
return py_versions
208+
209+
def get_linux_ci_versions(self) -> List[str]:
210+
"""
211+
Returns the Python versions to run tests for on Linux.
212+
"""
213+
214+
return self.templates.globals["python_versions"]
215+
216+
def get_macos_ci_versions(self) -> List[str]:
217+
"""
218+
Returns the Python versions to run tests for on macOS.
219+
"""
220+
221+
return self.templates.globals["python_versions"]
105222

106223
standard_python_install_lines = [
107224
"python -VV",
108225
"python -m site",
109226
"python -m pip install --upgrade pip setuptools wheel",
110-
# "python -m pip install --upgrade tox tox-gh-actions virtualenv",
111227
"python -m pip install --upgrade tox virtualenv",
112228
]
113229

114-
if "Windows" in templates.globals["platforms"]:
115-
py_versions: List[str] = templates.globals["python_versions"][:]
116-
if not templates.globals["pure_python"] and "3.8" in py_versions:
117-
py_versions.remove("3.8") # FIXME: Python 3.8 tests fail on Windows for native wheels.
118-
if "pypy3" in py_versions:
119-
# FIXME: PyPy3 tests fail on Windows.
120-
# https://github.com/domdfcoding/flake8-sphinx-links/runs/1276871725?check_suite_focus=true
121-
py_versions.remove("pypy3")
230+
def _get_additional_requirements(self) -> Iterator[str]:
231+
if self.templates.globals["travis_additional_requirements"]:
232+
additional_requirements = DelimitedList(self.templates.globals["travis_additional_requirements"])
233+
yield f"python -m pip install --upgrade {additional_requirements: }"
122234

123-
dependency_lines = StringList(standard_python_install_lines)
124-
if templates.globals["travis_additional_requirements"]:
125-
travis_additional_requirements = DelimitedList(templates.globals["travis_additional_requirements"])
126-
dependency_lines.append(f"python -m pip install --upgrade {travis_additional_requirements: }")
127-
128-
windows_ci_file.write_clean(
129-
actions.render(
130-
no_dev_versions=no_dev_versions,
131-
ci_platform="windows-2019",
132-
ci_name="Windows",
133-
python_versions=set_gh_actions_versions(py_versions),
134-
dependency_lines=dependency_lines,
135-
)
136-
)
137-
elif windows_ci_file.is_file():
138-
windows_ci_file.unlink()
139-
140-
if "macOS" in templates.globals["platforms"]:
141-
142-
dependency_lines = StringList(standard_python_install_lines)
143-
if templates.globals["travis_additional_requirements"]:
144-
travis_additional_requirements = DelimitedList(templates.globals["travis_additional_requirements"])
145-
dependency_lines.append(f"python -m pip install --upgrade {travis_additional_requirements: }")
146-
147-
macos_ci_file.write_clean(
148-
actions.render(
149-
no_dev_versions=no_dev_versions,
150-
ci_platform="macos-latest",
151-
ci_name="macOS",
152-
python_versions=set_gh_actions_versions(templates.globals["python_versions"]),
153-
dependency_lines=dependency_lines,
154-
)
155-
)
156-
elif macos_ci_file.is_file():
157-
macos_ci_file.unlink()
235+
def get_windows_ci_requirements(self) -> List[str]:
236+
"""
237+
Returns the Python requirements to run tests for on Windows.
238+
"""
239+
240+
dependency_lines = StringList(self.standard_python_install_lines)
241+
dependency_lines.extend(self._get_additional_requirements())
242+
243+
return dependency_lines
158244

159-
if "Linux" in templates.globals["platforms"]:
160-
dependency_lines = StringList(templates.globals["travis_extra_install_pre"])
161-
dependency_lines.extend(standard_python_install_lines)
245+
def get_linux_ci_requirements(self) -> List[str]:
246+
"""
247+
Returns the Python requirements to run tests for on Linux.
248+
"""
162249

163-
if templates.globals["enable_tests"]:
250+
dependency_lines = StringList(self.templates.globals["travis_extra_install_pre"])
251+
dependency_lines.extend(self.standard_python_install_lines)
252+
253+
if self.templates.globals["enable_tests"]:
164254
dependency_lines.append("python -m pip install --upgrade coverage_pyver_pragma")
165255

166-
if templates.globals["travis_additional_requirements"]:
167-
travis_additional_requirements = DelimitedList(templates.globals["travis_additional_requirements"])
168-
dependency_lines.append(f"python -m pip install --upgrade {travis_additional_requirements: }")
256+
dependency_lines.extend(self._get_additional_requirements())
257+
dependency_lines.extend(self.templates.globals["travis_extra_install_post"])
169258

170-
dependency_lines.extend(templates.globals["travis_extra_install_post"])
259+
return dependency_lines
171260

172-
linux_ci_file.write_clean(
173-
actions.render(
174-
no_dev_versions=no_dev_versions,
175-
python_versions=set_gh_actions_versions(templates.globals["python_versions"]),
176-
ci_platform="ubuntu-20.04",
177-
ci_name="Linux",
178-
dependency_lines=dependency_lines,
179-
)
180-
)
181-
elif linux_ci_file.is_file():
182-
linux_ci_file.unlink()
261+
def get_macos_ci_requirements(self) -> List[str]:
262+
"""
263+
Returns the Python requirements to run tests for on macOS.
264+
"""
183265

184-
return [
185-
windows_ci_file.relative_to(repo_path).as_posix(),
186-
macos_ci_file.relative_to(repo_path).as_posix(),
187-
linux_ci_file.relative_to(repo_path).as_posix(),
188-
]
266+
return self.get_windows_ci_requirements()
267+
268+
269+
platform_ci_names = {
270+
"Windows": "windows-2019",
271+
"macOS": "macos-latest",
272+
"Linux": "ubuntu-20.04",
273+
}
274+
"""
275+
Mapping of platform names to the GitHub Actions platform tags.
276+
277+
.. versionadded:: 2020.12.18
278+
"""
189279

190280

191281
@management.register("conda_actions", ["enable_conda"])

0 commit comments

Comments
 (0)