1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
# Generate the matrix of jobs to run tests, build docs, build installers
#
# run `python .github/workflows/matrix.py --json` to see the output
#
# Philosophy:
# - test everything
# - get unittest results back as fast as possible, burning extra CPU time
# to do that if necessary
# - sphinx is slow, build documentation separately to running the unittests
# - pyinstaller is slow, run it separately to running the unittests
import json
import sys
pretty = "--json" in sys.argv
jobs = []
# List of OS images to use for release builds
# Notes on OS selection:
# - macos
# - windows
# - linux: the release that is used defines the oldest distro on which
# the Linux pyinstaller output will run as libc is still
# dynamically linked by pyinstaller.
# https://pyinstaller.readthedocs.io/en/stable/usage.html#making-gnu-linux-apps-forward-compatible
os_release_list = [
'ubuntu-22.04',
'windows-latest',
'macos-latest',
'macos-15-intel',
]
# List of OS images to use for release tests
os_test_list = os_release_list + [
'ubuntu-latest',
]
# List of python versions to use for release builds
python_release_list = [
'3.11',
]
# List of python versions to use for tests
python_test_list = python_release_list + [
# No additional test versions - add more to this list as needed
]
def truthy(val):
# the json importer in the github actions doesn't cope with true, false,
# or none particularly nicely; making this output only 0/1 as integers
# simplifies all the conditionals in the yml file.
return int(bool(val))
def entry(job_name="Job", os=None, pyver=None, tests=None, docs=None, installer=None):
# Stuff the values into a dict that will appear in the json;
# make sure all entries have all keys even if not specified for that
# job so that validating the matrix or fallbacks for missing keys are
# not needed in the yml file.
return {
'job_name': job_name,
'os': os or os_release_list[0],
'python-version': pyver or python_release_list[0],
'tests': truthy(tests),
'docs': truthy(docs),
'installer': truthy(installer),
}
## Construct the list of jobs for build+test
# Test all the OS/pyver combinations as quickly as possible to get unittest
# results back to the author; docs and installer are much slower, so
# leave them for a separate build.
for os in os_test_list:
for pyver in python_test_list:
jobs.append(
entry(
job_name = f"Test ({os}, {pyver})",
os = os,
pyver = pyver,
tests = True,
docs = False,
installer = False,
)
)
## Construct the list of jobs for the installer
# Building the installer needs the docs but not the tests; this is a simple
# time optimisation to get the installer built faster, since the tests
# take a bit of time to run and are already run in the 'test' jobs.
for os in os_release_list:
for pyver in python_release_list:
jobs.append(
entry(
job_name = f"Installer ({os}, {pyver})",
os = os,
pyver = pyver,
tests = False,
docs = True,
installer = True,
)
)
if not pretty:
print("matrix=", end='')
print(json.dumps(jobs, indent=4 if pretty else None))
|