From 6d581544fa06a6e6c70dd5529095eab9de005388 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Mon, 12 Aug 2024 11:38:18 +0100 Subject: [PATCH] Allow return of multiple step commands (#36) --- README.md | 39 ++++++++++++++++++++++++++++++++++++--- entrypoint.py | 31 ++++++++++++++++++------------- 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 39bbad0..cbad4c5 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ jobs: steps: - name: Determine matrix id: generate_matrix - uses: coactions/dynamic-matrix@v1 + uses: coactions/dynamic-matrix@v3 with: other_names: | lint @@ -87,7 +87,7 @@ If your tox [envlist](https://tox.wiki/en/latest/config.html#envlist) is simple, ### Why this action does not just load envlist values? We plan to add support for this in the future but it might not be -as simple as one would assume. For historical reasons `envlist` do very often already include python versions instead of generic `py` entry or +as simple as one would assume. For historical reasons, `envlist` does very often already include Python versions instead of generic `py` entry or they are outdated. The repository code is not available at the time this action runs. @@ -97,7 +97,7 @@ Linux runners are the fastest ones and many Python projects do not need to suppo ### Why Windows and MacOS matrix expansion strategy is different than the Linux one? -The defaults for macOS and Windows are `minmax` while for Linux is `full`. This limits resource usage while still providing a good level of testing. If your pythons are `py38,py39,py310,py311` unless you specify `windows: full` you will see only two Windows based jobs in the generated matrix: py38 and py311. +The defaults for macOS and Windows are `minmax` while for Linux is `full`. This limit resource usage low while still providing a good level of testing. If your pythons are `py38,py39,py310,py311` unless you specify `windows: full` you will see only two Windows based jobs in the generated matrix: py38 and py311. ### Why is other_names a multiline string instead of being a comma-separated one? @@ -106,6 +106,39 @@ splitting on it. ### How to use custom test commands for some jobs. +In v3 we allow users to add entries like `py39-all:tox -f py39` inside `other-names`. This would be translated into returning the job name `py39-all` and the command `tox -f py39`. + +This is especially useful as it allows users to make use of labels (`-m`) and factor filtering (`-f`) to select groups of tox environments instead of just using the environments (`-e`) selector. + +This allows running other test frameworks instead of tox. + +### Generating multiple test commands for the same job + +In some cases, you might want to have separate test steps inside the same +job, as this makes it easier to debug them. As GHA does not have any support +for step looping, you are forced to manually add several steps if you want +to use this feature. + +Use `;` as a separator inside the other_names to achieve this: + +```yaml +# Return two commands instead of one for `all-tests` job +uses: coactions/dynamic-matrix@v3 +with: + other_names: | + all-tests:tox -e unit;tox -e integration + # ^ job-name ':' 1st command ';' 2nd command ... +--- +# Inside matrix job: +steps: + - run: "${{ matrix.command }}" + # Execute second command *if* it does exist + - run: "${{ matrix.command2 }}" + if: "${{ matrix.command2 || false }}" +``` + +### How to use custom test commands for some jobs. + In v3 we allow users to add entries like `py39-all:tox -f py39` inside `other-names`. This would translated into returning the job name `py39-all` and the command `tox -f py39`. This is especially useful as it allows users to make use of labels (`-m`) and factor filtering (`-f`) to select groups of tox environments instead of just using the environments (`-e`) selector. diff --git a/entrypoint.py b/entrypoint.py index 0e1a442..8931e8e 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -62,25 +62,26 @@ def main() -> None: # noqa: C901,PLR0912 python_flavours = len(python_names) core.debug("...") for line in other_names: - if ":" in line: - name, command = line.split(":", 1) - else: - name = line - command = f"tox -e {name}" + name, _ = line.split(":", 1) if ":" in line else (line, f"tox -e {line}") + commands = _.split(";") env_python = default_python # Check for using correct python version for other_names like py310-devel. match = re.search(r"py(\d+)", name) if match: py_version = match.groups()[0] env_python = f"{py_version[0]}.{py_version[1:]}" + data = { + "name": name, + "command": commands[0], + "python_version": PYTHON_REDIRECTS.get(env_python, env_python), + "os": PLATFORM_MAP["linux"], + } + for index, command in enumerate(commands[1:]): + data[f"command{index+2}"] = command add_job( result, name, - { - "command": command, - "python_version": PYTHON_REDIRECTS.get(env_python, env_python), - "os": PLATFORM_MAP["linux"], - }, + data, ) if not skip_explode: @@ -106,9 +107,13 @@ def main() -> None: # noqa: C901,PLR0912 core.info(f"Generated {len(result)} matrix entries.") names = sorted(result.keys()) core.info(f"Job names: {', '.join(names)}") - core.info(f"matrix: {json.dumps(result, indent=2)}") matrix_include = [] - matrix_include = [dict(result[name], name=name) for name in names] + matrix_include = [ + dict(sorted(dict(result[name], name=name).items())) for name in names + ] + core.info( + f"Matrix jobs ordered by their name: {json.dumps(matrix_include, indent=2)}", + ) core.set_output("matrix", {"include": matrix_include}) @@ -126,7 +131,7 @@ def main() -> None: # noqa: C901,PLR0912 os.environ["INPUT_MAX_PYTHON"] = "3.13" os.environ["INPUT_MIN_PYTHON"] = "3.8" os.environ["INPUT_OTHER_NAMES"] = ( - "lint\npkg\npy313-devel\npy39-factor:tox -f py39" + "lint\npkg\npy313-devel\nall:tox -e unit;tox -e integration" ) os.environ["INPUT_PLATFORMS"] = "linux,macos" # macos and windows os.environ["INPUT_SKIP_EXPLODE"] = "0"