|
25 | 25 |
|
26 | 26 | # stdlib |
27 | 27 | import pathlib |
28 | | -from typing import List |
| 28 | +from typing import Iterator, List |
29 | 29 |
|
30 | 30 | # 3rd party |
31 | 31 | import jinja2 |
|
47 | 47 | "ensure_bumpversion", |
48 | 48 | "make_actions_deploy_conda", |
49 | 49 | "make_conda_actions_ci", |
| 50 | + "ActionsManager", |
50 | 51 | ] |
51 | 52 |
|
52 | 53 |
|
@@ -92,100 +93,189 @@ def make_github_ci(repo_path: pathlib.Path, templates: jinja2.Environment) -> Li |
92 | 93 |
|
93 | 94 | # Matrix of OSs: https://youtu.be/KKJL8bM4cis?t=536 |
94 | 95 |
|
95 | | - # TODO: Allowed failure for -dev versions |
| 96 | + manager = ActionsManager(repo_path, templates) |
96 | 97 |
|
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 | + ] |
98 | 103 |
|
99 | | - workflows_dir = PathPlus(repo_path / ".github" / "workflows") |
100 | | - workflows_dir.maybe_make(parents=True) |
101 | 104 |
|
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"] |
105 | 222 |
|
106 | 223 | standard_python_install_lines = [ |
107 | 224 | "python -VV", |
108 | 225 | "python -m site", |
109 | 226 | "python -m pip install --upgrade pip setuptools wheel", |
110 | | - # "python -m pip install --upgrade tox tox-gh-actions virtualenv", |
111 | 227 | "python -m pip install --upgrade tox virtualenv", |
112 | 228 | ] |
113 | 229 |
|
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: }" |
122 | 234 |
|
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 |
158 | 244 |
|
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 | + """ |
162 | 249 |
|
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"]: |
164 | 254 | dependency_lines.append("python -m pip install --upgrade coverage_pyver_pragma") |
165 | 255 |
|
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"]) |
169 | 258 |
|
170 | | - dependency_lines.extend(templates.globals["travis_extra_install_post"]) |
| 259 | + return dependency_lines |
171 | 260 |
|
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 | + """ |
183 | 265 |
|
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 | +""" |
189 | 279 |
|
190 | 280 |
|
191 | 281 | @management.register("conda_actions", ["enable_conda"]) |
|
0 commit comments