diff --git a/.github/workflows/reusable-tox.yml b/.github/workflows/reusable-tox.yml deleted file mode 100644 index b059f6c..0000000 --- a/.github/workflows/reusable-tox.yml +++ /dev/null @@ -1,518 +0,0 @@ ---- - -name: >- - ❌ - [DO NOT CLICK] - Reusable Tox - -on: - workflow_call: - inputs: - built-wheel-names: - description: >- - A glob for the built distributions in the artifact - to test (is installed into tox env if passed) - required: false - type: string - cache-key-for-dependency-files: - description: Dependency files hash for use in cache keys - required: true - type: string - check-name: - description: A custom name for the Checks API-reported status - required: false - type: string - checkout-src-git-committish: - description: >- - A Git-resolvable ref that is used when the source is taken - from Git. No-op otherwise. The default is whatever - `actions/checkout` does. - default: '' - required: false - type: string - checkout-src-git-fetch-depth: - description: >- - A number of commits for Git to retrieve. Defaults to 1. Set to - 0 when the entire history is necessary. - default: '1' - required: false - type: string - dists-artifact-name: - description: >- - Workflow artifact name containing dists. - Defaults to "python-package-distributions". - default: python-package-distributions - required: false - type: string - environment-variables: - description: >- - A newline-delimited blob of text with environment variables - to be set using `${GITHUB_ENV}` - required: false - type: string - job-dependencies-context: - default: >- - {} - description: >- - The `$ {{ needs }}` context passed from the calling workflow - encoded as a JSON string. The caller is expected to form this - input as follows: - `job-dependencies-context: $ {{ toJSON(needs) }}`. - required: false - type: string - post-toxenv-preparation-command: - description: >- - A command to run at the end of the preparation stage, before - invoking the Tox's main environment command. Can be used to - pre-download things and perform actions that aren't seen as - testing directly. - required: false - type: string - python-version: - description: Python version to provision in the VM - required: true - type: string - require-successful-codecov-uploads: - default: >- - true - description: >- - A boolean string for whether Codecov upload failures would - fail the entire job. Defaults to "true". - required: false - type: string - runner-vm-os: - description: VM OS to use - default: ubuntu-latest - required: false - type: string - source-tarball-name: - description: Sdist filename wildcard - required: false - type: string - timeout-minutes: - description: Deadline for the job to complete - required: true - type: string - toxenv: - description: Name of the tox environment to use - required: true - type: string - tox-provision-args: - description: Tox arguments to pass to the env provisioning run - required: false - type: string - tox-run-args: - description: Tox arguments to pass to the regular run - required: false - type: string - tox-rerun-args: - description: Tox arguments to pass to the re-attempted run - required: false - type: string - tox-run-posargs: - description: Positional arguments to pass to the regular tox run - required: false - type: string - tox-rerun-posargs: - description: Positional arguments to pass to the re-attempted tox run - required: false - type: string - tox-tool-deps: - default: tox tox-uv - description: >- - PEP 508 specifiers passed to `pip install`. Ignored when - `dependencies/direct/tox.in` exists. Defaults to "tox tox-uv". - required: false - type: string - xfail: - description: >- - Whether this job is expected to fail. Controls if the run outcomes - contribute to the failing CI status or not. The job status will be - treated as successful if this is set to `true`. Setting `false` - should be preferred typically. - required: true - type: string - secrets: - codecov-token: - description: An API token for uploading to Codecov - required: false - - outputs: - steps: - description: >- - JSON-formatted collection of all tox steps with their outputs - value: ${{ jobs.tox.outputs.steps }} - -env: - COLOR: >- # Supposedly, pytest or coveragepy use this - yes - FORCE_COLOR: 1 # Request colored output from CLI tools supporting it - MYPY_FORCE_COLOR: 1 # MyPy's color enforcement - PIP_DISABLE_PIP_VERSION_CHECK: 1 - PIP_NO_PYTHON_VERSION_WARNING: 1 - PIP_NO_WARN_SCRIPT_LOCATION: 1 - PRE_COMMIT_COLOR: always - PY_COLORS: 1 # Recognized by the `py` package, dependency of `pytest` - PYTHONIOENCODING: utf-8 - PYTHONUTF8: 1 - TOX_PARALLEL_NO_SPINNER: 1 - TOX_TESTENV_PASSENV: >- # Make tox-wrapped tools see color requests - CI - COLOR - FORCE_COLOR - GITHUB_* - MYPY_FORCE_COLOR - NO_COLOR - PIP_DISABLE_PIP_VERSION_CHECK - PIP_NO_PYTHON_VERSION_WARNING - PIP_NO_WARN_SCRIPT_LOCATION - PRE_COMMIT_COLOR - PY_COLORS - PYTEST_THEME - PYTEST_THEME_MODE - PYTHONDONTWRITEBYTECODE - PYTHONIOENCODING - PYTHONLEGACYWINDOWSSTDIO - PYTHONTRACEMALLOC - PYTHONUTF8 - -jobs: - tox: - name: >- - ${{ - inputs.check-name - && inputs.check-name - || format( - '{0}@🐍{1}@πŸ’»{2}', - inputs.toxenv, - inputs.python-version, - inputs.runner-vm-os - ) - }} - - runs-on: ${{ inputs.runner-vm-os }} - - timeout-minutes: ${{ fromJSON(inputs.timeout-minutes) }} - - continue-on-error: >- - ${{ - ( - fromJSON(inputs.xfail) || - ( - startsWith(inputs.python-version, '~') - ) || - endsWith(inputs.python-version, '-dev') || - contains(inputs.python-version, 'alpha') - ) && true || false - }} - - outputs: - steps: ${{ toJSON(steps) }} - - env: - TOXENV: ${{ inputs.toxenv }} - - steps: - - name: Export requested job-global environment variables - if: inputs.environment-variables != '' - run: >- - echo '${{ inputs.environment-variables }}' - >> "${GITHUB_ENV}" - - - name: >- - Switch to using Python v${{ inputs.python-version }} - by default - id: python-install - uses: actions/setup-python@v6 - with: - python-version: ${{ inputs.python-version }} - - - name: Grab the source from Git - if: inputs.source-tarball-name == '' - uses: actions/checkout@v5 - with: - fetch-depth: ${{ inputs.checkout-src-git-fetch-depth }} - ref: ${{ inputs.checkout-src-git-committish }} - - name: Retrieve the project source from an sdist inside the GHA artifact - if: inputs.source-tarball-name != '' - uses: re-actors/checkout-python-sdist@release/v2 - with: - source-tarball-name: ${{ inputs.source-tarball-name }} - workflow-artifact-name: ${{ inputs.dists-artifact-name }} - - - name: πŸͺ Invoke the in-repo `post-src-checkout` hook (if exists) - id: hook-post-src-checkout - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles( - '.github/reusables/tox-dev/workflow/reusable-tox/hooks/post-src-checkout/action.yml' - ) != '' - uses: ./.github/reusables/tox-dev/workflow/reusable-tox/hooks/post-src-checkout # yamllint disable-line rule:line-length - with: - calling-job-context: ${{ toJSON(inputs) }} - current-job-steps: ${{ toJSON(steps) }} - job-dependencies-context: ${{ inputs.job-dependencies-context }} - - - name: Set up pip cache - uses: re-actors/cache-python-deps@release/v1 - with: - cache-key-for-dependency-files: >- - ${{ inputs.cache-key-for-dependency-files }} - - - name: Identify tox's own lock file - # FIXME: tox-lock/tox-tools/tox-pip-tools <- bin/ - id: tox-deps - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles( - 'bin/print_lockfile_base_name.py', - 'dependencies/direct/tox.in' - ) != '' - run: > - LOCK_FILE_PATH="dependencies/lock-files/$( - python bin/print_lockfile_base_name.py tox - ).txt" - - - echo lock-file="$( - ls -1 "${LOCK_FILE_PATH}" - || >&2 echo "${LOCK_FILE_PATH}" not found, not injecting... - )" - >> "${GITHUB_OUTPUT}" - shell: bash # windows compat - - - name: Install tox and plugins from `dependencies/direct/tox.in` - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles('dependencies/direct/tox.in') != '' - run: >- - python -Im pip install -r dependencies/direct/tox.in - ${{ - steps.tox-deps.outputs.lock-file - && format('--constraint={0}', steps.tox-deps.outputs.lock-file) - || '' - }} - shell: bash # windows compat - - - name: Install ${{ inputs.tox-tool-deps }} - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles('dependencies/direct/tox.in') == '' - run: python -Im pip install ${{ inputs.tox-tool-deps }} - shell: bash # windows compat - - - name: Download all the dists - if: >- - inputs.built-wheel-names != '' - uses: actions/download-artifact@v6 - with: - name: ${{ inputs.dists-artifact-name }} - path: dist/ - - - name: >- - Pre-populate tox envs: `${{ env.TOXENV }}` - run: >- - python -Xutf8 -Im - tox - --parallel auto - --parallel-live - --skip-missing-interpreters false - ${{ inputs.tox-provision-args }} - ${{ - inputs.built-wheel-names != '' - && format('--installpkg dist/{0}', inputs.built-wheel-names) - || '' - }} - --notest - - name: Pre-heat the `${{ env.TOXENV }}` tox env - if: inputs.post-toxenv-preparation-command != '' - run: >- - python -Xutf8 -Im - tox - exec - --skip-pkg-install - --quiet - -- - ${{ inputs.post-toxenv-preparation-command }} - - name: πŸͺ Invoke the in-repo `prepare-for-tox-run` hook (if exists) - id: hook-prepare-for-tox-run - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles( - '.github/reusables/tox-dev/workflow/reusable-tox/hooks/prepare-for-tox-run/action.yml' - ) != '' - uses: ./.github/reusables/tox-dev/workflow/reusable-tox/hooks/prepare-for-tox-run # yamllint disable-line rule:line-length - with: - calling-job-context: ${{ toJSON(inputs) }} - current-job-steps: ${{ toJSON(steps) }} - job-dependencies-context: ${{ inputs.job-dependencies-context }} - - name: >- - Run tox envs: `${{ env.TOXENV }}` - id: tox-run - run: >- - python -Xutf8 -Im - tox - --parallel auto - --parallel-live - --skip-missing-interpreters false - --skip-pkg-install - --quiet - ${{ inputs.tox-run-args }} - ${{ - inputs.tox-run-posargs != '' - && format('-- {0}', inputs.tox-run-posargs) - || '' - }} - - - name: πŸͺ Invoke the in-repo `post-tox-run` hook (if exists) - id: hook-post-tox-run - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles( - '.github/reusables/tox-dev/workflow/reusable-tox/hooks/post-tox-run/action.yml' - ) != '' - uses: ./.github/reusables/tox-dev/workflow/reusable-tox/hooks/post-tox-run - with: - calling-job-context: ${{ toJSON(inputs) }} - current-job-steps: ${{ toJSON(steps) }} - job-dependencies-context: ${{ inputs.job-dependencies-context }} - - - name: Explain re-runing the failing tests - if: >- - !cancelled() - && steps.tox-run.outcome == 'failure' - && inputs.tox-rerun-posargs != '' - run: >- - { - echo '> [!IMPORTANT]'; - echo -n '> The main tox command failed. It has been restarted with '; - echo -n 'maximum context extraction to help you troubleshoot the '; - echo -n 'issue. We have intentionally marked the second run as '; - echo -n 'failing. Be sure to carefully compare the first and the '; - echo -n 'second invocations to learn if the tests are flaky and '; - echo 'hopefully guide you in fixing them. Cheers!' - echo '> πŸ’›πŸ’™' - echo; - echo; - } | tee -a "${GITHUB_STEP_SUMMARY}" - shell: bash -eEuo pipefail {0} - - - name: Produce markdown test summary from JUnit - if: >- - !cancelled() - && steps.tox-run.outputs.test-result-files != '' - uses: test-summary/action@v2.3 - with: - paths: >- - ${{ steps.tox-run.outputs.test-result-files }} - - name: Produce markdown test summary from Cobertura XML - # NOTE: MyPy is temporarily excluded because it produces incomplete XML - # NOTE: files that `irongut/CodeCoverageSummary` can't stomach. - # Refs: - # * https://github.com/irongut/CodeCoverageSummary/issues/324 - # * https://github.com/python/mypy/issues/17689 - # FIXME: Revert the exclusion once upstream fixes the bug. - if: >- - !cancelled() - && runner.os == 'Linux' - && steps.tox-run.outputs.cov-report-files != '' - && steps.tox-run.outputs.test-result-files == '' - && steps.tox-run.outputs.codecov-flags != 'MyPy' - uses: irongut/CodeCoverageSummary@v1.3.0 - with: - badge: true - filename: >- - ${{ steps.tox-run.outputs.cov-report-files }} - format: markdown - output: both - # Ref: https://github.com/irongut/CodeCoverageSummary/issues/66 - - name: Append coverage results to Job Summary - if: >- - !cancelled() - && runner.os == 'Linux' - && steps.tox-run.outputs.cov-report-files != '' - && steps.tox-run.outputs.test-result-files == '' - && steps.tox-run.outputs.codecov-flags != 'MyPy' - run: >- - cat code-coverage-results.md >> "${GITHUB_STEP_SUMMARY}" - - name: Re-run the failing tests with maximum verbosity - if: >- - !cancelled() - && steps.tox-run.outcome == 'failure' - && inputs.tox-rerun-posargs != '' - run: >- # `exit 1` makes sure that the job remains red with flaky runs - python -Xutf8 -Im - tox - --parallel auto - --parallel-live - --skip-missing-interpreters false - -vvvvv - --skip-pkg-install - ${{ inputs.tox-rerun-args }} - -- - ${{ inputs.tox-rerun-posargs }} - && exit 1 - shell: bash - - name: Send coverage data to Codecov - if: >- - !cancelled() - && steps.tox-run.outputs.cov-report-files != '' - uses: codecov/codecov-action@v5 - with: - disable_search: true - fail_ci_if_error: >- - ${{ inputs.require-successful-codecov-uploads }} - files: >- - ${{ steps.tox-run.outputs.cov-report-files }} - flags: >- - CI-GHA, - ${{ steps.tox-run.outputs.codecov-flags }}, - OS-${{ - runner.os - }}, - VM-${{ - inputs.runner-vm-os - }}, - Py-${{ - steps.python-install.outputs.python-version - }} - token: ${{ secrets.codecov-token }} - - name: Upload test results to Codecov - if: >- - !cancelled() - && steps.tox-run.outputs.test-result-files != '' - # NOTE: `codecov/test-results-action` is not used because it has a bug in - # NOTE: the architecture detection logic that leads it to download an - # NOTE: incompatible executable built for x86_64 under arm64. - # yamllint disable rule:line-length - # Ref: https://github.com/codecov/test-results-action/issues/121#issuecomment-2859242703 - # yamllint enable rule:line-length - uses: codecov/codecov-action@v5 - with: - disable_search: true - fail_ci_if_error: >- - ${{ inputs.require-successful-codecov-uploads }} - files: >- - ${{ steps.tox-run.outputs.test-result-files }} - flags: >- - CI-GHA, - ${{ steps.tox-run.outputs.codecov-flags }}, - OS-${{ - runner.os - }}, - VM-${{ - inputs.runner-vm-os - }}, - Py-${{ - steps.python-install.outputs.python-version - }} - report_type: test_results # Toggle from "coverage" to "tests" mode - token: ${{ secrets.codecov-token }} - - - name: πŸͺ Invoke the in-repo `post-tox-job` hook (if exists) - id: hook-post-tox-job - if: >- # `hashFiles()` is used as a rudimentary `file.exists()` - hashFiles( - '.github/reusables/tox-dev/workflow/reusable-tox/hooks/post-tox-job/action.yml' - ) != '' - uses: ./.github/reusables/tox-dev/workflow/reusable-tox/hooks/post-tox-job - with: - calling-job-context: ${{ toJSON(inputs) }} - current-job-steps: ${{ toJSON(steps) }} - job-dependencies-context: ${{ inputs.job-dependencies-context }} - -... diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml new file mode 100644 index 0000000..c4b2055 --- /dev/null +++ b/.github/workflows/tox.yml @@ -0,0 +1,181 @@ +--- + +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: 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 + 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' + 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 + + tox-env-matrix-hook: + default: + description: >- + A Python snippet that can be used to modify the + automatically generated job matrix + required: false + type: string + + outputs: {} + + secrets: {} + +jobs: + + make-tox-env-matrix: + name: >- + πŸ”Ž tox: discover envs + + outputs: + matrix: >- + ${{ + inputs.tox-env-matrix-hook + && steps.post-process-matrix-definition.outputs.matrix + || steps.discovered-tox.outputs.matrix + }} + + runs-on: ubuntu-latest + + steps: + - 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 }}' + + - name: Select Python 3.10 + if: inputs.tox-env-matrix-hook + uses: actions/setup-python@v4 + 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: >- + ${{ inputs.tox-job-names-prefix }} + ${{ 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: ${{ matrix.runs-on && matrix.runs-on || 'ubuntu-latest' }} + + strategy: + matrix: ${{ fromJSON(needs.make-tox-env-matrix.outputs.matrix) }} + + steps: + - name: >- + πŸ§ͺ Run tox: ${{ matrix.toxenv }} + uses: tox-dev/gh-action-tox@experiments/composite-action + 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 + + # https://github.com/marketplace/actions/alls-green#why + check-tox: # This job does nothing and is only used for the branch protection + if: always() + + name: ${{ inputs.check-job-name }} + + 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) }} + +... diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 3a2039f..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- - -ci: - autoupdate_schedule: quarterly - -repos: -- repo: https://github.com/adrienverge/yamllint.git - rev: v1.37.1 - hooks: - - id: yamllint - args: - - --strict - -- repo: https://github.com/rhysd/actionlint.git - rev: v1.7.7 - hooks: - - id: actionlint - -... diff --git a/.yamllint b/.yamllint deleted file mode 100644 index 3dde2ea..0000000 --- a/.yamllint +++ /dev/null @@ -1,20 +0,0 @@ ---- - -extends: default - -rules: - indentation: - level: error - indent-sequences: false - quoted-strings: - required: only-when-needed - truthy: - allowed-values: - - >- - false - - >- - true - - >- # Allow "on" key name in GHA CI/CD workflow definitions - on - -... diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 52deee1..0000000 --- a/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright Β© Sviatoslav Sydorenko (@webknjaz ) -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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. diff --git a/README.md b/README.md index b8a3cf6..634f15f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,51 @@ -![tox-dev badge] -[![pre-commit.ci status badge]][pre-commit.ci results page] -[![GH Sponsors badge]][GH Sponsors URL] +# One (Reusable) Tox Workflow To Rule Them All -# `tox-dev/workflow@release/v1` +This repository holds a centrally maintained test matrix for tox-based +projects. -[tox-dev badge]: -https://img.shields.io/badge/project-yellow?label=tox-dev&labelColor=c3cc39&color=7f833e +## Howto -[pre-commit.ci results page]: -https://results.pre-commit.ci/latest/github/tox-dev/workflow/release/v1 -[pre-commit.ci status badge]: -https://results.pre-commit.ci/badge/github/tox-dev/workflow/release/v1.svg +The example use is demonstrated below. You can start by provisioning a +file at the path `.github/workflows/ci-cd.yml` in your repository. -[GH Sponsors badge]: -https://img.shields.io/badge/%40webknjaz-transparent?logo=githubsponsors&logoColor=%23EA4AAA&label=Sponsor&color=2a313c -[GH Sponsors URL]: -https://github.com/sponsors/webknjaz +```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.