@@ -29,13 +29,19 @@ jobs:
2929 strategy :
3030 fail-fast : false
3131 matrix :
32- # os: [ubuntu-latest, macos-latest, windows-latest]
33- # python-version: ["3.9", "3.10", "3.11", "3.12", "pypy3.9", "pypy3.10"]
34- os : [ubuntu-latest]
35- python-version : ["3.9", "3.14", "3.14t"]
32+ include :
33+ - os : ubuntu-latest
34+ python-version : " 3.9"
35+ - os : ubuntu-latest
36+ python-version : " 3.14"
37+ - os : ubuntu-latest
38+ python-version : " 3.14t"
39+ - os : macos-latest
40+ python-version : " 3.9"
3641
3742 steps :
3843 - name : Harden the runner (Audit all outbound calls)
44+ if : matrix.os != 'windows-latest'
3945 uses : step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
4046 with :
4147 egress-policy : audit
@@ -50,37 +56,30 @@ jobs:
5056 python-version : ${{ matrix.python-version }}
5157 activate-environment : true
5258
53- - name : Install system dependencies for GUI testing
59+ - name : Install system dependencies for GUI testing on linux
60+ if : matrix.os == 'ubuntu-latest'
5461 run : |
5562 sudo apt-get update
56- # Only install system Tcl/Tk for Python < 3.13 (newer versions bundle their own)
57- if [[ "${{ matrix.python-version }}" < "3.13" ]]; then
58- echo "Installing system Tcl/Tk 8.6 for Python ${{ matrix.python-version }}"
59- sudo apt-get install -y python3-tk tcl8.6 tk8.6 libtcl8.6 libtk8.6
60- else
61- echo "Python ${{ matrix.python-version }} uses bundled Tcl/Tk, skipping system packages"
62- # Only install tools, not Tcl/Tk libraries
63- sudo apt-get install -y scrot xdotool x11-utils gnome-screenshot
64- fi
65- python3 --version && python3 -c "import tkinter; print(tkinter.TclVersion, tkinter.TkVersion)"
63+ sudo apt-get install -y xvfb python3-tk tcl tk tcl-dev tk-dev libx11-6 libxrender1 libxext6 libsm6 scrot xdotool x11-utils
64+ python3 --version
65+ python3 -c "import tkinter; print('Tk OK:', tkinter.TclVersion, tkinter.TkVersion)"
6666
67- - name : Ensure Tcl/Tk search paths
67+ - name : Install system dependencies for GUI testing on macOS
68+ if : matrix.os == 'macos-latest'
6869 run : |
69- # Only set Tcl/Tk paths for Python < 3.13
70- if [[ "${{ matrix.python-version }}" < "3.13" ]]; then
71- echo "Setting Tcl/Tk paths for Python ${{ matrix.python-version }}"
72- echo "TCL_LIBRARY=/usr/share/tcltk/tcl8.6" >> $GITHUB_ENV
73- echo "TK_LIBRARY=/usr/share/tcltk/tk8.6" >> $GITHUB_ENV
74- else
75- echo "Python ${{ matrix.python-version }} uses bundled Tcl/Tk, no custom paths needed"
76- fi
70+ brew install tcl-tk
71+ echo "LDFLAGS=-L$(brew --prefix tcl-tk)/lib" >> $GITHUB_ENV
72+ echo "CPPFLAGS=-I$(brew --prefix tcl-tk)/include" >> $GITHUB_ENV
73+ echo "PKG_CONFIG_PATH=$(brew --prefix tcl-tk)/lib/pkgconfig" >> $GITHUB_ENV
74+ python3 -c "import tkinter; print('Tk OK:', tkinter.TclVersion, tkinter.TkVersion)"
7775
7876 - name : Install dependencies and application
7977 # without --editable, the coverage report is not generated correctly
8078 run : |
8179 uv pip install --editable .[dev,ci_headless_tests]
8280
8381 - name : Download ArduCopter SITL (if available)
82+ if : matrix.os == 'ubuntu-latest'
8483 run : |
8584 # Create cache key based on current quarter (YYYY-Q)
8685 CURRENT_YEAR=$(date +%Y)
@@ -132,21 +131,19 @@ jobs:
132131 continue-on-error : false
133132 run : |
134133 export LIBGL_ALWAYS_SOFTWARE=1
135- export DISPLAY=:99
136- # disable X authentication
137- export XAUTHORITY=/dev/null
138- # disable access control restrictions
139- Xvfb :99 -screen 0 1024x768x16 -ac &
140- # ensure Xvfb is fully started before running tests
141- sleep 2
142- if [ "$SITL_AVAILABLE" = "true" ]; then
143- echo "Running tests with SITL support"
144- uv run pytest --cov=ardupilot_methodic_configurator --cov-report=xml:tests/coverage.xml --md=tests/results-${{ matrix.python-version }}.md --junit-xml=tests/results-junit.xml -m "sitl or not sitl"
134+
135+ if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then
136+ export DISPLAY=:99
137+ export XAUTHORITY=/dev/null
138+ Xvfb :99 -screen 0 1024x768x16 -ac &
139+ sleep 2
140+ FINAL_MARKER="sitl or not sitl"
145141 else
146- echo "Running tests without SITL (mocked tests only)"
147- uv run pytest --cov=ardupilot_methodic_configurator --cov-report=xml:tests/coverage.xml --md=tests/results-${{ matrix.python-version }}.md --junit-xml=tests/results-junit.xml -m "not sitl"
142+ FINAL_MARKER="not gui and not acceptance"
148143 fi
149144
145+ echo "Running tests with markers: $FINAL_MARKER"
146+ uv run pytest --cov=ardupilot_methodic_configurator --cov-report=xml:tests/coverage.xml --md=tests/results-${{ matrix.python-version }}.md --junit-xml=tests/results-junit.xml -m "$FINAL_MARKER"
150147 - name : Fix coverage paths
151148 run : |
152149 sed -i 's|<package name="." |<package name="ardupilot_methodic_configurator" |' tests/coverage.xml
@@ -160,13 +157,13 @@ jobs:
160157 if : ${{ always() }}
161158
162159 - name : Upload coverage xml report
160+ # Use always() to always run this step to publish test results when there are test failures
161+ if : matrix.os == 'ubuntu-latest' && always()
163162 uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
164163 with :
165164 name : coverage-${{ matrix.python-version }}-xml
166165 path : tests/*.xml
167166 retention-days : 1
168- # Use always() to always run this step to publish test results when there are test failures
169- if : ${{ always() }}
170167
171168 - name : Upload coverage report
172169 uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -175,8 +172,6 @@ jobs:
175172 path : .coverage
176173 include-hidden-files : true
177174 retention-days : 1
178- # Use always() to always run this step to publish test results when there are test failures
179- if : ${{ always() }}
180175
181176 upload_coverage_to_coveralls :
182177 if : (github.event_name == 'push' && github.ref == 'refs/heads/master') && (success() || failure())
0 commit comments