Skip to content

Commit 229ce2b

Browse files
committed
ci: replace corrupted gui-tests workflow with clean guarded GUI job
1 parent 5e2b0af commit 229ce2b

2 files changed

Lines changed: 306 additions & 52 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: gui-tests-fixed
2+
3+
on:
4+
push:
5+
paths:
6+
- 'tests/**'
7+
- '.github/workflows/gui-tests-fixed.yml'
8+
branches: ['main']
9+
pull_request:
10+
paths:
11+
- 'tests/**'
12+
- '.github/workflows/gui-tests-fixed.yml'
13+
branches: ['main']
14+
15+
jobs:
16+
gui-tests:
17+
name: GUI tests (Linux headless)
18+
runs-on: ubuntu-latest
19+
env:
20+
PYTHONPATH: ${{ github.workspace }}
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Python
26+
uses: actions/setup-python@v4
27+
with:
28+
python-version: 3.11
29+
30+
- name: Install system packages for headless Qt
31+
run: |
32+
sudo apt-get update -y
33+
sudo apt-get install -y --no-install-recommends xvfb libegl1 libegl1-mesa libegl-mesa0 libegl1-mesa-drivers libglvnd0 libglx-mesa0 libglx0 libgl1-mesa-glx \
34+
libgl1-mesa-dri libgles2-mesa libgbm1 libxrandr2 libx11-xcb1 libxcb1 libx11-6 libxkbcommon0 \
35+
libxcb-xinerama0 libxss1 fontconfig fonts-dejavu-core fonts-dejavu-extra || true
36+
sudo fc-cache -f -v || true
37+
38+
- name: Install Python dependencies (pytest-qt + PySide6)
39+
run: |
40+
python -m pip install --upgrade pip
41+
python -m pip install -r requirements-dev-minimal.txt
42+
python -m pip install pytest-qt
43+
python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7" || \
44+
(sleep 3 && python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7") || \
45+
python -m pip install --no-deps --force-reinstall "PySide6>=6.5,<7"
46+
47+
- name: Check PySide6 import and set output
48+
id: check_pyside6
49+
run: |
50+
if python -c "import importlib; importlib.import_module('PySide6')" >/dev/null 2>&1; then
51+
echo "import_ok=true" >> "$GITHUB_OUTPUT"
52+
else
53+
echo "import_ok=false" >> "$GITHUB_OUTPUT"
54+
fi
55+
56+
- name: Initialize test database for CI
57+
run: |
58+
export PYTHONPATH="${{ github.workspace }}"
59+
python tools/ci_init_db.py || true
60+
61+
- name: Run GUI-marked tests
62+
if: steps.check_pyside6.outputs.import_ok == 'true'
63+
run: |
64+
export QT_QPA_PLATFORM=offscreen
65+
xvfb-run -s '-screen 0 1280x1024x24' pytest -q -m gui
66+
67+
- name: Skip GUI tests notice
68+
if: steps.check_pyside6.outputs.import_ok != 'true'
69+
run: |
70+
echo 'PySide6 import failed — skipping GUI tests on this runner.'

.github/workflows/gui-tests.yml

Lines changed: 236 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,184 @@ on:
55
paths:
66
- 'tests/**'
77
- '.github/workflows/gui-tests.yml'
8-
branches: ['main', 'feat/**', '*']
8+
branches: ['main', 'feat/**']
9+
pull_request:
10+
paths:
11+
- 'tests/**'
12+
- '.github/workflows/gui-tests.yml'
13+
branches: ['main']
14+
15+
jobs:
16+
gui-tests:
17+
name: GUI tests (Linux headless)
18+
runs-on: ubuntu-latest
19+
env:
20+
PYTHONPATH: ${{ github.workspace }}
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Python
26+
uses: actions/setup-python@v4
27+
with:
28+
python-version: 3.11
29+
30+
- name: Install system packages for headless Qt
31+
run: |
32+
sudo apt-get update -y
33+
sudo apt-get install -y --no-install-recommends xvfb libegl1 libegl1-mesa libegl-mesa0 libegl1-mesa-drivers libglvnd0 libglx-mesa0 libglx0 libgl1-mesa-glx \
34+
libgl1-mesa-dri libgles2-mesa libgbm1 libxrandr2 libx11-xcb1 libxcb1 libx11-6 libxkbcommon0 \
35+
libxcb-xinerama0 libxss1 fontconfig fonts-dejavu-core fonts-dejavu-extra || true
36+
sudo fc-cache -f -v || true
37+
38+
- name: Install Python dependencies (pytest-qt + PySide6)
39+
run: |
40+
python -m pip install --upgrade pip
41+
python -m pip install -r requirements-dev-minimal.txt
42+
python -m pip install pytest-qt
43+
python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7" || \
44+
(sleep 3 && python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7") || \
45+
python -m pip install --no-deps --force-reinstall "PySide6>=6.5,<7"
46+
47+
- name: Check PySide6 import and set output
48+
id: check_pyside6
49+
run: |
50+
if python -c "import importlib; importlib.import_module('PySide6')" >/dev/null 2>&1; then
51+
echo "import_ok=true" >> "$GITHUB_OUTPUT"
52+
else
53+
echo "import_ok=false" >> "$GITHUB_OUTPUT"
54+
fi
55+
56+
name: gui-tests
57+
58+
on:
59+
push:
60+
paths:
61+
- 'tests/**'
62+
- '.github/workflows/gui-tests.yml'
63+
branches: ['main']
64+
pull_request:
65+
paths:
66+
- 'tests/**'
67+
- '.github/workflows/gui-tests.yml'
68+
branches: ['main']
69+
70+
jobs:
71+
gui-tests:
72+
name: GUI tests (Linux headless)
73+
runs-on: ubuntu-latest
74+
env:
75+
PYTHONPATH: ${{ github.workspace }}
76+
steps:
77+
- name: Checkout
78+
uses: actions/checkout@v4
79+
80+
- name: Set up Python
81+
uses: actions/setup-python@v4
82+
with:
83+
python-version: 3.11
84+
85+
- name: Install system packages for headless Qt
86+
run: |
87+
sudo apt-get update -y
88+
sudo apt-get install -y --no-install-recommends xvfb libegl1 libegl1-mesa libegl-mesa0 libegl1-mesa-drivers libglvnd0 libglx-mesa0 libglx0 libgl1-mesa-glx \
89+
libgl1-mesa-dri libgles2-mesa libgbm1 libxrandr2 libx11-xcb1 libxcb1 libx11-6 libxkbcommon0 \
90+
libxcb-xinerama0 libxss1 fontconfig fonts-dejavu-core fonts-dejavu-extra || true
91+
sudo fc-cache -f -v || true
92+
93+
- name: Install Python dependencies (pytest-qt + PySide6)
94+
run: |
95+
python -m pip install --upgrade pip
96+
python -m pip install -r requirements-dev-minimal.txt
97+
python -m pip install pytest-qt
98+
python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7" || \
99+
(sleep 3 && python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7") || \
100+
python -m pip install --no-deps --force-reinstall "PySide6>=6.5,<7"
101+
102+
- name: Check PySide6 import and set output
103+
id: check_pyside6
104+
run: |
105+
if python -c "import importlib; importlib.import_module('PySide6')" >/dev/null 2>&1; then
106+
echo "import_ok=true" >> "$GITHUB_OUTPUT"
107+
else
108+
echo "import_ok=false" >> "$GITHUB_OUTPUT"
109+
fi
110+
111+
- name: Initialize test database for CI
112+
run: |
113+
export PYTHONPATH="${{ github.workspace }}"
114+
python tools/ci_init_db.py || true
115+
116+
- name: Run GUI-marked tests
117+
if: steps.check_pyside6.outputs.import_ok == 'true'
118+
run: |
119+
export QT_QPA_PLATFORM=offscreen
120+
xvfb-run -s '-screen 0 1280x1024x24' pytest -q -m gui
121+
122+
- name: Skip GUI tests notice
123+
if: steps.check_pyside6.outputs.import_ok != 'true'
124+
run: |
125+
echo 'PySide6 import failed — skipping GUI tests on this runner.'
126+
v = getattr(m, '__version__', 'unknown')
127+
print('PySide6 import OK, version:', v)
128+
from PySide6 import QtCore
129+
print('QtCore QT_VERSION_STR:', QtCore.QT_VERSION_STR)
130+
except Exception:
131+
print('PySide6 import failed (sanity check):', file=sys.stderr)
132+
traceback.print_exc()
133+
# Try to provide more diagnostics: locate shiboken6 or a binary in the
134+
# PySide6 distribution and run ldd to show missing shared objects.
135+
try:
136+
shib = importlib.import_module('shiboken6')
137+
path = getattr(shib, '__file__', None)
138+
if path:
139+
print('\n== ldd for shiboken6 binary ==')
140+
import subprocess
141+
subprocess.run(['ldd', path], check=False)
142+
except Exception:
143+
pass
144+
# Do not raise here — let the separate check step decide whether to skip GUI tests.
145+
sys.exit(0)
146+
PY
147+
148+
- name: Check PySide6 import and set output
149+
id: check_pyside6
150+
run: |
151+
# Use bash to write a single output line that's safe for the Actions runner
152+
if python -c "import importlib; importlib.import_module('PySide6')" >/dev/null 2>&1; then
153+
echo "import_ok=true" >> "$GITHUB_OUTPUT"
154+
else
155+
echo "import_ok=false" >> "$GITHUB_OUTPUT"
156+
fi
157+
158+
- name: Initialize test database for CI
159+
run: |
160+
# Ensure the repo root is on PYTHONPATH so tools/ci_init_db.py can import local packages
161+
export PYTHONPATH="${{ github.workspace }}"
162+
python tools/ci_init_db.py || true
163+
164+
- name: Run GUI-marked tests
165+
if: steps.check_pyside6.outputs.import_ok == 'true'
166+
run: |
167+
# Use xvfb-run to provide an X server for Qt. Set QT_QPA_PLATFORM
168+
# to offscreen; this helps avoid platform plugin issues on headless
169+
# runners. Use a reasonably-sized screen and ensure the process
170+
# exits with the test status.
171+
export QT_QPA_PLATFORM=offscreen
172+
xvfb-run -s '-screen 0 1280x1024x24' pytest -q -m gui
173+
174+
- name: Skip GUI tests notice
175+
if: steps.check_pyside6.outputs.import_ok != 'true'
176+
run: |
177+
echo 'PySide6 import failed — skipping GUI tests on this runner.'
178+
name: gui-tests
179+
180+
on:
181+
push:
182+
paths:
183+
- 'tests/**'
184+
- '.github/workflows/gui-tests.yml'
185+
branches: ['main', 'feat/**']
9186
pull_request:
10187
paths:
11188
- 'tests/**'
@@ -57,39 +234,44 @@ jobs:
57234
(sleep 3 && python -m pip install --prefer-binary --no-cache-dir "PySide6>=6.5,<7") || \
58235
python -m pip install --no-deps --force-reinstall "PySide6>=6.5,<7"
59236
60-
- name: Sanity check PySide6 import
61-
run: |
62-
echo 'Sanity: check PySide6 can be imported and report platform info (non-fatal)'
63-
python - <<'PY'
64-
import sys, importlib, traceback
65-
try:
66-
m = importlib.import_module('PySide6')
67-
v = getattr(m, '__version__', 'unknown')
68-
print('PySide6 import OK, version:', v)
69-
from PySide6 import QtCore
70-
print('QtCore QT_VERSION_STR:', QtCore.QT_VERSION_STR)
71-
except Exception:
72-
print('PySide6 import failed (sanity check):', file=sys.stderr)
73-
traceback.print_exc()
74-
# Try to provide more diagnostics: locate shiboken6 or a binary in the
75-
# PySide6 distribution and run ldd to show missing shared objects.
76-
try:
77-
shib = importlib.import_module('shiboken6')
78-
path = getattr(shib, '__file__', None)
79-
if path:
237+
- name: Sanity check PySide6 import
238+
run: |
239+
echo 'Sanity: check PySide6 can be imported and report platform info (non-fatal)'
240+
python - <<'PY'
241+
import sys, importlib, traceback
242+
try:
243+
m = importlib.import_module('PySide6')
244+
v = getattr(m, '__version__', 'unknown')
245+
print('PySide6 import OK, version:', v)
246+
from PySide6 import QtCore
247+
print('QtCore QT_VERSION_STR:', QtCore.QT_VERSION_STR)
248+
except Exception:
249+
print('PySide6 import failed (sanity check):', file=sys.stderr)
250+
traceback.print_exc()
251+
# Try to provide more diagnostics: locate shiboken6 or a binary in the
252+
# PySide6 distribution and run ldd to show missing shared objects.
253+
try:
254+
shib = importlib.import_module('shiboken6')
255+
path = getattr(shib, '__file__', None)
256+
if path:
80257
print('\n== ldd for shiboken6 binary ==')
81258
import subprocess
82259
subprocess.run(['ldd', path], check=False)
83-
except Exception:
84-
pass
85-
# Do not raise here — let the separate check step decide whether to skip GUI tests.
86-
sys.exit(0)
87-
PY
260+
except Exception:
261+
pass
262+
# Do not raise here — let the separate check step decide whether to skip GUI tests.
263+
sys.exit(0)
264+
PY
88265
89266
- name: Check PySide6 import and set output
90267
id: check_pyside6
91268
run: |
92-
python -c "import importlib;\nimport sys;\ntry:\n importlib.import_module('PySide6');\n print('import_ok=true');\nexcept Exception:\n print('import_ok=false');\n" | while read line; do echo "${line}" >> $GITHUB_OUTPUT; done
269+
# Use bash to write a single output line that's safe for the Actions runner
270+
if python -c "import importlib; importlib.import_module('PySide6')" >/dev/null 2>&1; then
271+
echo "import_ok=true" >> "$GITHUB_OUTPUT"
272+
else
273+
echo "import_ok=false" >> "$GITHUB_OUTPUT"
274+
fi
93275
94276
- name: Initialize test database for CI
95277
run: |
@@ -118,7 +300,7 @@ on:
118300
paths:
119301
- 'tests/**'
120302
- '.github/workflows/gui-tests.yml'
121-
branches: ['main', 'feat/**', '*']
303+
branches: ['main', 'feat/**']
122304
pull_request:
123305
paths:
124306
- 'tests/**'
@@ -173,36 +355,38 @@ jobs:
173355
- name: Sanity check PySide6 import
174356
run: |
175357
echo 'Sanity: check PySide6 can be imported and report platform info (non-fatal)'
176-
python - <<'PY'
177-
import sys, importlib, traceback
178-
try:
179-
m = importlib.import_module('PySide6')
180-
v = getattr(m, '__version__', 'unknown')
181-
print('PySide6 import OK, version:', v)
182-
from PySide6 import QtCore
183-
print('QtCore QT_VERSION_STR:', QtCore.QT_VERSION_STR)
184-
except Exception:
185-
print('PySide6 import failed (sanity check):', file=sys.stderr)
186-
traceback.print_exc()
187-
# Try to provide more diagnostics: locate shiboken6 or a binary in the
188-
# PySide6 distribution and run ldd to show missing shared objects.
189-
try:
190-
shib = importlib.import_module('shiboken6')
191-
path = getattr(shib, '__file__', None)
192-
if path:
358+
python - <<'PY'
359+
import importlib, sys, traceback, subprocess
360+
try:
361+
m = importlib.import_module('PySide6')
362+
v = getattr(m, '__version__', 'unknown')
363+
print('PySide6 import OK, version:', v)
364+
from PySide6 import QtCore
365+
print('QtCore QT_VERSION_STR:', QtCore.QT_VERSION_STR)
366+
except Exception:
367+
print('PySide6 import failed (sanity check):', file=sys.stderr)
368+
traceback.print_exc()
369+
# Try to provide more diagnostics: locate shiboken6 and run ldd to show missing shared objects.
370+
try:
371+
shib = importlib.import_module('shiboken6')
372+
path = getattr(shib, '__file__', None)
373+
if path:
193374
print('\n== ldd for shiboken6 binary ==')
194-
import subprocess
195375
subprocess.run(['ldd', path], check=False)
196-
except Exception:
197-
pass
198-
# Do not raise here — let the separate check step decide whether to skip GUI tests.
199-
sys.exit(0)
200-
PY
376+
except Exception:
377+
pass
378+
# Do not raise here — let the separate check step decide whether to skip GUI tests.
379+
sys.exit(0)
380+
PY
201381

202382
- name: Check PySide6 import and set output
203383
id: check_pyside6
204384
run: |
205-
python -c "import importlib;\nimport sys;\ntry:\n importlib.import_module('PySide6');\n print('import_ok=true');\nexcept Exception:\n print('import_ok=false');\n" | while read line; do echo "${line}" >> $GITHUB_OUTPUT; done
385+
if python -c "import importlib; importlib.import_module('PySide6')" >/dev/null 2>&1; then
386+
echo "import_ok=true" >> "$GITHUB_OUTPUT"
387+
else
388+
echo "import_ok=false" >> "$GITHUB_OUTPUT"
389+
fi
206390
207391
- name: Initialize test database for CI
208392
run: |

0 commit comments

Comments
 (0)