Skip to content

Commit

Permalink
Test more on GitHub Actions (#564)
Browse files Browse the repository at this point in the history
The only environments left on AppVeyor are now 2.7, 3.5, and 3.6. The remaining Python versions are now also tested on Windows using GitHub Actions.

Additionally, a new group of dependencies called "oldest" is now tested as well to ensure compatibility with the oldest pinned versions in requirements.txt and setup.py.

AppVeyor is used for 3.5 and 3.6 because those versions aren't available on GitHub Actions at all. Python 2.7 crashes on Windows with a pip cache failure so it only runs on GHA with the "oldest" dependencies on Ubuntu.

The other Python version running "oldest" dependencies is 3.7, also only running on Ubuntu.
  • Loading branch information
ambv committed Mar 3, 2023
1 parent 01b7dea commit f0bb2a6
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 42 deletions.
8 changes: 0 additions & 8 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ environment:
- TOXENV: py35-optional
- TOXENV: py36-base
- TOXENV: py36-optional
- TOXENV: py37-base
- TOXENV: py37-optional
- TOXENV: py38-base
- TOXENV: py38-optional
- TOXENV: py39-base
- TOXENV: py39-optional
- TOXENV: py310-base
- TOXENV: py310-optional

install:
- git submodule update --init --recursive
Expand Down
51 changes: 46 additions & 5 deletions .github/workflows/python-tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,62 @@ jobs:
# Prevent duplicate builds for 'internal' pull requests on existing commits
# Credit: https://github.community/t/duplicate-checks-on-push-and-pull-request-simultaneous-event/18012
if: github.event.push || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy-2.7", "pypy-3.8"]
# 2.7, 3.5, and 3.6 run on Windows via AppVeyor
python: ["3.7", "3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-latest, windows-latest]
deps: [base, optional]
include:
- python: "pypy-2.7"
os: ubuntu-latest
deps: base
- python: "pypy-3.8"
os: ubuntu-latest
deps: base
- python: "2.7"
os: ubuntu-latest
deps: oldest
- python: "3.7"
os: ubuntu-latest
deps: oldest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: actions/setup-python@v4
- if: ${{ matrix.deps == 'base' }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
cache: pip
cache-dependency-path: "requirements*.txt"
cache-dependency-path: |
requirements.txt
requirements-test.txt
- if: ${{ matrix.deps == 'optional' }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
cache: pip
cache-dependency-path: |
requirements.txt
requirements-optional.txt
requirements-test.txt
- if: ${{ matrix.deps == 'oldest' }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
cache: pip
cache-dependency-path: |
requirements-oldest.txt
- if: ${{ matrix.os == 'windows-latest' }}
name: Determine environment name for Tox (PowerShell)
run: python toxver.py ${{ matrix.python }} ${{ matrix.deps }} >> $env:GITHUB_ENV
- if: ${{ matrix.os == 'ubuntu-latest' }}
name: Determine environment name for Tox (Bash)
run: python toxver.py ${{ matrix.python }} ${{ matrix.deps }} >> $GITHUB_ENV
- run: pip install tox
- run: tox -e py
- run: tox
- if: ${{ always() }}
run: python debug-info.py
15 changes: 0 additions & 15 deletions requirements-install.sh

This file was deleted.

29 changes: 29 additions & 0 deletions requirements-oldest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This allows us to install the actually oldest supported dependencies and test whether that works.

# requirements.txt
six==1.9
webencodings==0.5.1

# requirements-optional.txt
genshi==0.7.1 ; python_version < '3.8'
genshi==0.7.6 ; python_version >= '3.8'
chardet==2.2.1
# this should be 3.4.0 but there are no Linux
# binary wheels for older releases
lxml==3.8.0 ; python_version < '3.7'
# minimums for 3.x are actually different:
# - 3.7 is actually 4.1.1
# - 3.8 is actually 4.3.5
# - 3.9-3.10 is actually 4.5.2
# - 3.11 is actually 4.9.0
lxml==4.9.0 ; python_version >= '3.7'

# requirements-test.txt
flake8==3.9.2 ; python_version < '3.6'
flake8==5.0.4; python_version >= '3.6'
pytest==4.6.10 ; python_version < '3'
pytest==5.4.2 ; python_version >= '3'
coverage==5.1
pytest-expect==1.1.0
mock==3.0.5 ; python_version < '3.6'
mock==4.0.2 ; python_version >= '3.6'
6 changes: 3 additions & 3 deletions requirements-optional.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

# We support a Genshi treewalker that can be used to serialize Genshi
# streams.
genshi
genshi>=0.7.1

# chardet can be used as a fallback in case we are unable to determine
# the encoding of a document.
chardet>=2.2
chardet>=2.2.1

# lxml is supported with its own treebuilder ("lxml") and otherwise
# uses the standard ElementTree support
lxml ; platform_python_implementation == 'CPython'
lxml>=3.4.0 ; platform_python_implementation == 'CPython'
4 changes: 2 additions & 2 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-r requirements.txt

tox>=3.15.1,<4
flake8>=3.8.1,<6
flake8==3.9.2 ; python_version < '3.6'
flake8>=5.0.4; python_version >= '3.6'
pytest>=4.6.10,<5 ; python_version < '3'
pytest>=5.4.2,<7 ; python_version >= '3'
coverage>=5.1,<6
Expand Down
12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,23 @@ def default_environment():
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
install_requires=[
'six>=1.9',
'webencodings',
'webencodings>=0.5.1',
],
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
extras_require={
# A conditional extra will only install these items when the extra is
# requested and the condition matches.
"lxml:platform_python_implementation == 'CPython'": ["lxml"],
"lxml:platform_python_implementation == 'CPython'": ["lxml>=3.4.0"],

# Standard extras, will be installed when the extra is requested.
"genshi": ["genshi"],
"chardet": ["chardet>=2.2"],
"genshi": ["genshi>=0.7.1"],
"chardet": ["chardet>=2.2.1"],

# The all extra combines a standard extra which will be used anytime
# the all extra is requested, and it extends it with a conditional
# extra that will be installed whenever the condition matches and the
# all extra is requested.
"all": ["genshi", "chardet>=2.2"],
"all:platform_python_implementation == 'CPython'": ["lxml"],
"all": ["genshi>=0.7.1", "chardet>=2.2.1"],
"all:platform_python_implementation == 'CPython'": ["lxml>=3.4.0"],
},
)
7 changes: 4 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
[tox]
envlist = py{27,35,36,37,38,39,310,311,py,py3}-{base,six19,optional}
envlist = py{27,35,36,37,38,39,310,311,py,py3}-{base,optional,oldest}

[testenv]
deps =
base: -r{toxinidir}/requirements-test.txt
optional: -r{toxinidir}/requirements-test.txt
optional: -r{toxinidir}/requirements-optional.txt
-r{toxinidir}/requirements-test.txt
oldest: -r{toxinidir}/requirements-oldest.txt
doc: Sphinx

passenv =
PYTEST_COMMAND # this is maintained so one can, e.g., PYTEST_COMMAND="coverage run -m pytest"
COVERAGE_RUN_OPTIONS
commands =
six19: pip install six==1.9
{env:PYTEST_COMMAND:{envbindir}/pytest} {posargs}
flake8 {toxinidir}

Expand Down
57 changes: 57 additions & 0 deletions toxver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python

"""
usage: toxver.py [python-version] [deps]
Returns a Tox environment name given a GHA matrix Python version and dependencies.
Many GHA configurations do this with inline Bash scripts but we want our solution
to be cross-platform and work on Windows workers, too.
Examples:
$ toxver.py pypy-3.8 base
TOXENV=pypy3-base
$ toxver.py 2.7 oldest
TOXENV=py27-oldest
$ toxver.py ~3.12.0-0 optional
TOXENV=py312-optional
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import sys


def main(argv):
if len(argv) != 3:
print(__doc__.strip(), file=sys.stderr)
return 1

deps = argv[2]

if argv[1].startswith("pypy-2"):
print("TOXENV=pypy-" + deps)
return 0

if argv[1].startswith("pypy-3"):
print("TOXENV=pypy3-" + deps)
return 0

if argv[1].startswith("~"):
ver = argv[1][1:5]
else:
ver = argv[1]

ver = ver.replace(".", "")
print("TOXENV=py" + ver + "-" + deps)
return 0


if __name__ == "__main__":
sys.exit(main(sys.argv))

0 comments on commit f0bb2a6

Please sign in to comment.