-
Notifications
You must be signed in to change notification settings - Fork 31
219 lines (184 loc) · 7.24 KB
/
Copy pathci.yml
File metadata and controls
219 lines (184 loc) · 7.24 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, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
permissions:
contents: read
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install lint dependencies
run: |
python -m pip install --upgrade pip
pip install ruff
- name: Ruff lint (zero-error policy)
run: ruff check effgen/
types:
name: Public-surface types (advisory)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install type-check dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install "mypy>=1.7.0"
# effGen ships py.typed; this lane type-checks the public surface so the
# annotations users see stay accurate. It is advisory (allowed to warn) —
# the hard gate that public stubs resolve lives in the unit tests.
- name: mypy (public API surface)
run: bash scripts/check_public_types.sh
test-unit:
name: Unit Tests (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}
restore-keys: ${{ runner.os }}-pip-${{ matrix.python-version }}-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Verify critical imports
run: |
python -c "
import effgen; print(f'effgen {effgen.__version__}')
from effgen.guardrails import GuardrailChain
from effgen.rag import DocumentIngester
from effgen.eval import AgentEvaluator
from effgen.domains import TechDomain
from effgen.cache import PromptCache
from effgen.client import EffGenClient
print('All imports OK')
"
- name: Run unit + benchmark tests
# Coverage is opt-in (default config has no --cov, so collect-only and
# parallel runs don't corrupt the data file); this job enables it
# explicitly. Deselect the lanes that belong to dedicated jobs below.
run: |
pytest tests/unit/ tests/benchmarks/ -v \
--cov=effgen --cov-report=xml --cov-report=term-missing \
-m "not gpu and not api and not live and not docker and not expensive" \
--tb=short --no-header
- name: Upload coverage
if: matrix.python-version == '3.11'
uses: actions/upload-artifact@v4
with:
name: coverage-unit
path: coverage.xml
test-integration:
name: Integration Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run integration tests (no GPU, no API)
run: |
pytest tests/integration/ -v -m "not gpu and not api and not live and not docker" \
--ignore=tests/e2e \
--tb=short --no-header
test-order-independence:
# The per-directory jobs above each run in their own process, which cannot
# catch cross-directory test pollution (a test that only fails depending on
# what ran before it — e.g. a teardown that empties a global registry, or an
# import that mutates sys.path). This job runs the WHOLE offline suite in a
# single process, then again in a randomized order, so such isolation
# regressions fail CI instead of flaking a future release run.
name: Order-independence (single-process offline suite)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
# This lane runs the WHOLE tests/ tree in one process, so it needs the
# optional-feature deps those suites exercise (docs/image/audio/maps/rss/
# youtube/sql/jupyter/lambda/extra-provider SDKs/server metrics). They are
# CPU-friendly, pure-Python extras — the GPU-only stacks (vllm/local) and
# heavy vector DBs stay out. Tests whose backend needs a *system* library
# (zbar, tesseract, ffmpeg) skip cleanly via importorskip when it's absent.
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,jupyter,api,lambda,translate,audio,prompts-data,youtube,tools-docs,rss,geo,server,tools,qr]"
- name: Full offline suite, single process (fixed order)
# No provider keys are set in CI, so the key-gated live tests skip.
run: |
pytest tests \
-m "not gpu and not api and not live and not docker and not expensive" \
--tb=short --no-header -q
- name: Full offline suite, single process (randomized order)
# Drop the default `-p no:randomly` (see pyproject addopts) so the run
# shuffles; the printed seed reproduces any failing order exactly.
run: |
pytest tests \
-m "not gpu and not api and not live and not docker and not expensive" \
-o "addopts=" -p randomly --tb=short -q
security:
name: Security Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install security tools
run: |
python -m pip install --upgrade pip
pip install bandit safety
pip install -e ".[dev]"
- name: Run bandit security linter
run: bandit -r effgen/ -c pyproject.toml --exit-zero -f json -o bandit-report.json
- name: Run security test suite (-m security)
# The `security` marker is applied by directory (tests/security/) in
# tests/conftest.py. Docker/gitleaks-gated cases skip with clear reasons
# on this runner; the full CI image runs them as required checks.
run: |
pytest -m "security and not docker and not live" \
--tb=short --no-header
- name: Check dependency vulnerabilities
run: pip install -r requirements.txt && safety check --output json || true
- name: Upload security reports
uses: actions/upload-artifact@v4
with:
name: security-reports
path: bandit-report.json