From e71e5ee302a7336d5fbce74bb17d7d866a2a859f Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 4 Nov 2022 22:53:47 +0100 Subject: [PATCH] Documented python_jobs and artifact_names. Fixed JSON format. --- .github/workflows/Parameters.yml | 117 +++++++++++---------- .github/workflows/_Checking_Parameters.yml | 36 +++---- doc/JobTemplate/Parameters.rst | 67 +++++++++++- 3 files changed, 141 insertions(+), 79 deletions(-) diff --git a/.github/workflows/Parameters.yml b/.github/workflows/Parameters.yml index 48b7025..57e5bce 100644 --- a/.github/workflows/Parameters.yml +++ b/.github/workflows/Parameters.yml @@ -83,6 +83,7 @@ jobs: id: params shell: python run: | + from json import dumps as json_dumps from os import getenv from pathlib import Path from pprint import pprint @@ -109,13 +110,13 @@ jobs: # Deprecated structure params = { - 'python_version': python_version, - 'artifacts': { - 'unittesting': f"{artifact_names['unittesting']}", - 'coverage': f"{artifact_names['codecoverage']}", - 'typing': f"{artifact_names['statictyping']}", - 'package': f"{artifact_names['package']}", - 'doc': f"{artifact_names['documentation']}", + "python_version": python_version, + "artifacts": { + "unittesting": f"{artifact_names['unittesting']}", + "coverage": f"{artifact_names['codecoverage']}", + "typing": f"{artifact_names['statictyping']}", + "package": f"{artifact_names['package']}", + "doc": f"{artifact_names['documentation']}", } } @@ -154,32 +155,32 @@ jobs: data = { # Python and PyPy versions supported by "setup-python" action - 'python': { - '3.6': { 'icon': '⚫', 'until': '2021.12.23' }, - '3.7': { 'icon': '🔴', 'until': '2023.06.27' }, - '3.8': { 'icon': '🟠', 'until': '2024.10' }, - '3.9': { 'icon': '🟡', 'until': '2025.10' }, - '3.10': { 'icon': '🟢', 'until': '2026.10' }, - '3.11': { 'icon': '🟢', 'until': '2027.10' }, - '3.12': { 'icon': '🟣', 'until': '2028.10' }, - 'pypy-3.7': { 'icon': '⟲🔴', 'until': '????.??' }, - 'pypy-3.8': { 'icon': '⟲🟠', 'until': '????.??' }, - 'pypy-3.9': { 'icon': '⟲🟡', 'until': '????.??' }, + "python": { + "3.6": { "icon": "⚫", "until": "2021.12.23" }, + "3.7": { "icon": "🔴", "until": "2023.06.27" }, + "3.8": { "icon": "🟠", "until": "2024.10" }, + "3.9": { "icon": "🟡", "until": "2025.10" }, + "3.10": { "icon": "🟢", "until": "2026.10" }, + "3.11": { "icon": "🟢", "until": "2027.10" }, + "3.12": { "icon": "🟣", "until": "2028.10" }, + "pypy-3.7": { "icon": "⟲🔴", "until": "????.??" }, + "pypy-3.8": { "icon": "⟲🟠", "until": "????.??" }, + "pypy-3.9": { "icon": "⟲🟡", "until": "????.??" }, }, # Runner systems (runner images) supported by GitHub Actions - 'sys': { - 'ubuntu': { 'icon': '🐧', 'runs-on': 'ubuntu-latest', 'shell': 'bash', 'name': "Linux (x86-64)" }, - 'windows': { 'icon': '🧊', 'runs-on': 'windows-latest', 'shell': 'pwsh', 'name': "Windows (x86-64)" }, - 'macos': { 'icon': '🍎', 'runs-on': 'macos-latest', 'shell': 'bash', 'name': "MacOS (x86-64)" }, + "sys": { + "ubuntu": { "icon": "🐧", "runs-on": "ubuntu-latest", "shell": "bash", "name": "Linux (x86-64)" }, + "windows": { "icon": "🧊", "runs-on": "windows-latest", "shell": "pwsh", "name": "Windows (x86-64)" }, + "macos": { "icon": "🍎", "runs-on": "macos-latest", "shell": "bash", "name": "MacOS (x86-64)" }, }, # Runtimes provided by MSYS2 - 'runtime': { - 'msys': { 'icon': '🟪', 'name': 'Windows+MSYS2 (x86-64) - MSYS' }, - 'mingw32': { 'icon': '⬛', 'name': 'Windows+MSYS2 (x86-64) - MinGW32' }, - 'mingw64': { 'icon': '🟦', 'name': 'Windows+MSYS2 (x86-64) - MinGW64' }, - 'clang32': { 'icon': '🟫', 'name': 'Windows+MSYS2 (x86-64) - Clang32' }, - 'clang64': { 'icon': '🟧', 'name': 'Windows+MSYS2 (x86-64) - Clang64' }, - 'ucrt64': { 'icon': '🟨', 'name': 'Windows+MSYS2 (x86-64) - UCRT64' }, + "runtime": { + "msys": { "icon": "🟪", "name": "Windows+MSYS2 (x86-64) - MSYS" }, + "mingw32": { "icon": "⬛", "name": "Windows+MSYS2 (x86-64) - MinGW32" }, + "mingw64": { "icon": "🟦", "name": "Windows+MSYS2 (x86-64) - MinGW64" }, + "clang32": { "icon": "🟫", "name": "Windows+MSYS2 (x86-64) - Clang32" }, + "clang64": { "icon": "🟧", "name": "Windows+MSYS2 (x86-64) - Clang64" }, + "ucrt64": { "icon": "🟨", "name": "Windows+MSYS2 (x86-64) - UCRT64" }, } } @@ -193,20 +194,20 @@ jobs: combinations = [ (system, version) for system in systems - if system in data['sys'] + if system in data["sys"] for version in versions - if version in data['python'] + if version in data["python"] and f"{system}:{version}" not in excludes ] + [ (system, currentMSYS2Version) for system in systems - if system in data['runtime'] + if system in data["runtime"] and f"{system}:{currentMSYS2Version}" not in excludes ] + [ (system, version) for system, version in includes - if system in data['sys'] - and version in data['python'] + if system in data["sys"] + and version in data["python"] ] print(f"Combinations ({len(combinations)}):") for system, version in combinations: @@ -214,27 +215,27 @@ jobs: jobs = [ { - 'sysicon': data['sys'][system]['icon'], - 'system': system, - 'runs-on': data['sys'][system]['runs-on'], - 'shell': data['sys'][system]['shell'], - 'pyicon': data['python'][version]['icon'], - 'python': currentAlphaRelease if version == currentAlphaVersion else version, - 'envname': data['sys'][system]['name'], + "sysicon": data["sys"][system]["icon"], + "system": system, + "runs-on": data["sys"][system]["runs-on"], + "shell": data["sys"][system]["shell"], + "pyicon": data["python"][version]["icon"], + "python": currentAlphaRelease if version == currentAlphaVersion else version, + "envname": data["sys"][system]["name"], } - for system, version in combinations if system in data['sys'] + for system, version in combinations if system in data["sys"] ] + [ { - 'sysicon': data['runtime'][runtime]['icon'], - 'system': "msys2", - 'runs-on': "windows-latest", - 'runtime': runtime.upper(), - 'shell': "msys2 {0}", - 'pyicon': data['python'][currentMSYS2Version]['icon'], - 'python': version, - 'envname': data['runtime'][runtime]['name'], + "sysicon": data["runtime"][runtime]["icon"], + "system": "msys2", + "runs-on": "windows-latest", + "runtime": runtime.upper(), + "shell": "msys2 {0}", + "pyicon": data["python"][currentMSYS2Version]["icon"], + "python": version, + "envname": data["runtime"][runtime]["name"], } - for runtime, version in combinations if runtime not in data['sys'] + for runtime, version in combinations if runtime not in data["sys"] ] # Format jobs as list of dictionaries @@ -253,14 +254,14 @@ jobs: print(f"GITHUB_OUTPUT: {github_output}") with github_output.open("a+") as f: f.write(f"python_version={python_version}\n") - f.write(f"python_jobs={jobs!s}\n") - f.write(f"artifact_names={artifact_names!s}\n") - f.write(f"params={params!s}\n") + f.write(f"python_jobs={json_dumps(jobs)}\n") + f.write(f"artifact_names={json_dumps(artifact_names)}\n") + f.write(f"params={json_dumps(params)}\n") - name: Verify out parameters id: verify run: | - echo "python_version: ${{ steps.params.outputs.python_version }}" - echo "python_jobs: ${{ steps.params.outputs.python_jobs }}" - echo "artifact_names: ${{ steps.params.outputs.artifact_names }}" - echo "params: ${{ steps.params.outputs.params }}" + echo 'python_version: ${{ steps.params.outputs.python_version }}' + echo 'python_jobs: ${{ steps.params.outputs.python_jobs }}' + echo 'artifact_names: ${{ steps.params.outputs.artifact_names }}' + echo 'params: ${{ steps.params.outputs.params }}' diff --git a/.github/workflows/_Checking_Parameters.yml b/.github/workflows/_Checking_Parameters.yml index e9555b7..538a212 100644 --- a/.github/workflows/_Checking_Parameters.yml +++ b/.github/workflows/_Checking_Parameters.yml @@ -79,9 +79,9 @@ jobs: "documentation": f"{expectedName}-Documentation" } - actualPythonVersion = "${{ needs.Params_Default.outputs.python_version }}" - actualPythonJobs = json_loads("${{ needs.Params_Default.outputs.python_jobs }}".replace("'", '"')) - actualArtifactNames = json_loads("${{ needs.Params_Default.outputs.artifact_names }}".replace("'", '"')) + actualPythonVersion = """${{ needs.Params_Default.outputs.python_version }}""" + actualPythonJobs = json_loads("""${{ needs.Params_Default.outputs.python_jobs }}""".replace("'", '"')) + actualArtifactNames = json_loads("""${{ needs.Params_Default.outputs.artifact_names }}""".replace("'", '"')) errors = 0 if actualPythonVersion != expectedPythonVersion: @@ -121,9 +121,9 @@ jobs: "documentation": f"{expectedName}-Documentation" } - actualPythonVersion = "${{ needs.Params_PythonVersions.outputs.python_version }}" - actualPythonJobs = json_loads("${{ needs.Params_PythonVersions.outputs.python_jobs }}".replace("'", '"')) - actualArtifactNames = json_loads("${{ needs.Params_PythonVersions.outputs.artifact_names }}".replace("'", '"')) + actualPythonVersion = """${{ needs.Params_PythonVersions.outputs.python_version }}""" + actualPythonJobs = json_loads("""${{ needs.Params_PythonVersions.outputs.python_jobs }}""".replace("'", '"')) + actualArtifactNames = json_loads("""${{ needs.Params_PythonVersions.outputs.artifact_names }}""".replace("'", '"')) errors = 0 if actualPythonVersion != expectedPythonVersion: @@ -163,9 +163,9 @@ jobs: "documentation": f"{expectedName}-Documentation" } - actualPythonVersion = "${{ needs.Params_Systems.outputs.python_version }}" - actualPythonJobs = json_loads("${{ needs.Params_Systems.outputs.python_jobs }}".replace("'", '"')) - actualArtifactNames = json_loads("${{ needs.Params_Systems.outputs.artifact_names }}".replace("'", '"')) + actualPythonVersion = """${{ needs.Params_Systems.outputs.python_version }}""" + actualPythonJobs = json_loads("""${{ needs.Params_Systems.outputs.python_jobs }}""".replace("'", '"')) + actualArtifactNames = json_loads("""${{ needs.Params_Systems.outputs.artifact_names }}""".replace("'", '"')) errors = 0 if actualPythonVersion != expectedPythonVersion: @@ -205,9 +205,9 @@ jobs: "documentation": f"{expectedName}-Documentation" } - actualPythonVersion = "${{ needs.Params_Include.outputs.python_version }}" - actualPythonJobs = json_loads("${{ needs.Params_Include.outputs.python_jobs }}".replace("'", '"')) - actualArtifactNames = json_loads("${{ needs.Params_Include.outputs.artifact_names }}".replace("'", '"')) + actualPythonVersion = """${{ needs.Params_Include.outputs.python_version }}""" + actualPythonJobs = json_loads("""${{ needs.Params_Include.outputs.python_jobs }}""".replace("'", '"')) + actualArtifactNames = json_loads("""${{ needs.Params_Include.outputs.artifact_names }}""".replace("'", '"')) errors = 0 if actualPythonVersion != expectedPythonVersion: @@ -247,9 +247,9 @@ jobs: "documentation": f"{expectedName}-Documentation" } - actualPythonVersion = "${{ needs.Params_Exclude.outputs.python_version }}" - actualPythonJobs = json_loads("${{ needs.Params_Exclude.outputs.python_jobs }}".replace("'", '"')) - actualArtifactNames = json_loads("${{ needs.Params_Exclude.outputs.artifact_names }}".replace("'", '"')) + actualPythonVersion = """${{ needs.Params_Exclude.outputs.python_version }}""" + actualPythonJobs = json_loads("""${{ needs.Params_Exclude.outputs.python_jobs }}""".replace("'", '"')) + actualArtifactNames = json_loads("""${{ needs.Params_Exclude.outputs.artifact_names }}""".replace("'", '"')) errors = 0 if actualPythonVersion != expectedPythonVersion: @@ -289,9 +289,9 @@ jobs: "documentation": f"{expectedName}-Documentation" } - actualPythonVersion = "${{ needs.Params_All.outputs.python_version }}" - actualPythonJobs = json_loads("${{ needs.Params_All.outputs.python_jobs }}".replace("'", '"')) - actualArtifactNames = json_loads("${{ needs.Params_All.outputs.artifact_names }}".replace("'", '"')) + actualPythonVersion = """${{ needs.Params_All.outputs.python_version }}""" + actualPythonJobs = json_loads("""${{ needs.Params_All.outputs.python_jobs }}""".replace("'", '"')) + actualArtifactNames = json_loads("""${{ needs.Params_All.outputs.artifact_names }}""".replace("'", '"')) errors = 0 if actualPythonVersion != expectedPythonVersion: diff --git a/doc/JobTemplate/Parameters.rst b/doc/JobTemplate/Parameters.rst index 85f84f7..c82275c 100644 --- a/doc/JobTemplate/Parameters.rst +++ b/doc/JobTemplate/Parameters.rst @@ -262,7 +262,7 @@ A single string parameter representing the default Python version that should be pipeline. Such a parameter is needed as a workaround, because GitHub Actions doesn't support proper handling of global pipeline -variables. Thus, this job is used to compute an output parameter that can be reused in many other jobs. +variables. Thus, this job is used to compute an output parameter that can be reused in other jobs. **Usage Example:** @@ -284,12 +284,73 @@ variables. Thus, this job is used to compute an output parameter that can be reu python_jobs =========== -.. todo:: Parameters:python_jobs Needs documentation. +A list of dictionaries containing a job description. + +A job description contains the following key-value pairs: + +* ``sysicon`` - icon to display +* ``system`` - name of the system +* ``runs-on`` - virtual machine image and base operating system +* ``runtime`` - name of the runtime environment if not running natively on the VM image +* ``shell`` - name of the shell +* ``pyicon`` - icon for CPython or pypy +* ``python`` - Python version +* ``envname`` - full name of the selected environment + +**Usage Example:** + +.. code-block:: yaml + + jobs: + Params: + uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0 + with: + name: pyTooling + + UnitTesting: + uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@dev + needs: + - Params + with: + jobs: ${{ needs.Params.outputs.python_jobs }} + +This list can be unpacked with ``fromJson(...)`` in a job ``strategy:matrix:include``: + +.. code-block:: yaml + + UnitTesting: + name: ${{ matrix.sysicon }} ${{ matrix.pyicon }} Unit Tests using Python ${{ matrix.python }} + runs-on: ${{ matrix.runs-on }} + + strategy: + matrix: + include: ${{ fromJson(inputs.jobs) }} + + defaults: + run: + shell: ${{ matrix.shell }} + + steps: + - name: 🐍 Setup Python ${{ matrix.python }} + if: matrix.system != 'msys2' + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + artifact_names ============== -.. todo:: Parameters:artifact_names Needs documentation. +A dictionary of artifact names sharing a common prefix. + +The supported artifacts are: + +* ``unittesting`` - UnitTesting XML summary report +* ``codecoverage`` - Code Coverage HTML report +* ``statictyping`` - Static Type Checking HTML report +* ``package`` - Packaged Python project +* ``documentation`` - Documentation in HTML format + Params ======