From 2944b0ebf888a039c6a0062e994c3828c4c63aee Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 11 Nov 2021 22:06:02 +0100 Subject: [PATCH 01/29] Add initial README --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1c8efb0 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# One (Reusable) Tox Workflow To Rule Them All + +This repository holds a centrally maintained test matrix for tox-based +projects. + +## Howto + +The example use is demonstrated below. You can start by provisioning a +file at the path `.github/workflows/ci-cd.yml` in your repository. + +```yaml +--- + +name: πŸ§ͺ + +on: + pull_request: + push: + schedule: + - cron: 1 0 * * * # Run daily at 0:01 UTC + +concurrency: + group: >- + ${{ + github.workflow + }}-${{ + github.event.pull_request.number || github.sha + }} + cancel-in-progress: true + +jobs: + tox-matrix: + name: >- # Short name for UI, or use πŸ§‘β€πŸ’», it's even shorter + [m] + # REPRODUCIBILITY NOTE: Replace the `main` version with a stable tag + uses: tox-dev/workflow/.github/workflows/tox.yml@main + with: # all of these inputs are absolutely optional + max-python: # Python maximum, formated as MAJOR.MINOR + min-python: # Python minimum, formated as MAJOR.MINOR + tox-target: # Regex to filter the detected tox envs + tox-version: # Tox PyPI package w/ version spec for pip + YOLO: true # Rely on the unstable version of the underlying GHA + +... +``` + +## Features + +The reusable workflow has a job called `check-tox` that waits for the +whole tox matrix. It can be used in the branch protection to avoid +having to list each of the dynamic check names. From 0adcd1f2f275103fef9bcb1423022d441cb3708b Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 11 Nov 2021 22:06:56 +0100 Subject: [PATCH 02/29] Add a license file --- LICENSE.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 LICENSE.rst diff --git a/LICENSE.rst b/LICENSE.rst new file mode 100644 index 0000000..3822b10 --- /dev/null +++ b/LICENSE.rst @@ -0,0 +1,22 @@ +The MIT License (MIT) +--------------------- +**Copyright Β© Sviatoslav Sydorenko** (`@webknjaz `_) + +=============================================================================== + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the β€œSoftware”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 6a4b7951d7921fafcd500bc7d2c8fa1aa67ea16a Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 11 Nov 2021 22:07:38 +0100 Subject: [PATCH 03/29] Add an initial reusable workflow --- .github/workflows/tox.yml | 284 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 .github/workflows/tox.yml diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml new file mode 100644 index 0000000..4d25976 --- /dev/null +++ b/.github/workflows/tox.yml @@ -0,0 +1,284 @@ +--- + +name: tox + +on: + workflow_call: + inputs: + target: + default: + description: Regex to filter the tox envs, required with 'run-env' + required: false + type: string + + min-python: + default: 'None' + description: Minimum supported Python version (quote as a string!) + required: false + type: string + max-python: + default: 'None' + description: Maximum supported Python version (quote as a string!) + required: false + type: string + + version: + default: tox + description: tox with version spec for pip + required: false + type: string + secrets: {} + +jobs: + make-tox-env-matrix: + name: >- + tox: discover envs + + outputs: + matrix: ${{ steps.tox.outputs.matrix }} + + runs-on: Ubuntu-latest + + steps: + - name: Install packaging tools + run: | + echo '::group::Preparing the outer Python env for tox' + python -m pip install --user -U wheel + python -m pip install --user -U pip-with-requires-python setuptools + python -m pip install --user -U virtualenv + echo '::endgroup::' + shell: bash + - name: Install tox + run: | + echo '::group::Installing tox: ${{ inputs.version }}' + python -m pip install --user -U '${{ inputs.version }}' + echo '::endgroup::' + shell: bash + + # NOTE: Check out the caller repository under $GITHUB_WORKSPACE, + # NOTE: so the job can access it. + - uses: actions/checkout@v2 + + - name: Generate the matrix + id: tox + run: | + from __future__ import print_function + + __metaclass__ = type + + + import json + import re + import subprocess + import sys + + + print('::group::Generating GHA environments based on tox config') + filter_pattern = '${{ matrix.toxenv }}' + + min_py_ver = ${{ inputs.min-python }} + max_py_ver = ${{ inputs.max-python }} + if min_py_ver is not None: + min_py_ver = tuple(map(int, str(min_py_ver).split('.'))) + else: + min_py_ver = 2, 7 + if max_py_ver is not None: + max_py_ver = tuple(map(int, str(max_py_ver).split('.'))) + else: + max_py_ver = 3, 10 + + def inc_minor_py_ver(ver): + if ver == (2, 7): + return 3, 5 + return ver[0], ver[1] + 1 + + def generate_py_vers(min_py, max_py): + cur_ver = min_py + while cur_ver <= max_py: + yield cur_ver + cur_ver = inc_minor_py_ver(cur_ver) + + tox_discovery_cmd = sys.executable, '-m', 'tox', '-a' + toxenvs = set(subprocess.check_output( + tox_discovery_cmd, + universal_newlines=True, + ).splitlines()) + if {'py', 'python'} & toxenvs: + toxenvs -= {'py', 'python'} + for py_ver in generate_py_vers(min_py_ver, max_py_ver): + toxenvs |= {'py{ver[0]}{ver[1]}'.format(ver=py_ver)} + + envs = [] + for toxenv in toxenvs: + if filter_pattern and not re.search(filter_pattern, toxenv): + print( + '`{env}` does not march `{pattern}`. Excluding it...'. + format(env=toxenv, pattern=filter_pattern), + ) + continue + + print('Adding `{env}` to the list'.format(env=toxenv)) + py_ver = ( + (toxenv[2], toxenv[3:]) if toxenv.startswith('py') + else max_py_ver + ) + envs.append({ + 'name': 'tox: {env}'.format(env=toxenv), + 'python-version': '.'.join(py_ver), + 'toxenv': toxenv, + }) + + matrix_json_string = json.dumps({'include': envs}) + print( + '::set-output name=matrix::{out_json}'. + format(out_json=matrix_json_string), + ) + print('::endgroup::') + shell: python + + - name: Log the discovered matrix + run: echo '${{ steps.tox.outputs.matrix }}' + + + run-tox: + name: ${{ matrix.name }} + + needs: + - make-tox-env-matrix + + runs-on: ubuntu-latest + + strategy: + matrix: ${{ fromJSON(needs.make-tox-env-matrix.outputs.matrix) }} + + steps: + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install packaging tools + run: | + echo '::group::Preparing the outer Python env for tox' + python -m pip install --user -U wheel + python -m pip install --user -U pip-with-requires-python setuptools + python -m pip install --user -U virtualenv + echo '::endgroup::' + shell: bash + - name: Install tox + run: | + echo '::group::Installing tox: ${{ inputs.version }}' + python -m pip install --user -U '${{ inputs.version }}' + echo '::endgroup::' + shell: bash + - uses: actions/checkout@v2 + - name: Prepare tox env '${{ matrix.toxenv }}' + run: > + echo '::group::Preparing tox environment' + + + python -m + tox + --parallel auto + --parallel-live + -vv + --notest + + + echo '::endgroup::' + shell: bash + env: + PY_COLORS: 1 + TOX_PARALLEL_NO_SPINNER: 1 + TOXENV: ${{ matrix.toxenv }} + - name: Run tox env '${{ matrix.toxenv }}' + id: tox-results + run: | + echo '::group::Executing tox environment commands' + + TMPDIR=$(mktemp -d --suffix=-results tox-XXXXX) + + JSON_RESULTS_FILE="${TMPDIR}/.tox-run-results.json" && \ + echo "::set-output name=results-file::${JSON_RESULTS_FILE}" + + python -m \ + tox \ + --parallel auto \ + --parallel-live \ + -vv \ + --result-json "${JSON_RESULTS_FILE}" + + echo '::endgroup::' + shell: bash + env: + PY_COLORS: 1 + TOX_PARALLEL_NO_SPINNER: 1 + TOXENV: ${{ matrix.toxenv }} + - uses: actions/setup-python@v2 + if: always() + with: + python-version: '3.10' + - name: t res + if: always() + run: python3.10 -m json.tool '${{ steps.tox-results.outputs.results-file }}' + - name: Log results + if: always() + id: json-results + run: | + import json + from shutil import rmtree + from pathlib import Path + from pprint import pprint + + print('::group::Saving json results...') + + results_file = Path('${{ steps.tox-results.outputs.results-file }}') + tox_results = json.loads(results_file.read_text()) + compact_tox_results = json.dumps(tox_results, indent=None) + + print(f'::set-output name=json-results::{compact_tox_results}') + + toxenv_data = tox_results['testenvs']['${{ matrix.toxenv }}'] + test_commands = toxenv_data['test'] + + for test_cmd in test_commands: + pprint(test_cmd) + + rc = test_cmd['retcode'] + if rc: + print( + '::error file=({rc}) $ {cmd}::{out}'. + format( + rc=rc, + cmd=' '.join(test_cmd['command']), + out=test_cmd['output'].replace('\n', '%0A'), + ) + ) + continue + + test_cmd_out = test_cmd['output'].replace('\n', '%0A') + print(f'::debug:({rc}) $ {" ".join(test_cmd["command"])}') + print(f'::debug:{test_cmd_out}') + + rmtree((results_file / '..').resolve()) + + print('::endgroup::') + shell: python + + - name: j res + if: always() + run: echo '${{ steps.json-results.outputs.json-results }}' | python3.10 -m json.tool + + check-tox: # This job does nothing and is only used for the branch protection + if: always() + + needs: + - run-tox + + runs-on: Ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + +... From 9ac80347da411236fcec6ad874fee0f7fabf53fb Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sun, 5 Dec 2021 03:31:34 +0100 Subject: [PATCH 04/29] debug! use gha --- .github/workflows/tox.yml | 241 ++++++-------------------------------- 1 file changed, 38 insertions(+), 203 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 4d25976..82801cc 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -5,9 +5,27 @@ name: tox on: workflow_call: inputs: + + check-job-name: + default: check-tox + description: >- + A custom job name to use in branch protection, + defaults to 'check-tox' + required: false + type: string + + tox-job-names-prefix: + default: >- + πŸ§ͺ tox: + description: >- + A custom tox matix job names prefix, + defaults to 'πŸ§ͺ tox:' + required: false + type: string + target: default: - description: Regex to filter the tox envs, required with 'run-env' + description: Regex to filter the tox envs required: false type: string @@ -27,121 +45,36 @@ on: description: tox with version spec for pip required: false type: string + secrets: {} jobs: + make-tox-env-matrix: name: >- - tox: discover envs + πŸ”Ž tox: discover envs outputs: - matrix: ${{ steps.tox.outputs.matrix }} + matrix: ${{ steps.discovered-tox.outputs.matrix }} runs-on: Ubuntu-latest steps: - - name: Install packaging tools - run: | - echo '::group::Preparing the outer Python env for tox' - python -m pip install --user -U wheel - python -m pip install --user -U pip-with-requires-python setuptools - python -m pip install --user -U virtualenv - echo '::endgroup::' - shell: bash - - name: Install tox - run: | - echo '::group::Installing tox: ${{ inputs.version }}' - python -m pip install --user -U '${{ inputs.version }}' - echo '::endgroup::' - shell: bash - # NOTE: Check out the caller repository under $GITHUB_WORKSPACE, # NOTE: so the job can access it. - uses: actions/checkout@v2 - - name: Generate the matrix - id: tox - run: | - from __future__ import print_function - - __metaclass__ = type - - - import json - import re - import subprocess - import sys - - - print('::group::Generating GHA environments based on tox config') - filter_pattern = '${{ matrix.toxenv }}' - - min_py_ver = ${{ inputs.min-python }} - max_py_ver = ${{ inputs.max-python }} - if min_py_ver is not None: - min_py_ver = tuple(map(int, str(min_py_ver).split('.'))) - else: - min_py_ver = 2, 7 - if max_py_ver is not None: - max_py_ver = tuple(map(int, str(max_py_ver).split('.'))) - else: - max_py_ver = 3, 10 - - def inc_minor_py_ver(ver): - if ver == (2, 7): - return 3, 5 - return ver[0], ver[1] + 1 - - def generate_py_vers(min_py, max_py): - cur_ver = min_py - while cur_ver <= max_py: - yield cur_ver - cur_ver = inc_minor_py_ver(cur_ver) - - tox_discovery_cmd = sys.executable, '-m', 'tox', '-a' - toxenvs = set(subprocess.check_output( - tox_discovery_cmd, - universal_newlines=True, - ).splitlines()) - if {'py', 'python'} & toxenvs: - toxenvs -= {'py', 'python'} - for py_ver in generate_py_vers(min_py_ver, max_py_ver): - toxenvs |= {'py{ver[0]}{ver[1]}'.format(ver=py_ver)} - - envs = [] - for toxenv in toxenvs: - if filter_pattern and not re.search(filter_pattern, toxenv): - print( - '`{env}` does not march `{pattern}`. Excluding it...'. - format(env=toxenv, pattern=filter_pattern), - ) - continue - - print('Adding `{env}` to the list'.format(env=toxenv)) - py_ver = ( - (toxenv[2], toxenv[3:]) if toxenv.startswith('py') - else max_py_ver - ) - envs.append({ - 'name': 'tox: {env}'.format(env=toxenv), - 'python-version': '.'.join(py_ver), - 'toxenv': toxenv, - }) - - matrix_json_string = json.dumps({'include': envs}) - print( - '::set-output name=matrix::{out_json}'. - format(out_json=matrix_json_string), - ) - print('::endgroup::') - shell: python + - uses: tox-dev/gh-action-tox/matrix@experiments/composite-action + id: discovered-tox - name: Log the discovered matrix - run: echo '${{ steps.tox.outputs.matrix }}' + run: echo '${{ steps.discovered-tox.outputs.matrix }}' run-tox: - name: ${{ matrix.name }} + name: >- + ${{ inputs.tox-job-names-prefix }} + ${{ matrix.toxenv }} needs: - make-tox-env-matrix @@ -152,124 +85,26 @@ jobs: matrix: ${{ fromJSON(needs.make-tox-env-matrix.outputs.matrix) }} steps: - - uses: actions/setup-python@v2 + - uses: tox-dev/gh-action-tox@experiments/composite-action with: python-version: ${{ matrix.python-version }} - - name: Install packaging tools - run: | - echo '::group::Preparing the outer Python env for tox' - python -m pip install --user -U wheel - python -m pip install --user -U pip-with-requires-python setuptools - python -m pip install --user -U virtualenv - echo '::endgroup::' - shell: bash - - name: Install tox - run: | - echo '::group::Installing tox: ${{ inputs.version }}' - python -m pip install --user -U '${{ inputs.version }}' - echo '::endgroup::' - shell: bash - - uses: actions/checkout@v2 - - name: Prepare tox env '${{ matrix.toxenv }}' - run: > - echo '::group::Preparing tox environment' - - - python -m - tox - --parallel auto - --parallel-live - -vv - --notest - - - echo '::endgroup::' - shell: bash - env: - PY_COLORS: 1 - TOX_PARALLEL_NO_SPINNER: 1 - TOXENV: ${{ matrix.toxenv }} - - name: Run tox env '${{ matrix.toxenv }}' - id: tox-results - run: | - echo '::group::Executing tox environment commands' - - TMPDIR=$(mktemp -d --suffix=-results tox-XXXXX) - - JSON_RESULTS_FILE="${TMPDIR}/.tox-run-results.json" && \ - echo "::set-output name=results-file::${JSON_RESULTS_FILE}" - - python -m \ - tox \ - --parallel auto \ - --parallel-live \ - -vv \ - --result-json "${JSON_RESULTS_FILE}" - - echo '::endgroup::' - shell: bash - env: - PY_COLORS: 1 - TOX_PARALLEL_NO_SPINNER: 1 - TOXENV: ${{ matrix.toxenv }} + target: ${{ matrix.toxenv }} + id: tox - uses: actions/setup-python@v2 if: always() with: - python-version: '3.10' - - name: t res - if: always() - run: python3.10 -m json.tool '${{ steps.tox-results.outputs.results-file }}' - - name: Log results - if: always() - id: json-results - run: | - import json - from shutil import rmtree - from pathlib import Path - from pprint import pprint - - print('::group::Saving json results...') - - results_file = Path('${{ steps.tox-results.outputs.results-file }}') - tox_results = json.loads(results_file.read_text()) - compact_tox_results = json.dumps(tox_results, indent=None) - - print(f'::set-output name=json-results::{compact_tox_results}') - - toxenv_data = tox_results['testenvs']['${{ matrix.toxenv }}'] - test_commands = toxenv_data['test'] - - for test_cmd in test_commands: - pprint(test_cmd) - - rc = test_cmd['retcode'] - if rc: - print( - '::error file=({rc}) $ {cmd}::{out}'. - format( - rc=rc, - cmd=' '.join(test_cmd['command']), - out=test_cmd['output'].replace('\n', '%0A'), - ) - ) - continue - - test_cmd_out = test_cmd['output'].replace('\n', '%0A') - print(f'::debug:({rc}) $ {" ".join(test_cmd["command"])}') - print(f'::debug:{test_cmd_out}') - - rmtree((results_file / '..').resolve()) - - print('::endgroup::') - shell: python - + python-version: >- + 3.10 - name: j res if: always() - run: echo '${{ steps.json-results.outputs.json-results }}' | python3.10 -m json.tool + run: echo '${{ steps.tox.outputs.json-results }}' | python3.10 -m json.tool + check-tox: # This job does nothing and is only used for the branch protection if: always() + name: ${{ inputs.check-job-name }} + needs: - run-tox From 609405d9326f340db77cef66806c46bb93091656 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sun, 5 Dec 2021 22:30:39 +0100 Subject: [PATCH 05/29] Add a checkbox emoji to the default check job --- .github/workflows/tox.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 82801cc..b22c557 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -7,7 +7,7 @@ on: inputs: check-job-name: - default: check-tox + default: βœ… check-tox description: >- A custom job name to use in branch protection, defaults to 'check-tox' diff --git a/README.md b/README.md index 1c8efb0..634f15f 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,6 @@ jobs: ## Features -The reusable workflow has a job called `check-tox` that waits for the +The reusable workflow has a job called `βœ… check-tox` that waits for the whole tox matrix. It can be used in the branch protection to avoid having to list each of the dynamic check names. From c12636d9a3412bf06aa330ebb1167782ceafcfed Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sun, 5 Dec 2021 22:33:53 +0100 Subject: [PATCH 06/29] Make tox action invocations named --- .github/workflows/tox.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index b22c557..d8540d3 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -64,7 +64,8 @@ jobs: # NOTE: so the job can access it. - uses: actions/checkout@v2 - - uses: tox-dev/gh-action-tox/matrix@experiments/composite-action + - name: πŸ”Ž Produce tox environment job matrix for GHA + uses: tox-dev/gh-action-tox/matrix@experiments/composite-action id: discovered-tox - name: Log the discovered matrix @@ -85,7 +86,9 @@ jobs: matrix: ${{ fromJSON(needs.make-tox-env-matrix.outputs.matrix) }} steps: - - uses: tox-dev/gh-action-tox@experiments/composite-action + - name: >- + πŸ§ͺ Run tox: ${{ matrix.toxenv }} + uses: tox-dev/gh-action-tox@experiments/composite-action with: python-version: ${{ matrix.python-version }} target: ${{ matrix.toxenv }} From a057936e06e84188e900e07c0e502f4927daa5ce Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 15 Dec 2021 19:39:50 +0100 Subject: [PATCH 07/29] Add a funding config --- .github/FUNDING.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..25bd04e --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,10 @@ +--- + +custom: +- https://webknjaz.me +- https://www.paypal.me/webknjazCZ + +github: +- webknjaz + +... From 18fb69fd08e6f3495028214aa9ef0f7b1c9d132f Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 16 Dec 2021 01:23:06 +0100 Subject: [PATCH 08/29] Implement `tox-env-matrix-hook` for user code --- .github/workflows/tox.yml | 41 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index d8540d3..39a37ee 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -46,6 +46,14 @@ on: required: false type: string + tox-env-matrix-hook: + default: + description: >- + A Python snippet that can be used to modify the + automatically generated job matrix + required: false + type: string + secrets: {} jobs: @@ -55,7 +63,12 @@ jobs: πŸ”Ž tox: discover envs outputs: - matrix: ${{ steps.discovered-tox.outputs.matrix }} + matrix: >- + ${{ + inputs.tox-env-matrix-hook + && steps.post-process-matrix-definition.outputs.matrix + || steps.discovered-tox.outputs.matrix + }} runs-on: Ubuntu-latest @@ -71,6 +84,32 @@ jobs: - name: Log the discovered matrix run: echo '${{ steps.discovered-tox.outputs.matrix }}' + - name: Select Python 3.10 + if: inputs.tox-env-matrix-hook + uses: actions/setup-python@v2 + with: + python-version: >- + 3.10 + + - name: Post-process the discovered matrix + id: post-process-matrix-definition + if: inputs.tox-env-matrix-hook + run: | + import json + computed_matrix = """${{ steps.discovered-tox.outputs.matrix }}""" + + gha_matrix = json.loads(computed_matrix) + + ${{ inputs.tox-env-matrix-hook }} + + final_gha_matrix_compact_str = json.dumps(gha_matrix, indent=None) + print(f'::set-output name=matrix::{final_gha_matrix_compact_str}') + shell: python + + - name: Log the potentially modified matrix + if: inputs.tox-env-matrix-hook + run: echo '${{ steps.post-process-matrix-definition.outputs.matrix }}' + run-tox: name: >- From b2737f916cb3c2cf9117e7a9a87d13f2af614cd4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Fri, 17 Dec 2021 14:17:29 +0100 Subject: [PATCH 09/29] Allow customizing the job names --- .github/workflows/tox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 39a37ee..5bf67cc 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -114,7 +114,7 @@ jobs: run-tox: name: >- ${{ inputs.tox-job-names-prefix }} - ${{ matrix.toxenv }} + ${{ matrix.custom-job-name && matrix.custom-job-name || matrix.toxenv }} needs: - make-tox-env-matrix From 75d67926b040245bfbf04078c0bd7edf859e02b4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sat, 18 Dec 2021 02:11:57 +0100 Subject: [PATCH 10/29] Get the OS from matrix --- .github/workflows/tox.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 5bf67cc..52057c9 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -114,12 +114,13 @@ jobs: run-tox: name: >- ${{ inputs.tox-job-names-prefix }} - ${{ matrix.custom-job-name && matrix.custom-job-name || matrix.toxenv }} + ${{ matrix.custom-job-name && matrix.custom-job-name || matrix.toxenv }} + ${{ matrix.runs-on && matrix.runs-on || 'Ubuntu-latest' }} needs: - make-tox-env-matrix - runs-on: ubuntu-latest + runs-on: ${{ matrix.runs-on && matrix.runs-on || 'Ubuntu-latest' }} strategy: matrix: ${{ fromJSON(needs.make-tox-env-matrix.outputs.matrix) }} From 1cad3b73faf148d21ea53769086b4190558851b4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sat, 18 Dec 2021 15:34:52 +0100 Subject: [PATCH 11/29] win10 compat for results output --- .github/workflows/tox.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 52057c9..abb7291 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -141,6 +141,7 @@ jobs: - name: j res if: always() run: echo '${{ steps.tox.outputs.json-results }}' | python3.10 -m json.tool + shell: bash # Windows compat check-tox: # This job does nothing and is only used for the branch protection From a07316df0a01f5857026c3d5f2cc4e72af705fdb Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 23 Dec 2021 00:54:44 +0100 Subject: [PATCH 12/29] Reuse set interpreter version --- .github/workflows/tox.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index abb7291..faf23bf 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -135,12 +135,16 @@ jobs: id: tox - uses: actions/setup-python@v2 if: always() + id: use-py310 with: python-version: >- 3.10 - name: j res if: always() - run: echo '${{ steps.tox.outputs.json-results }}' | python3.10 -m json.tool + run: >- + echo '${{ steps.tox.outputs.json-results }}' + | + ${{ steps.use-py310.outputs.python-version }} -m json.tool shell: bash # Windows compat From 09ee08f100a01f7cf0d9fba68b39f37370cc0905 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 23 Dec 2021 01:01:03 +0100 Subject: [PATCH 13/29] Revert "Reuse set interpreter version" This reverts commit a07316df0a01f5857026c3d5f2cc4e72af705fdb. --- .github/workflows/tox.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index faf23bf..abb7291 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -135,16 +135,12 @@ jobs: id: tox - uses: actions/setup-python@v2 if: always() - id: use-py310 with: python-version: >- 3.10 - name: j res if: always() - run: >- - echo '${{ steps.tox.outputs.json-results }}' - | - ${{ steps.use-py310.outputs.python-version }} -m json.tool + run: echo '${{ steps.tox.outputs.json-results }}' | python3.10 -m json.tool shell: bash # Windows compat From 06e688ff783fa2e7dd278b87858f1f4a794a0150 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 23 Dec 2021 01:20:35 +0100 Subject: [PATCH 14/29] Invoke Python under Windows with `py` --- .github/workflows/tox.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index abb7291..cb99963 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -140,7 +140,14 @@ jobs: 3.10 - name: j res if: always() - run: echo '${{ steps.tox.outputs.json-results }}' | python3.10 -m json.tool + run: >- + echo '${{ steps.tox.outputs.json-results }}' + | + ${{ + runner.os == 'Windows' + && 'py -3.10' + || 'python3.10' + }} -m json.tool shell: bash # Windows compat From 417677a1d78f2f245df94a61318e2d1a593f3f13 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 23 Dec 2021 18:22:30 +0100 Subject: [PATCH 15/29] Expose the `json-results` output from the workflow --- .github/workflows/tox.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index cb99963..5af91d4 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -54,6 +54,9 @@ on: required: false type: string + outputs: + json-results: ${{ jobs.run-tox.outputs.json-results }} + secrets: {} jobs: @@ -120,6 +123,9 @@ jobs: needs: - make-tox-env-matrix + outputs: + json-results: ${{ steps.tox.outputs.json-results }} + runs-on: ${{ matrix.runs-on && matrix.runs-on || 'Ubuntu-latest' }} strategy: From d6c409df1d6af4b091a6ffc6616fdeca156a51f1 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 23 Dec 2021 18:28:05 +0100 Subject: [PATCH 16/29] Fix the workflow outputs syntax --- .github/workflows/tox.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 5af91d4..d400dc6 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -55,7 +55,9 @@ on: type: string outputs: - json-results: ${{ jobs.run-tox.outputs.json-results }} + json-results: + description: JSON results of all the matrix jobs produced by tox + value: ${{ jobs.run-tox.outputs.json-results }} secrets: {} From 8a228fb6949c4467711070d53036afc514640bbe Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 23 Dec 2021 20:10:12 +0100 Subject: [PATCH 17/29] Explain why the called workflow output is bad --- .github/workflows/tox.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index d400dc6..c3fa709 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -55,6 +55,10 @@ on: type: string outputs: + # NOTE: This doesn't actually work well because for jobs with the matrix + # NOTE: strategy chosen, it retrieves the output from one of them instead + # NOTE: of returning results from each job. Ref: + # https://github.community/t/bug-jobs-output-should-return-a-list-for-a-matrix-job/128626 json-results: description: JSON results of all the matrix jobs produced by tox value: ${{ jobs.run-tox.outputs.json-results }} From 74db6d321210a1c0f694b7af5b162a6b89fd060a Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 30 Dec 2021 01:52:06 +0100 Subject: [PATCH 18/29] Enable workflow extract project source from sdist --- .github/workflows/tox.yml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index c3fa709..a8b49bd 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -28,6 +28,21 @@ on: description: Regex to filter the tox envs required: false type: string + workflow-artifact-name: + default: + description: >- + If set, is used the produced dists are made accessible to the + later jobs under this name (defaults to unset) + required: false + type: string + source-tarball-name: + default: >- + *.tar.gz + description: >- + A glob for the built source distribution in the artifact + to retrieve the project from (defaults to `*.tar.gz`) + required: false + type: string min-python: default: 'None' @@ -82,9 +97,16 @@ jobs: runs-on: Ubuntu-latest steps: - # NOTE: Check out the caller repository under $GITHUB_WORKSPACE, - # NOTE: so the job can access it. - - uses: actions/checkout@v2 + - name: Retrieve the project source from the repository + if: >- + !inputs.workflow-artifact-name + uses: actions/checkout@v2 + - name: Retrieve the project source from an sdist inside the GHA artifact + if: inputs.workflow-artifact-name + uses: re-actors/checkout-python-sdist@main + with: + source-tarball-name: ${{ inputs.source-tarball-name }} + workflow-artifact-name: ${{ inputs.workflow-artifact-name }} - name: πŸ”Ž Produce tox environment job matrix for GHA uses: tox-dev/gh-action-tox/matrix@experiments/composite-action From 6a526e001dd14a600004b461577abba32b8c0e36 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 30 Dec 2021 03:10:43 +0100 Subject: [PATCH 19/29] Delegate the project src checkout to the action --- .github/workflows/tox.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index a8b49bd..61c4418 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -97,20 +97,12 @@ jobs: runs-on: Ubuntu-latest steps: - - name: Retrieve the project source from the repository - if: >- - !inputs.workflow-artifact-name - uses: actions/checkout@v2 - - name: Retrieve the project source from an sdist inside the GHA artifact - if: inputs.workflow-artifact-name - uses: re-actors/checkout-python-sdist@main - with: - source-tarball-name: ${{ inputs.source-tarball-name }} - workflow-artifact-name: ${{ inputs.workflow-artifact-name }} - - name: πŸ”Ž Produce tox environment job matrix for GHA uses: tox-dev/gh-action-tox/matrix@experiments/composite-action id: discovered-tox + with: + source-tarball-name: ${{ inputs.source-tarball-name }} + workflow-artifact-name: ${{ inputs.workflow-artifact-name }} - name: Log the discovered matrix run: echo '${{ steps.discovered-tox.outputs.matrix }}' @@ -166,6 +158,8 @@ jobs: with: python-version: ${{ matrix.python-version }} target: ${{ matrix.toxenv }} + source-tarball-name: ${{ inputs.source-tarball-name }} + workflow-artifact-name: ${{ inputs.workflow-artifact-name }} id: tox - uses: actions/setup-python@v2 if: always() From 4d07717e5cfa3db77c664259681c3839bb059e08 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 6 Oct 2022 02:26:43 +0200 Subject: [PATCH 20/29] Bump actions/setup-python to v4 --- .github/workflows/tox.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 61c4418..a03d950 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -109,7 +109,7 @@ jobs: - name: Select Python 3.10 if: inputs.tox-env-matrix-hook - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: >- 3.10 @@ -161,7 +161,7 @@ jobs: source-tarball-name: ${{ inputs.source-tarball-name }} workflow-artifact-name: ${{ inputs.workflow-artifact-name }} id: tox - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 if: always() with: python-version: >- From ae19e0b29376346e3e7260bc0022f55445d54d22 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 6 Oct 2022 02:29:06 +0200 Subject: [PATCH 21/29] Add a comment to the check-tox job --- .github/workflows/tox.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index a03d950..b706ef8 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -179,6 +179,7 @@ jobs: shell: bash # Windows compat + # https://github.com/marketplace/actions/alls-green#why check-tox: # This job does nothing and is only used for the branch protection if: always() From 63f64f9e811549f440ad4ce5bdeb67357314ac6d Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 6 Oct 2022 03:18:54 +0200 Subject: [PATCH 22/29] Use the exact Python executable --- .github/workflows/tox.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index b706ef8..48f150d 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -163,6 +163,7 @@ jobs: id: tox - uses: actions/setup-python@v4 if: always() + id: python-install with: python-version: >- 3.10 @@ -171,11 +172,7 @@ jobs: run: >- echo '${{ steps.tox.outputs.json-results }}' | - ${{ - runner.os == 'Windows' - && 'py -3.10' - || 'python3.10' - }} -m json.tool + ${{ steps.python-install.outputs.python-version }} -m json.tool shell: bash # Windows compat From 2adc99e4e47ce69421bf983d1a78006e0b71f3b1 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 6 Oct 2022 19:52:20 +0200 Subject: [PATCH 23/29] Fix the python path reference --- .github/workflows/tox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 48f150d..1e78451 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -172,7 +172,7 @@ jobs: run: >- echo '${{ steps.tox.outputs.json-results }}' | - ${{ steps.python-install.outputs.python-version }} -m json.tool + ${{ steps.python-install.outputs.python-path }} -m json.tool shell: bash # Windows compat From 27fea1040287a4e75ae27438b2e8b448cf4dab49 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 6 Oct 2022 20:04:36 +0200 Subject: [PATCH 24/29] Unbash the workflow --- .github/workflows/tox.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 1e78451..b2df06b 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -173,7 +173,6 @@ jobs: echo '${{ steps.tox.outputs.json-results }}' | ${{ steps.python-install.outputs.python-path }} -m json.tool - shell: bash # Windows compat # https://github.com/marketplace/actions/alls-green#why From 3e08f1a26ed2736a87848c8f7655cef71abc22d2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 6 Oct 2022 20:58:34 +0200 Subject: [PATCH 25/29] Use json results file instead of an output --- .github/workflows/tox.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index b2df06b..917819e 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -170,9 +170,9 @@ jobs: - name: j res if: always() run: >- - echo '${{ steps.tox.outputs.json-results }}' - | - ${{ steps.python-install.outputs.python-path }} -m json.tool + ${{ steps.python-install.outputs.python-path }} -m + json.tool + '${{ steps.tox.outputs.json-results-file }}' # https://github.com/marketplace/actions/alls-green#why From 8ca2e604091d85babd857a4d919ed0826c010f99 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Fri, 7 Oct 2022 15:50:41 +0200 Subject: [PATCH 26/29] Stop processing output --- .github/workflows/tox.yml | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 917819e..266f734 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -69,14 +69,7 @@ on: required: false type: string - outputs: - # NOTE: This doesn't actually work well because for jobs with the matrix - # NOTE: strategy chosen, it retrieves the output from one of them instead - # NOTE: of returning results from each job. Ref: - # https://github.community/t/bug-jobs-output-should-return-a-list-for-a-matrix-job/128626 - json-results: - description: JSON results of all the matrix jobs produced by tox - value: ${{ jobs.run-tox.outputs.json-results }} + outputs: {} secrets: {} @@ -143,9 +136,6 @@ jobs: needs: - make-tox-env-matrix - outputs: - json-results: ${{ steps.tox.outputs.json-results }} - runs-on: ${{ matrix.runs-on && matrix.runs-on || 'Ubuntu-latest' }} strategy: @@ -161,19 +151,6 @@ jobs: source-tarball-name: ${{ inputs.source-tarball-name }} workflow-artifact-name: ${{ inputs.workflow-artifact-name }} id: tox - - uses: actions/setup-python@v4 - if: always() - id: python-install - with: - python-version: >- - 3.10 - - name: j res - if: always() - run: >- - ${{ steps.python-install.outputs.python-path }} -m - json.tool - '${{ steps.tox.outputs.json-results-file }}' - # https://github.com/marketplace/actions/alls-green#why check-tox: # This job does nothing and is only used for the branch protection From 6ca9f66e2d8cbdeadd81f6b5413e61a5f8b93eac Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 9 Apr 2025 01:57:55 +0200 Subject: [PATCH 27/29] Sync the funding config --- .github/FUNDING.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 25bd04e..dd64f3d 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,10 +1,22 @@ --- custom: -- https://webknjaz.me +- https://www.comebackalive.in.ua/donate +- https://github.com/vshymanskyy/StandWithUkraine#for-maintainers-and-authors - https://www.paypal.me/webknjazCZ +- https://webknjaz.me github: - webknjaz +ko_fi: webknjaz + +liberapay: webknjaz + +open_collective: webknjaz + +# patreon: webknjaz # not in use because of the ties with ruscism + +thanks_dev: u/gh/webknjaz + ... From 6e89496f89a145c67091cc33457e82a07893d37e Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 9 Apr 2025 01:58:26 +0200 Subject: [PATCH 28/29] Lower-case `ubuntu-latest` --- .github/workflows/tox.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 266f734..58d9828 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -87,7 +87,7 @@ jobs: || steps.discovered-tox.outputs.matrix }} - runs-on: Ubuntu-latest + runs-on: ubuntu-latest steps: - name: πŸ”Ž Produce tox environment job matrix for GHA @@ -131,12 +131,12 @@ jobs: name: >- ${{ inputs.tox-job-names-prefix }} ${{ matrix.custom-job-name && matrix.custom-job-name || matrix.toxenv }} - ${{ matrix.runs-on && matrix.runs-on || 'Ubuntu-latest' }} + ${{ matrix.runs-on && matrix.runs-on || 'ubuntu-latest' }} needs: - make-tox-env-matrix - runs-on: ${{ matrix.runs-on && matrix.runs-on || 'Ubuntu-latest' }} + runs-on: ${{ matrix.runs-on && matrix.runs-on || 'ubuntu-latest' }} strategy: matrix: ${{ fromJSON(needs.make-tox-env-matrix.outputs.matrix) }} @@ -161,7 +161,7 @@ jobs: needs: - run-tox - runs-on: Ubuntu-latest + runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed From ba3b988c6eb19b3711eb0fcd3ff8437836a059e8 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 9 Apr 2025 01:58:46 +0200 Subject: [PATCH 29/29] Add `built-wheel-names` input --- .github/workflows/tox.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 58d9828..c4b2055 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -43,6 +43,14 @@ on: to retrieve the project from (defaults to `*.tar.gz`) required: false type: string + built-wheel-names: + default: >- + *.whl + description: >- + A glob for the built distributions in the artifact + to test (defaults to `*.whl`) + required: false + type: string min-python: default: 'None' @@ -148,6 +156,7 @@ jobs: with: python-version: ${{ matrix.python-version }} target: ${{ matrix.toxenv }} + built-wheel-names: ${{ inputs.built-wheel-names }} source-tarball-name: ${{ inputs.source-tarball-name }} workflow-artifact-name: ${{ inputs.workflow-artifact-name }} id: tox