forked from chigwell/telegram-mcp
-
Notifications
You must be signed in to change notification settings - Fork 0
211 lines (184 loc) · 8.18 KB
/
Copy pathtests.yml
File metadata and controls
211 lines (184 loc) · 8.18 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
name: Tests & Coverage
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
test:
name: Pytest With Coverage
runs-on: ubuntu-latest
# A hung decoder would otherwise hold a runner for GitHub's 6-hour default.
# The guarded runner below bounds the run itself; this bounds the job around it.
timeout-minutes: 20
# The floor and the ceiling. pyproject declares >=3.11 and classifies up to
# 3.13; running both is what turns that claim into evidence.
strategy:
fail-fast: false
matrix:
python-version: ['3.11', '3.13']
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v5
# --cov-fail-under=0 overrides the floor in pyproject FOR THIS JOB. The
# floor is a claim about the project and no single runner can execute the
# whole project: telegram_mcp.visual.capture is Win32 and cannot run here.
# The `coverage` job applies the floor once, to the combined data.
- name: Run tests with coverage
env:
TELEGRAM_API_ID: "12345"
TELEGRAM_API_HASH: "dummy_hash"
TELEGRAM_SESSION_NAME: "test_session"
COVERAGE_FILE: .coverage.linux-py${{ matrix.python-version }}
run: >
uv run python scripts/run_tests_guarded.py --
--cov --cov-report=term-missing --cov-fail-under=0
- name: Upload this leg's coverage data
uses: actions/upload-artifact@v4
with:
# Must be unique per matrix leg: upload-artifact@v4 refuses a second
# upload to the same name, so a static name fails the 3.13 job.
name: coverage-data-linux-py${{ matrix.python-version }}
path: .coverage.linux-py${{ matrix.python-version }}
# The data file starts with a dot, and v4 drops hidden files unless
# told otherwise - which would leave the combine step short a leg.
include-hidden-files: true
# The job above installs the base package, where the .tgs tests skip - which is
# also the proof that the base install works without the optional renderer. This
# job installs the extra so that code path is actually exercised somewhere.
# Run on Windows as well as Linux: rlottie-python is a NATIVE optional
# dependency, so "it installs and renders" is a per-platform fact, not a
# per-project one — and the visual half of this fork is Windows-first, which is
# exactly where an rlottie wheel failing to build would go unnoticed otherwise.
lottie:
name: Pytest With Lottie Renderer (${{ matrix.os }})
runs-on: ${{ matrix.os }}
# The native rlottie decoder is exactly the kind of child that wedges
# without exiting, so this job needs the ceiling more than the others.
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Fail if the lottie extra did not install
run: >
uv run --extra lottie python -c
"from telegram_mcp.visual.frames import lottie_available;
assert lottie_available(), 'rlottie-python is missing: the .tgs tests would silently skip'"
# The whole suite, not a file list. Selecting by path re-creates the exact
# hole the guard above exists to close: a renderer-gated test added to any
# unlisted file would run with the renderer nowhere and skip silently
# everywhere. Running everything under the extra cannot drift.
# Measured here too. This is the only job that runs on Windows, so it is
# the only place the Win32 capture module executes at all - and the only
# place the .tgs renderer does. Both belong in the combined total.
- name: Run the whole suite with the renderer available
env:
TELEGRAM_API_ID: "12345"
TELEGRAM_API_HASH: "dummy_hash"
TELEGRAM_SESSION_NAME: "test_session"
COVERAGE_FILE: .coverage.lottie-${{ matrix.os }}
run: >
uv run --extra lottie python scripts/run_tests_guarded.py --
-q --cov --cov-report= --cov-fail-under=0
- name: Upload this leg's coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-data-lottie-${{ matrix.os }}
path: .coverage.lottie-${{ matrix.os }}
include-hidden-files: true
# The launchers are PowerShell and Windows-only, and nothing ran their tests
# until now - which is how `tests/test_update_menu.ps1` was able to outlive the
# script it tested. Discovery, not a list, for exactly that reason: a suite
# added here is picked up, and one whose subject is deleted fails loudly.
launchers:
name: PowerShell Launcher Tests
runs-on: windows-latest
timeout-minutes: 10
steps:
- name: Check out repository code
uses: actions/checkout@v4
# test_launchers.ps1 exercises the launcher's Python tee wrapper, and falls
# back to `python` on PATH when .venv is absent - which it is, on a runner.
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Run every PowerShell suite
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$suites = @(Get-ChildItem -Path tests -Filter 'test_*.ps1' -File | Sort-Object Name)
if ($suites.Count -eq 0) { throw 'No PowerShell suites found under tests/ - discovery is broken.' }
Write-Host "Found $($suites.Count) suite(s): $(($suites.Name) -join ', ')"
$failed = @()
foreach ($suite in $suites) {
Write-Host "::group::$($suite.Name)"
& pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File $suite.FullName
$code = $LASTEXITCODE
Write-Host '::endgroup::'
if ($code -ne 0) { $failed += "$($suite.Name) (exit $code)" }
}
if ($failed.Count -gt 0) { throw "PowerShell suites failed: $($failed -join '; ')" }
Write-Host "All $($suites.Count) PowerShell suite(s) passed."
# The floor, applied once, to everything that ran.
#
# Neither runner can execute the whole project. telegram_mcp.visual.capture
# is Win32 (PrintWindow) and 110 of its lines cannot run on Linux; the POSIX
# branches of handles.py, owner_only.py and singleton.py cannot run on
# Windows. Measured on the first CI runs this repository ever had, the same
# commit read 85.49% on windows-latest and 81.90% on ubuntu-latest - so
# gating either number alone gates the runner, not the suite.
#
# No separate 'did every leg upload' check: a missing leg takes its platform's
# exclusive modules down to near zero, which puts the total under the floor
# and fails right here. The floor is its own guard.
coverage:
name: Combined Coverage Gate
runs-on: ubuntu-latest
needs: [test, lottie]
timeout-minutes: 10
steps:
# `coverage report` reads the source to say which lines were missed, so
# the checkout is load-bearing here, not habit.
- name: Check out repository code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Collect every leg's coverage data
uses: actions/download-artifact@v4
with:
pattern: coverage-data-*
path: coverage-data
merge-multiple: true
- name: Combine the platforms and apply the floor
run: |
uv run python -m coverage combine coverage-data
uv run python -m coverage report
uv run python -m coverage xml
- name: Upload the combined report
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-xml-combined
path: coverage.xml