Skip to content

Commit

Permalink
feat: allow defining a python version list for GHA action
Browse files Browse the repository at this point in the history
  • Loading branch information
mayeut committed Apr 30, 2022
1 parent e538b56 commit 988e1ec
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 15 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ jobs:
- uses: actions/checkout@v2
- uses: ./
- run: nox --non-interactive --error-on-missing-interpreter --session github_actions_default_tests
action-all-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04, windows-2019, windows-2022, macos-10.15, macos-11, macos-12]
steps:
- uses: actions/checkout@v2
- uses: ./
with:
python-versions: "2.7.18, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11-dev, pypy-3.7, pypy-3.8, pypy-3.9-v7.3.9"
- run: nox --non-interactive --error-on-missing-interpreter --session github_actions_all_tests
lint:
runs-on: ubuntu-20.04
steps:
Expand Down
118 changes: 108 additions & 10 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,134 @@
name: Setup Nox
description: 'Prepares all python versions for nox'
description: "Prepares all python versions for nox"
inputs:
python-versions:
description: "comma-separated list of python versions to install"
required: true
default: "3.7, 3.8, 3.9, 3.10, pypy-3.7, pypy-3.8, pypy-3.9"
branding:
icon: package
color: blue

runs:
using: composite
steps:
- name: "Validate input"
id: validate-input
run: |
def filter_version(version):
"""return python 'major.minor'"""
if version.startswith("pypy-"):
version_ = version[5:]
elif version.startswith("pypy"):
version_ = version[4:]
else:
version_ = version
version_ = version_.split("-")[0] # remove extra specifier e.g. "3.11-dev" => "3.11"
version_parts = version_.split(".")
if len(version_parts) < 2:
raise ValueError(f"invalid version: {version}")
if not version_parts[0].isdigit():
raise ValueError(f"invalid major python version: {version}")
if not version_parts[1].isdigit():
raise ValueError(f"invalid minor python version: {version}")
return ".".join(version_parts[:2])
input = "${{ inputs.python-versions }}"
versions = [version.strip() for version in input.split(",")]
pypy_versions = [version for version in versions if version.startswith("pypy")]
pypy_versions_filtered = [filter_version(version) for version in pypy_versions]
if len(pypy_versions) != len(set(pypy_versions_filtered)):
raise ValueError(f"multiple versions specified for the same 'major.minor' PyPy interpreter: {pypy_versions}")
cpython_versions = [version for version in versions if version not in pypy_versions]
cpython_versions_filtered = [filter_version(version) for version in cpython_versions]
if len(cpython_versions) != len(set(cpython_versions_filtered)):
raise ValueError(f"multiple versions specified for the same 'major.minor' CPython interpreter: {cpython_versions}")
# cpython shall be installed last because
# other interpreters also define pythonX.Y symlinks.
versions = pypy_versions + cpython_versions
if "3.10" in cpython_versions_filtered:
# need to place this last
index = cpython_versions_filtered.index("3.10")
index = versions.index(cpython_versions[index])
cpython_310 = versions.pop(index)
versions.append(cpython_310)
else:
# add this to install nox
versions.append("3.10")
if len(versions) > 15:
raise ValueError(f"Too many interpreters to install: {len(versions)} > 15")
print(f"::set-output name=interpreter_count::{len(versions)}")
for i, version in enumerate(versions):
print(f"::set-output name=interpreter_{i}::{version}")
shell: "${{ runner.os == 'Windows' && 'python' || 'python3' }} {0}"
- uses: actions/setup-python@v3
with:
python-version: "pypy-3.7"
python-version: "${{ steps.validate-input.outputs.interpreter_0 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 0 }}
- uses: actions/setup-python@v3
with:
python-version: "pypy-3.8"
python-version: "${{ steps.validate-input.outputs.interpreter_1 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 1 }}
- uses: actions/setup-python@v3
with:
python-version: "pypy-3.9"

python-version: "${{ steps.validate-input.outputs.interpreter_2 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 2 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_3 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 3 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_4 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 4 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_5 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 5 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_6 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 6 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_7 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 7 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_8 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 8 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_9 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 9 }}
- uses: actions/setup-python@v3
with:
python-version: "${{ steps.validate-input.outputs.interpreter_10 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 10 }}
- uses: actions/setup-python@v3
with:
python-version: "3.7"
python-version: "${{ steps.validate-input.outputs.interpreter_11 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 11 }}
- uses: actions/setup-python@v3
with:
python-version: "3.8"
python-version: "${{ steps.validate-input.outputs.interpreter_12 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 12 }}
- uses: actions/setup-python@v3
with:
python-version: "3.9"
python-version: "${{ steps.validate-input.outputs.interpreter_13 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 13 }}
- uses: actions/setup-python@v3
with:
python-version: "3.10"
python-version: "${{ steps.validate-input.outputs.interpreter_14 }}"
if: ${{ steps.validate-input.outputs.interpreter_count > 14 }}

- name: "Install nox"
# --python "$(which python)" => always use the last setup-python version to install nox.
run: pipx install --python "$(which python)" '${{ github.action_path }}'
shell: bash
16 changes: 11 additions & 5 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,23 @@ If you want to run ``nox`` within `GitHub Actions`_, you can use the ``wntrblm/n
# setup nox with all active CPython and PyPY versions provided by
# the GitHub Actions environment i.e.
# CPython 3.7 -> 3.10, PyPy 3.7 -> 3.9
# python-versions: "3.7, 3.8, 3.9, 3.10, pypy-3.7, pypy-3.8, pypy-3.9"
- uses: wntrblm/nox
# You can also safely combine this with setup-python
# setup nox only for a given list of python versions
# Limitations:
# - Version specifiers shall be supported by actions/setup-python
# - You can specify up-to 15 versions
# - There can only be one "major.minor" per interpreter i.e. "3.7.0, 3.7.1" is invalid
- uses: wntrblm/nox
- uses: actions/setup-python@v3
with:
python-version: "2.7"
python-versions: "2.7, 3.5, 3.10, 3.11-dev, pypy-3.9"
# You can also safely combine this with setup-python
- uses: wntrblm/nox
- uses: actions/setup-python@v3
with:
python-version: "3.11-dev"
python-version: "3.11.0-alpha.7"
.. _pip: https://pip.readthedocs.org
.. _user site: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
Expand Down
21 changes: 21 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,24 @@ def _check_python_version(session):
def github_actions_default_tests(session):
"""Check default versions installed by the nox GHA Action"""
_check_python_version(session)


# The following sessions are only to be run in CI to check the nox GHA action
@nox.session(
python=[
"2.7",
"3.5",
"3.6",
"3.7",
"3.8",
"3.9",
"3.10",
"3.11",
"pypy3.7",
"pypy3.8",
"pypy3.9",
]
)
def github_actions_all_tests(session):
"""Check all versions installed by the nox GHA Action"""
_check_python_version(session)

0 comments on commit 988e1ec

Please sign in to comment.