-
-
Notifications
You must be signed in to change notification settings - Fork 30
239 lines (231 loc) · 8.95 KB
/
Copy pathpython-package.yml
File metadata and controls
239 lines (231 loc) · 8.95 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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Python Package
on:
# `push` restricted to `main` so feature branches only run via `pull_request`.
# Otherwise every push to a branch with an open PR would trigger the workflow
# twice (once for `push`, once for `pull_request`) — doubling CI cost and
# latency for no benefit.
push:
branches: [main]
pull_request:
# Allow re-running the workflow without an empty push (handy after the
# workflow gets `disabled_inactivity` after 60 days idle).
workflow_dispatch:
schedule:
- cron: '0 0 */7 * *'
# Cancel an in-flight run when a newer commit lands on the same ref. Keeps the
# queue lean and stops stale runs from blocking the merge button.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install lint deps
run: |
python -m pip install --upgrade pip
pip install flake8
- name: Lint
run: |
flake8 PyMemoryEditor tests
type-check:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dev deps
# Include the `speed` extra (NumPy) so mypy type-checks the NumPy fast
# path against real stubs. Without it, `import numpy` resolves to `Any`
# and the `# type: ignore` in scan_numpy.py reads as unused.
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,speed]"
- name: Run mypy
run: |
mypy PyMemoryEditor
build:
needs: lint
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13']
os:
- ubuntu-latest
- windows-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Qt system libraries (Linux)
# PySide6 links against libEGL/libGL/libxkbcommon/libfontconfig and the
# XCB stack at import time, even when running under the `offscreen`
# platform plugin. The Ubuntu runner ships without them, so pytest-qt's
# `import QtGui` crashes with `libEGL.so.1: cannot open shared object`.
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libegl1 \
libgl1 \
libxkbcommon0 \
libfontconfig1 \
libdbus-1-3 \
libxcb-cursor0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-shape0 \
libxcb-sync1 \
libxcb-xfixes0 \
libxcb-xinerama0 \
libxcb-xkb1 \
libxkbcommon-x11-0
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Test with pytest
env:
QT_QPA_PLATFORM: offscreen
# --cov-fail-under is the real, in-repo coverage gate (deterministic and
# independent of any external service). It's a conservative floor: the
# full suite measures ~87% on a given OS today (coverage.py only counts
# the host backend + shared code — the two foreign backends aren't
# imported, so they don't drag the number down per-platform). 60 leaves
# headroom for a less-covered backend / Python-version variance while
# still catching any large regression. Ratchet it up once the per-OS
# numbers settle on Codecov.
run: |
pytest tests -v -s -x --cov=PyMemoryEditor --cov-report=term --cov-report=xml --cov-fail-under=60
- name: Upload coverage to Codecov
# Upload from every matrix cell so Codecov merges each OS's backend
# coverage into one combined view (each platform exercises a different
# win32/linux/macos backend). Informational only — see codecov.yml — so a
# flaky upload never blocks the merge; the hard gate is --cov-fail-under
# above. Runs even when tests fail so partial coverage stays visible.
if: always()
uses: codecov/codecov-action@v5
with:
files: ./coverage.xml
flags: ${{ runner.os }}-py${{ matrix.python-version }}
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
# macOS gets a single cell instead of a row in the matrix above. Its only
# purpose is to measure the `macos` backend so the merged Codecov report
# covers all three platforms; the Python-version sweep stays on Linux and
# Windows, where it costs a fraction of the wall clock.
#
# Unlike the matrix, this job installs `.[dev,speed]` (NumPy). That is not a
# preference — it is what makes a macOS cell viable at all. A macOS process
# exposes ~390 GiB of sparse address space across ~145 regions, two orders of
# magnitude more than a Linux one, and the scan tests walk all of it. Measured
# on an M-series Mac, this exact command takes ~82s with NumPy and 681s
# without: an 8x gap that a 3-core runner only widens, which is what made
# macOS look like it hung here before (it was removed in 041bfc0).
# The pure-Python scan path loses nothing — all eight cells of the matrix
# above still exercise it.
build-macos:
needs: lint
runs-on: macos-latest
# Hard ceiling so a pathological scan can never sit at the 6h default.
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
# No Qt system-library step here: the PySide6 macOS wheel bundles its own
# Qt frameworks, unlike the Linux one.
- name: Install dependencies (with NumPy speed extra)
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,speed]"
- name: Test with pytest
env:
QT_QPA_PLATFORM: offscreen
# Same conservative coverage gate as the main matrix (see that step's note).
run: |
pytest tests -v -s -x --cov=PyMemoryEditor --cov-report=term --cov-report=xml --cov-fail-under=60
- name: Upload coverage to Codecov
# Flag mirrors the matrix format (`runner.os` is "macOS" here) so Codecov
# groups this cell alongside the Linux and Windows uploads.
if: always()
uses: codecov/codecov-action@v5
with:
files: ./coverage.xml
flags: macOS-py3.12
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
# Isolated job for the optional NumPy-accelerated scan fast path (the
# `[speed]` extra). The matrix above deliberately runs WITHOUT NumPy so the
# pure-Python scan path stays covered; this single Linux job installs
# `.[speed]` on top of the dev deps to exercise the vectorized path.
build-speed:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Qt system libraries (Linux)
# PySide6 links against libEGL/libGL/libxkbcommon/libfontconfig and the
# XCB stack at import time, even when running under the `offscreen`
# platform plugin. The Ubuntu runner ships without them, so pytest-qt's
# `import QtGui` crashes with `libEGL.so.1: cannot open shared object`.
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libegl1 \
libgl1 \
libxkbcommon0 \
libfontconfig1 \
libdbus-1-3 \
libxcb-cursor0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-shape0 \
libxcb-sync1 \
libxcb-xfixes0 \
libxcb-xinerama0 \
libxcb-xkb1 \
libxkbcommon-x11-0
- name: Install dependencies (with NumPy speed extra)
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,speed]"
- name: Test with pytest (NumPy fast path)
env:
QT_QPA_PLATFORM: offscreen
# Same conservative coverage gate as the main matrix (see that step's note).
run: |
pytest tests -v -s -x --cov=PyMemoryEditor --cov-report=term --cov-report=xml --cov-fail-under=60
- name: Upload coverage to Codecov
if: always()
uses: codecov/codecov-action@v5
with:
files: ./coverage.xml
flags: speed-Linux-py3.12
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false