-
Notifications
You must be signed in to change notification settings - Fork 0
250 lines (233 loc) · 11.3 KB
/
Copy pathwindows-unit-tests.yml
File metadata and controls
250 lines (233 loc) · 11.3 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
240
241
242
243
244
245
246
247
248
249
250
name: Windows Unit Tests
on:
push:
branches: [main]
pull_request:
schedule:
# Nightly drift check at 05:15 UTC — staggered 15min after the
# Linux unit-tests cron (05:00) so the two runners do not contend
# for the same upstream resources or notification slots. Surfaces
# upstream regressions that only manifest on the Windows side
# (MSYS2 packaging shifts, Win-specific gi typelib changes).
- cron: '15 5 * * *'
workflow_dispatch:
inputs:
gramps_repo:
description: 'gramps repo (owner/name); empty = same-owner fork'
default: ''
gramps_ref:
description: 'gramps branch/tag/sha; empty = matrix defaults'
default: ''
# See interface-tests.yml for rationale — dorny/test-reporter needs
# checks: write + pull-requests: write.
permissions:
contents: read
checks: write
pull-requests: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
windows-unit-tests:
name: '[upstream] Windows Unit Tests (${{ matrix.gramps_ref }})'
runs-on: windows-latest
timeout-minutes: 30
# Advisory gate. Same rationale as unit-tests.yml: this job runs
# gramps' own *_test.py suite against an upstream gramps checkout,
# so failures here almost always reflect upstream regressions or
# MSYS2 packaging drift, not testbed bugs. continue-on-error lets
# testbed PRs merge on upstream-caused red.
continue-on-error: true
strategy:
fail-fast: false
matrix:
# Windows uses UCRT64 (per #2198); UCRT64 + the BSDDB-on-Windows
# skip (#2202) only landed on maintenance/gramps61 and master, so
# gramps60 is not Windows-eligible and is omitted here. (Linux
# unit-tests.yml is gramps61-only too now; an earlier version of
# this note claiming "Linux still tests gramps60" was stale.)
# When Windows-eligible gramps minors expand, add them here.
gramps_ref:
- maintenance/gramps61
- master
defaults:
run:
shell: msys2 {0}
steps:
- name: Checkout testbed
uses: actions/checkout@v4
with:
path: gramps-testbed
- name: Checkout gramps fork
uses: actions/checkout@v4
with:
repository: ${{ github.event.inputs.gramps_repo || vars.GRAMPS_REPO || format('{0}/gramps', github.repository_owner) }}
ref: ${{ github.event.inputs.gramps_ref || matrix.gramps_ref }}
path: gramps
- name: Set up MSYS2 UCRT64
# Authoritative reference for the install list is the AIO build
# script (../gramps/aio/build.sh on maintenance/gramps61). This is
# the trimmed runtime subset — enough for gramps.gen to import
# and the *_test.py suite to run, but not for the AIO build
# itself (cx_freeze, NSIS, dictionary tooling are dropped).
# UCRT64 (vs the older MINGW64) is required: MINGW64's Python
# interpreter has target triple mingw_x86_64_msvcrt_gnu which
# orjson's maturin backend rejects, blocking gramps[testing]
# install. UCRT64's ucrt triple resolves orjson on PyPI.
# Migrated upstream in gramps PR #2198 (merged 2026-04-19).
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
install: >-
mingw-w64-ucrt-x86_64-python
mingw-w64-ucrt-x86_64-python-pip
mingw-w64-ucrt-x86_64-python-gobject
mingw-w64-ucrt-x86_64-python-cairo
mingw-w64-ucrt-x86_64-python-icu
mingw-w64-ucrt-x86_64-python-lxml
mingw-w64-ucrt-x86_64-python-jsonschema
mingw-w64-ucrt-x86_64-python-pillow
mingw-w64-ucrt-x86_64-python-maturin
mingw-w64-ucrt-x86_64-rust
mingw-w64-ucrt-x86_64-gexiv2
mingw-w64-ucrt-x86_64-gtk3
mingw-w64-ucrt-x86_64-osm-gps-map
mingw-w64-ucrt-x86_64-goocanvas
mingw-w64-ucrt-x86_64-gettext
intltool
- name: Install pinned-URL packages (graphviz, gspell, enchant)
# Mirrors aio/build.sh: the current MSYS2 main-repo versions of
# graphviz/gspell/enchant have compatibility regressions
# (graphviz breaks pygraphviz; spellcheck breaks on newer
# gspell/enchant), so upstream pins them to the 6.0.8-era
# versions via `pacman -U` from repo.msys2.org. Keep these URLs
# in sync with aio/build.sh — when AIO bumps them, bump here too.
# gexiv2/exiv2 are no longer pinned (#2198 moved gexiv2 to the
# regular pacman set; exiv2 comes in as a transitive dep).
run: |
pacman -U --needed --noconfirm \
https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-enchant-2.6.7-5-any.pkg.tar.zst \
https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-graphviz-12.2.1-4-any.pkg.tar.zst \
https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-gspell-1.14.0-4-any.pkg.tar.zst
- name: Set up Python venv (inherits gi/cairo/icu from pacman)
# Same rationale as the Ubuntu workflow's --system-site-packages
# venv: pacman python-gobject installs into /ucrt64's site —
# only visible to that interpreter. Inheriting it via venv keeps
# `pip install` writes contained while gramps.gen's `import gi`
# still resolves at test-collection time.
#
# MSYS2 UCRT64 Python uses POSIX-style venv layout (bin/), not
# Windows-native CPython's Scripts/. Its interpreter ships at
# /ucrt64/bin/python.exe and venvs it creates follow the same
# convention. Using Scripts/ here would 127 on `not found`.
run: |
/ucrt64/bin/python -m venv --system-site-packages .venv
echo "$(cygpath -u "$GITHUB_WORKSPACE")/.venv/bin" >> "$GITHUB_PATH"
.venv/bin/python -m pip install --upgrade pip
- name: Restore pip cache
# actions/cache scopes the key by runner.os automatically
# (Linux vs. Windows do not collide on the same key).
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-${{ hashFiles('gramps-testbed/requirements-test.txt') }}
restore-keys: |
pip-${{ runner.os }}-
- name: Install Python dependencies
# `source .venv/bin/activate` is required (not just $GITHUB_PATH
# from the venv-setup step): with `shell: msys2 {0}`, each step
# gets a fresh msys2 bash whose PATH inherits from setup-msys2's
# mingw context, not from the GITHUB_PATH prepend. UCRT64's
# Python 3.14 ships PEP 668's EXTERNALLY-MANAGED marker, so any
# bare `pip` call resolves to /ucrt64/bin/pip and refuses to
# install. (Under MINGW64 this was a latent bug — the older
# Python had no marker, so pip silently installed into the
# wrong site-packages.) Activating the venv routes pip/python
# through .venv/bin and bypasses PEP 668 (venvs aren't marked).
#
# orjson source build on UCRT64 Python 3.14 — bespoke chain
# ------------------------------------------------------------
# orjson has no PyPI wheel for the MSYS2 UCRT64 Python tag
# (mingw_x86_64_ucrt_llvm). pip falls back to source build via
# maturin. maturin's PyPI source build ALSO has no UCRT64 cp314
# wheel and ITS source build fails at metadata generation under
# cp314. So pip's default isolated build is a dead end.
#
# The escape: MSYS2 itself packages a working maturin for UCRT64
# (`mingw-w64-ucrt-x86_64-python-maturin`, built against the
# MSYS2 Python ABI). Installed via pacman above, it lives in
# /ucrt64/.../site-packages and is visible from the venv (which
# is --system-site-packages). With `--no-build-isolation`, pip
# uses THAT maturin to build orjson instead of trying to source-
# build its own.
#
# orjson version is pinned to 3.11.7 to mirror aio/build.sh:83
# on maintenance/gramps61 (Steve Youngs, commit 3d99a8d9,
# 2026-04-23). When upstream bumps the orjson pin, bump here.
#
# DELETE-WHEN: MSYS2 ships a cp314 wheel for orjson on UCRT64
# (so pip wheel-matching resolves directly). At that point this
# whole no-build-isolation dance can collapse back to a plain
# `pip install -e gramps[testing]`.
run: |
source .venv/bin/activate
# Sanity: the pacman-installed maturin is importable in the venv.
maturin --version
python -c "import maturin; print('maturin', maturin.__file__)"
# --no-build-isolation makes pip use the venv's (pacman-supplied)
# maturin instead of trying to source-build its own.
pip install --no-build-isolation --upgrade 'orjson==3.11.7'
# Smoke-test orjson now, before gramps install — a Rust ext can
# link against the wrong ABI and segfault on import. Catch that
# here, not 8 minutes into a test run.
python -c "import orjson; print(orjson.__version__); print(orjson.dumps({'x':1})); print(orjson.loads(b'{\"y\":2}'))"
pip install -r gramps-testbed/requirements-test.txt
# [testing] extras pulls in jsonschema/mock/lxml from gramps
# setup.py, which some of gramps' own *_test.py files import.
pip install -e 'gramps[testing]'
# Confirm the module that triggered the original collection
# failure now loads (gramps.gen.lib.json_utils imports orjson
# unconditionally at module load).
python -c "import gramps.gen.lib.json_utils"
- name: Compile Gramps translations
working-directory: gramps
run: |
for po in po/*.po; do
lang=$(basename "$po" .po)
dest="build/mo/$lang/LC_MESSAGES"
mkdir -p "$dest"
msgfmt "$po" -o "$dest/gramps.mo"
done
- name: Run unit tests
# Mirrors agent-work/scripts/windows/run-unit.sh. cygpath -w converts the
# POSIX results path back to a Windows path so the MSYS2-native
# Python interpreter writes to the location the next step (and
# actions/upload-artifact) can find. `source .venv/bin/activate`
# — see Install Python dependencies for the rationale.
working-directory: gramps
env:
GRAMPS_RESOURCES: .
run: |
source "$(cygpath -u "$GITHUB_WORKSPACE")/.venv/bin/activate"
ws_posix="$(cygpath -u "$GITHUB_WORKSPACE")"
mkdir -p "$ws_posix/gramps-testbed/test-results"
python -m xmlrunner discover \
-p '*_test.py' \
-o "$(cygpath -w "$ws_posix/gramps-testbed/test-results")" \
-v
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: windows-unit-test-results-${{ strategy.job-index }}
path: gramps-testbed/test-results/
- name: Publish test report
if: always()
uses: dorny/test-reporter@v1
with:
working-directory: gramps-testbed
name: '[upstream] Windows Unit Tests (${{ matrix.gramps_ref }})'
path: test-results/*.xml
reporter: java-junit
fail-on-error: false # report, don't gate — see interface-tests.yml