Repository navigation
143 lines (133 loc) · 6.53 KB
/
Copy pathpython-compatibility.yml
File metadata and controls
143 lines (133 loc) · 6.53 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
name: "Python Compatibility"
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 4 * * 6'
permissions:
contents: read
# Only pull-request runs may be superseded. Keying every event on the ref (as
# this did) coalesces all of main's pushes into one group, and GitHub cancels a
# *pending* run whenever a newer one joins the group -- `cancel-in-progress:
# false` protects a run that has already started, never one still queued. So a
# commit merged while its predecessor was still running lost its validation
# entirely. Keying non-PR events on the run id gives each one its own group,
# which is what "validate every commit" actually requires.
concurrency:
group: python-compatibility-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# #1660: the matrix below, from .github/python-versions.toml -- see the job of
# the same name in unit-tests.yml.
python-versions:
name: Read the Python versions
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
compatibility: ${{ steps.read.outputs.compatibility }}
steps:
- uses: actions/checkout@v7
with:
sparse-checkout: |
.github/python-versions.toml
util/python_versions.py
sparse-checkout-cone-mode: false
persist-credentials: false
- name: Read .github/python-versions.toml
id: read
run: python3 util/python_versions.py --github-output
compatibility:
# Not named "Python ${{ matrix.python-version }}": that name collided
# exactly with the Unit Tests matrix job of the same name, and `gh pr checks`
# showed two rows reading `Python 3.10`, one a 13-second import smoke test
# and one a three-minute test run, with nothing to tell them apart.
#
# #1633: two tiers. The supported tier, 3.11-3.15, keeps the plain name,
# which is what ruleset 23497679 requires one context per version of. The
# KTLO tier, end-of-life 3.7-3.10, is suffixed ` (KTLO)`, so no required
# context can match one. Its steps carry `continue-on-error`, as in
# unit-tests.yml's `test` job: job-level, a failed leg's check run concluded
# `failure`, so every commit showed red (#1672). 3.7 fails "Verify package"
# by design. No 3.6: setup-python builds it only for retired Ubuntu images.
name: Compat Python ${{ matrix.python-version }}${{ matrix.ktlo && ' (KTLO)' || '' }}
needs: [python-versions]
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
env:
ANNOTATION_LEVEL: ${{ matrix.ktlo && 'warning' || 'error' }}
strategy:
fail-fast: false
# Both tiers, as for the `test` job in unit-tests.yml (#1660): a KTLO leg
# carries `ktlo: true`, and `os` where `ubuntu-latest` cannot provide it.
# setup-python publishes 3.8 and 3.9 builds up to Ubuntu 24.04 only, and
# `ubuntu-latest` moves to 26.04 from 2026-10-19, hence their pin. 3.7's
# newest is for the deprecated 22.04; see the `test` job in unit-tests.yml.
# Each supported leg is one of ruleset 23497679's required contexts, so a
# tier change edits the ruleset too.
matrix: ${{ fromJSON(needs.python-versions.outputs.compatibility) }}
steps:
- uses: actions/checkout@v7
id: checkout
continue-on-error: ${{ matrix.ktlo == true }}
- uses: actions/setup-python@v7
id: python
continue-on-error: ${{ matrix.ktlo == true }}
with:
python-version: ${{ matrix.python-version }}
# The install needs this leg's interpreter, and the check below needs the
# install, as in unit-tests.yml's `test` job: on a KTLO leg a failed step
# does not stop the job, so each one waits on the `outcome` it needs.
- name: Install package
id: install
if: ${{ steps.python.outcome == 'success' }}
continue-on-error: ${{ matrix.ktlo == true }}
run: |
python -m pip install -U pip setuptools wheel
python -m pip install -e .
# One annotation saying why, so a failed leg -- such as 3.7's, where the
# editable install succeeds and the sources do not compile -- is legible
# from the run summary without opening the log. ANNOTATION_LEVEL makes it
# a warning on a KTLO leg (#1672). Each title escapes `,` as `%2C`: the
# runner splits a command's properties on `,`, so the KTLO leg's title
# would otherwise stop at "(KTLO" (actions/runner
# src/Runner.Common/ActionCommand.cs:100, at 5f0b3ddcc).
- name: Verify package
id: verify
if: ${{ steps.install.outcome == 'success' }}
continue-on-error: ${{ matrix.ktlo == true }}
shell: bash
env:
LEG: Python ${{ matrix.python-version }}${{ matrix.ktlo && ' (KTLO, non-blocking)' || '' }}
run: |
log="$RUNNER_TEMP/compileall.log"
if ! python -m compileall -q pcapkit > "$log" 2>&1; then
cat "$log"
count=$(awk '/^\*\*\* Error compiling /{n++} END{print n+0}' "$log")
first=$(awk '/^ File "/{sub(/^ /, ""); print; exit}' "$log")
echo "::${ANNOTATION_LEVEL} title=pcapkit does not compile on ${LEG//,/%2C}::$count modules fail to compile, the first at ${first:-an unreported place}; see this step's log."
exit 1
fi
if ! python -c 'import pcapkit; print(pcapkit.__version__)'; then
echo "::${ANNOTATION_LEVEL} title=pcapkit does not import on ${LEG//,/%2C}::See the traceback in this step's log."
exit 1
fi
# #1672: the KTLO leg's report -- the same step ends every KTLO matrix
# job; see unit-tests.yml's `test` job for how it works.
- name: KTLO summary
if: ${{ !cancelled() && matrix.ktlo == true }}
continue-on-error: ${{ matrix.ktlo == true }}
shell: bash
env:
LEG: Python ${{ matrix.python-version }}${{ matrix.ktlo && ' (KTLO, non-blocking)' || '' }}
STEPS: ${{ toJSON(steps) }}
run: |
failed=$(jq -r 'to_entries[] | select(.value.outcome == "failure") | .key' <<< "$STEPS")
if [ -z "$failed" ]; then
echo "$LEG: no step failed."
exit 0
fi
while IFS= read -r id; do
echo "::warning title=${id} failed on ${LEG//,/%2C}::KTLO legs never block (#1633), so this job still succeeds (#1672); see the ${id} step's log."
echo "- ${LEG}: step \`${id}\` failed; non-blocking, so this job still succeeds." >> "$GITHUB_STEP_SUMMARY"
done <<< "$failed"