-
Notifications
You must be signed in to change notification settings - Fork 28
219 lines (186 loc) · 8.48 KB
/
Copy pathci.yml
File metadata and controls
219 lines (186 loc) · 8.48 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
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Install core package
run: pip install -e .
- name: Install test + integration dependencies
run: |
pip install pytest pytest-cov langgraph langchain-core fastapi pydantic uvicorn python-multipart httpx opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
pip install claude-agent-sdk vercel-ai-sdk || echo "Optional SDK install failed (platform-specific), tests will skip"
# Build the canonical OpenClaw plugin TS so the
# ``test_openclaw_artifact_sync`` invariant test (compares
# ``plugins/sponsio-openclaw/dist/`` byte-for-byte against the
# wheel-bundled ``sponsio/plugin/openclaw_artifact/dist/``) has
# both copies on disk. ``npm ci`` pins to the exact lockfile
# versions that produced the committed bundled artifact, so
# bytes match.
- name: Set up Node.js (for OpenClaw plugin build)
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "22"
- name: Build OpenClaw plugin TS artifact
working-directory: plugins/sponsio-openclaw
run: npm ci && npm run build
- name: Run tests
run: pytest --cov=sponsio --cov-report=term-missing -v
build-smoke-test:
name: Build wheel + install smoke test
runs-on: ubuntu-latest
# Stand-in for the TestPyPI gate we used to keep in publish.yml.
# `twine check` catches the same metadata regressions PyPI rejects on
# upload (long-description content-type, classifier validity, etc.);
# the install + `sponsio --version`/--help run catches packaging
# errors (missing modules, broken entry point) that would brick the
# wheel before we burn an immutable PyPI version number.
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
cache: pip
- name: Build sdist + wheel
run: |
pip install build twine
python -m build
python -m twine check dist/*
- name: Install built wheel + verify CLI
# Install the freshly-built wheel into a clean venv (not editable)
# so this catches packaging issues that `pip install -e .` skips —
# e.g. missing files in `tool.setuptools.package-data`.
run: |
python -m venv /tmp/smoke-venv
/tmp/smoke-venv/bin/pip install dist/*.whl
/tmp/smoke-venv/bin/sponsio --version
/tmp/smoke-venv/bin/sponsio --help
# --version/--help are click-level and don't import yaml, so
# they missed #61 (pyyaml mis-filed as optional). Assert the
# core deps resolve, then run a command that actually reads the
# bundled YAML so a missing core dependency fails the build.
/tmp/smoke-venv/bin/python -c "import yaml"
/tmp/smoke-venv/bin/sponsio packs
test-typescript:
name: Test (TypeScript — native)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "22"
- name: Install + Build TS workspace
working-directory: ts
# Use the root ``build`` script (which already passes
# ``--if-present`` to ``npm run build --workspaces``) so the
# example packages — which intentionally have no ``build``
# script — don't fail the matrix.
run: npm install && npm run build
- name: Run cross-language tests
working-directory: ts/packages/sdk
run: node dist/__tests__/core.test.js
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
cache: pip
- name: Install ruff and dependencies
# Ruff `format` rules change between minor versions; pin to the
# same version pyproject.toml's `dev` extra declares so CI and
# local always agree.
run: pip install -e ".[dev]"
- name: Check formatting
run: ruff format --check sponsio/ tests/ scripts/
- name: Check linting
run: ruff check sponsio/ tests/ scripts/
- name: Check README/QUICKSTART command sync
run: |
# Canonical user-journey commands that must appear in user-facing
# docs. Prevents CLI renames/drift from silently desyncing the
# onboarding paths. README.md (the 60-second version) covers
# install + entry point; QUICKSTART.md (the full walkthrough)
# additionally covers report and the observe→enforce flip.
readme_required=(
"pip install sponsio"
"sponsio init"
)
quickstart_required=(
"pip install sponsio"
"sponsio init"
"sponsio report"
"SPONSIO_MODE=enforce"
)
exit_code=0
for cmd in "${readme_required[@]}"; do
if ! grep -qF "$cmd" README.md; then
echo "::error file=README.md::Canonical command missing: $cmd"
exit_code=1
fi
done
for cmd in "${quickstart_required[@]}"; do
if ! grep -qF "$cmd" QUICKSTART.md; then
echo "::error file=QUICKSTART.md::Canonical command missing: $cmd"
exit_code=1
fi
done
exit $exit_code
- name: Check README header assets intact
run: |
# WYSIWYG markdown editors strip key README assets:
# - banner image markdown at top
# - architecture diagram reference in "How Sponsio works"
# - <p align="center"> wrappers around badges + paste-prompt buttons
# Catch any of these going missing before push hits main.
fail=0
# Banner image markdown reference at top of README. Accepts both
# the relative path (works on GitHub) and the absolute raw.gh
# URL (also needed for PyPI README rendering, since PyPI does not
# resolve relative paths).
if ! grep -qE '!\[Sponsio\]\((assets/|https://raw\.githubusercontent\.com/[^)]+/assets/)readme-banner\.png\)' README.md; then
echo "::error file=README.md::Banner image markdown missing. Re-add at the top of the file (relative 'assets/readme-banner.png' or absolute 'https://raw.githubusercontent.com/.../assets/readme-banner.png')."
fail=1
fi
# Architecture diagram reference (anywhere in README)
if ! grep -qE 'assets/sponsio-architecture\.png' README.md; then
echo "::error file=README.md::Architecture diagram reference missing - 'assets/sponsio-architecture.png' was stripped. Re-add inside the 'How Sponsio works' section."
fail=1
fi
# Centered HTML wrappers (utility badges + social badges + architecture diagram + paste-prompt buttons → 3 minimum)
centered=$(grep -c '^<p align="center">' README.md || echo 0)
min_centered=3
if [ "$centered" -lt "$min_centered" ]; then
echo "::error file=README.md::Expected at least ${min_centered} <p align=\"center\"> blocks, found ${centered}. WYSIWYG editor likely stripped them."
fail=1
fi
# Asset files actually exist in the repo
for f in assets/readme-banner.png assets/sponsio-architecture.png; do
if [ ! -f "$f" ]; then
echo "::error file=${f}::Image asset missing from repo."
fail=1
fi
done
[ "$fail" -eq 0 ]