Skip to content

Commit f81cce2

Browse files
committed
ci: add installer smoke-test workflow for all platforms
New Installers workflow runs only when install.sh or install.ps1 changes (plus manual dispatch). On ubuntu/macos/windows it runs the matching installer against the latest release, then asserts the binary starts (--help shows a real version) and that an MCP stub session returns the expected tools — catching the class of native-image regression that let 0.3.2 ship a binary that started but crashed on first real use.
1 parent 02a54c2 commit f81cce2

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

.github/workflows/installers.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Installers
2+
3+
# Smoke-tests the install scripts on every supported platform.
4+
# Runs ONLY when an install script changes — installing from the latest
5+
# published release validates both the script and the release assets.
6+
on:
7+
push:
8+
paths:
9+
- install.sh
10+
- install.ps1
11+
pull_request:
12+
paths:
13+
- install.sh
14+
- install.ps1
15+
workflow_dispatch:
16+
17+
jobs:
18+
install:
19+
name: ${{ matrix.label }}
20+
runs-on: ${{ matrix.os }}
21+
timeout-minutes: 15
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
include:
26+
- os: ubuntu-latest
27+
label: linux-amd64
28+
- os: macos-latest
29+
label: macos-arm64
30+
- os: windows-latest
31+
label: windows-amd64
32+
# Relative path keeps it shell-agnostic (no Windows backslash vs. bash issues).
33+
env:
34+
INSTALL_DIR: qtsurfer-mcp-install
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- name: Run install.sh (Linux · macOS)
39+
if: runner.os != 'Windows'
40+
shell: bash
41+
run: bash ./install.sh
42+
43+
- name: Run install.ps1 (Windows)
44+
if: runner.os == 'Windows'
45+
shell: pwsh
46+
run: ./install.ps1
47+
48+
- name: Verify binary starts and MCP stub session works
49+
shell: bash
50+
run: |
51+
BIN="$INSTALL_DIR/qtsurfer-mcp"
52+
[ -f "$BIN.exe" ] && BIN="$BIN.exe"
53+
[ -x "$BIN" ] || { echo "::error::installed binary not found at $BIN"; exit 1; }
54+
55+
echo "== --help =="
56+
"$BIN" --help | tee help.txt
57+
grep -Eq 'qtsurfer-mcp [0-9]+\.[0-9]+\.[0-9]+' help.txt \
58+
|| { echo "::error::version banner missing or shows 'dev'"; exit 1; }
59+
60+
# Exercise the MCP server end-to-end without a backend. This is the
61+
# real check: a native image missing reflection/serialization metadata
62+
# starts fine but crashes here (UnsupportedFeatureError / HTTP 0).
63+
echo "== MCP stub session (initialize + tools/list) =="
64+
init='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"ci","version":"0"}}}'
65+
inited='{"jsonrpc":"2.0","method":"notifications/initialized"}'
66+
list='{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
67+
{ printf '%s\n' "$init" "$inited" "$list"; sleep 5; } \
68+
| "$BIN" --stub > mcp.out 2> mcp.err || true
69+
cat mcp.out
70+
grep -q '"list_exchanges"' mcp.out \
71+
|| { echo "::error::tools/list did not return the expected tools"; cat mcp.err; exit 1; }
72+
grep -q '"submit_backtest"' mcp.out \
73+
|| { echo "::error::tools/list incomplete"; cat mcp.err; exit 1; }
74+
echo "OK: installer + binary + MCP stub all good on ${{ matrix.label }}"

0 commit comments

Comments
 (0)