-
Notifications
You must be signed in to change notification settings - Fork 0
235 lines (200 loc) · 9.49 KB
/
Copy pathci.yml
File metadata and controls
235 lines (200 loc) · 9.49 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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
name: lint + tests (py${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Provenance tests verify that generated artifacts reference an
# ancestor source commit, which is unavailable in a depth-1 clone.
fetch-depth: 0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: requirements/test.lock
# The test suite and lint need only the scientific core; every heavy /
# optional dependency (boosting libs, torch, hmmlearn, broker SDKs, ...)
# is lazily imported with an explicit fallback or error, so it is
# intentionally not installed here. This proves the core package does not
# acquire accidental optional imports.
- name: Install core dependencies
run: python -m pip install -r requirements/test.lock
- name: Lint (ruff)
run: ruff check .
- name: Tests (pytest)
run: pytest tests/ -q --tb=short --cov=quantcortex --cov-report=term --cov-fail-under=60
notebooks:
name: notebook smoke (py3.11)
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.11"
cache: pip
cache-dependency-path: requirements/notebooks.lock
- name: Install notebook dependencies
run: python -m pip install -r requirements/notebooks.lock
- name: Build deterministic test-only fixtures
run: python tests/build_notebook_fixtures.py /tmp/quantcortex-notebook-fixtures
- name: Execute research notebooks
env:
MPLCONFIGDIR: /tmp/quantcortex-mpl
QUANTCORTEX_PRICES_CSV: /tmp/quantcortex-notebook-fixtures/prices.csv
QUANTCORTEX_OHLCV_CSV: /tmp/quantcortex-notebook-fixtures/aapl_ohlcv.csv
run: |
jupyter nbconvert --execute --ExecutePreprocessor.timeout=180 --ExecutePreprocessor.shutdown_kernel=immediate --to notebook --output-dir /tmp/quantcortex-notebook-output research/*.ipynb
- name: Verify notebook figures rendered
run: python tests/verify_notebook_outputs.py /tmp/quantcortex-notebook-output
broker-sdks:
name: optional broker SDK conformance (py3.12)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
requirements/test.lock
requirements/brokers.lock
- name: Install package with broker SDKs
run: python -m pip install -r requirements/test.lock -r requirements/brokers.lock
- name: Verify real SDK request and model contracts
env:
PYTHONPATH: .
run: |
pytest tests/test_broker_sdk_conformance.py -q
python scripts/verify_brokers.py
package:
name: build + install smoke (py${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: |
requirements/build.lock
requirements/core.lock
# Tests run from the repo root with pythonpath=["."], so also build and
# install the wheel in a clean environment. The smoke check proves the
# public import surface works and guards against accidentally packaging
# the removed market-data snapshot.
- name: Build sdist + wheel
run: |
python -m pip install -r requirements/build.lock
python -m build
- name: Install wheel into a clean venv and verify package contents
run: |
python -m venv /tmp/wheeltest
/tmp/wheeltest/bin/pip install -r requirements/core.lock
/tmp/wheeltest/bin/pip install --no-deps dist/*.whl
/tmp/wheeltest/bin/pip check
cd /tmp && /tmp/wheeltest/bin/python -c "from pathlib import Path; import quantcortex, quantcortex.portfolio.base, quantcortex.backtest.engines.vectorized, quantcortex.strategies.base_strategy; csv = Path(quantcortex.__file__).resolve().parent / 'data' / 'sample' / 'rotation_prices.csv'; assert not csv.exists(), f'restricted market-data snapshot packaged: {csv}'; print('packaged import OK; market-data snapshot absent')"
dependency-lock:
name: dependency lock drift (py3.12)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
cache: pip
- name: Install locked Poetry tooling
run: python -m pip install poetry==2.4.1 poetry-plugin-export==1.10.0
- name: Check lock and exported requirement files
run: |
poetry check
poetry export --only main --without-hashes --output /tmp/core.lock
poetry export --only main,test --without-hashes --output /tmp/test.lock
poetry export --only main,dev --without-hashes --output /tmp/notebooks.lock
poetry export --only main,test,dev --without-hashes --output /tmp/dev.lock
poetry export --only main -E brokers --without-hashes --output /tmp/brokers.lock
poetry export --only main -E brokers -E providers -E storage -E regime --without-hashes --output /tmp/runtime.lock
poetry export --only build --without-hashes --output /tmp/build.lock
diff -u requirements/core.lock /tmp/core.lock
diff -u requirements/test.lock /tmp/test.lock
diff -u requirements/notebooks.lock /tmp/notebooks.lock
diff -u requirements/dev.lock /tmp/dev.lock
diff -u requirements/brokers.lock /tmp/brokers.lock
diff -u requirements/runtime.lock /tmp/runtime.lock
diff -u requirements/build.lock /tmp/build.lock
paper-build:
name: deterministic paper build (Tectonic 0.16.9)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install Poppler and pinned Tectonic binary
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends poppler-utils
curl --fail --location --retry 3 \
'https://github.com/tectonic-typesetting/tectonic/releases/download/tectonic%400.16.9/tectonic-0.16.9-x86_64-unknown-linux-gnu.tar.gz' \
--output /tmp/tectonic.tar.gz
echo 'f3c825128095dc3399ea11c08c18035b33050a216930c295c79e8eb11bd21de4 /tmp/tectonic.tar.gz' | sha256sum --check
mkdir -p /tmp/tectonic
tar -xzf /tmp/tectonic.tar.gz -C /tmp/tectonic
echo '/tmp/tectonic' >> "$GITHUB_PATH"
- name: Load reviewed build metadata
run: |
echo "SOURCE_DATE_EPOCH=$(python -c 'import json; print(json.load(open("paper/build_manifest.json"))["source_date_epoch"])')" >> "$GITHUB_ENV"
echo "PAPER_SOURCE_COMMIT=$(python -c 'import json; print(json.load(open("paper/build_manifest.json"))["source_commit"])')" >> "$GITHUB_ENV"
- name: Rebuild and verify byte-identical paper artifacts
env:
PYTHON_BIN: python
TECTONIC_EXPECTED_VERSION: 0.16.9
TECTONIC_BUNDLE_SHA256: 6ffe055852f8faf66c0acbe1a7fb27f87b869a90bad1204f3bf4d9683f597c7c
run: |
scripts/build_paper.sh
git diff --exit-code -- \
paper/build_manifest.json \
paper/quantcortex_audit_anonymous.pdf \
paper/quantcortex_audit_anonymous.sha256 \
paper/quantcortex_audit_neurips2026.pdf \
paper/quantcortex_audit_neurips2026.sha256 \
paper/quantcortex_audit_neurips2026.sources.sha256
container:
name: container build + offline smoke
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Validate Compose configuration
env:
POSTGRES_PASSWORD: ci-only-not-a-secret
run: docker compose config --quiet
- name: Build pinned application image
run: docker build --tag quantcortex:ci .
- name: Verify read-only default command
run: docker run --rm --read-only --tmpfs /tmp quantcortex:ci
- name: Run the offline execution cycle
run: >-
docker run --rm --read-only --tmpfs /tmp quantcortex:ci
python scripts/paper_trade_cycle.py --offline