|
2 | 2 |
|
3 | 3 | import os
|
4 | 4 | import shlex
|
| 5 | +import shutil |
5 | 6 | from argparse import ArgumentParser, BooleanOptionalAction
|
6 | 7 | from glob import iglob
|
7 | 8 | from pathlib import Path
|
@@ -44,6 +45,29 @@ def install(session: nox.Session, *args, req: str, **kwargs):
|
44 | 45 | session.install("-r", f"tests/{req}.in", *args, **kwargs)
|
45 | 46 |
|
46 | 47 |
|
| 48 | +CONTAINER_ENGINES = ("podman", "docker") |
| 49 | +CHOSEN_CONTAINER_ENGINE = os.environ.get("CONTAINER_ENGINE") |
| 50 | +ACTIONLINT_IMAGE = "docker.io/rhysd/actionlint" |
| 51 | + |
| 52 | + |
| 53 | +def _get_container_engine(session: nox.Session) -> str: |
| 54 | + path: str | None = None |
| 55 | + if CHOSEN_CONTAINER_ENGINE: |
| 56 | + path = shutil.which(CHOSEN_CONTAINER_ENGINE) |
| 57 | + if not path: |
| 58 | + session.error( |
| 59 | + f"CONTAINER_ENGINE {CHOSEN_CONTAINER_ENGINE!r} does not exist!" |
| 60 | + ) |
| 61 | + return path |
| 62 | + for engine in CONTAINER_ENGINES: |
| 63 | + if path := shutil.which(engine): |
| 64 | + return path |
| 65 | + session.error( |
| 66 | + f"None of the following container engines were found: {CONTAINER_ENGINES}." |
| 67 | + f" {session.name} requires a container engine installed." |
| 68 | + ) |
| 69 | + |
| 70 | + |
47 | 71 | @nox.session
|
48 | 72 | def static(session: nox.Session):
|
49 | 73 | """
|
@@ -92,12 +116,35 @@ def spelling(session: nox.Session):
|
92 | 116 | )
|
93 | 117 |
|
94 | 118 |
|
| 119 | +@nox.session |
| 120 | +def actionlint(session: nox.Session) -> None: |
| 121 | + """ |
| 122 | + Run actionlint to lint Github Actions workflows. |
| 123 | + The actionlint tool is run in a Podman/Docker container. |
| 124 | + """ |
| 125 | + engine = _get_container_engine(session) |
| 126 | + session.run_always(engine, "pull", ACTIONLINT_IMAGE, external=True) |
| 127 | + session.run( |
| 128 | + engine, |
| 129 | + "run", |
| 130 | + "--rm", |
| 131 | + # fmt: off |
| 132 | + "--volume", f"{Path.cwd()}:/pwd:z", |
| 133 | + "--workdir", "/pwd", |
| 134 | + # fmt: on |
| 135 | + ACTIONLINT_IMAGE, |
| 136 | + *session.posargs, |
| 137 | + external=True, |
| 138 | + ) |
| 139 | + |
| 140 | + |
95 | 141 | @nox.session
|
96 | 142 | def lint(session: nox.Session):
|
97 | 143 | session.notify("typing")
|
98 | 144 | session.notify("static")
|
99 | 145 | session.notify("formatters")
|
100 | 146 | session.notify("spelling")
|
| 147 | + session.notify("actionlint") |
101 | 148 |
|
102 | 149 |
|
103 | 150 | requirements_files = list(
|
|
0 commit comments