forked from igerber/diff-diff
-
Notifications
You must be signed in to change notification settings - Fork 0
161 lines (145 loc) · 6.94 KB
/
Copy pathnotebooks.yml
File metadata and controls
161 lines (145 loc) · 6.94 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
name: Tutorial Notebooks
on:
push:
branches: [main]
paths:
- 'docs/tutorials/**'
- 'diff_diff/**'
- 'pyproject.toml'
- '.github/workflows/notebooks.yml'
# the interop drift guard runs only in this workflow (balance installed)
- 'tests/test_t26_composition_drift_calibration_drift.py'
# the MMM tutorial drift guards run as a step in execute-notebooks
- 'tests/test_t29_mmm_calibration_pymc_drift.py'
- 'tests/test_t30_mmm_calibration_meridian_drift.py'
pull_request:
branches: [main]
types: [opened, synchronize, reopened, labeled, unlabeled]
paths:
- 'docs/tutorials/**'
- 'diff_diff/**'
- 'pyproject.toml'
- '.github/workflows/notebooks.yml'
# the interop drift guard runs only in this workflow (balance installed)
- 'tests/test_t26_composition_drift_calibration_drift.py'
# the MMM tutorial drift guards run as a step in execute-notebooks
- 'tests/test_t29_mmm_calibration_pymc_drift.py'
- 'tests/test_t30_mmm_calibration_meridian_drift.py'
schedule:
# Weekly Sunday 6am UTC — smoke test that notebooks still execute cleanly
- cron: '0 6 * * 0'
permissions:
contents: read
jobs:
execute-notebooks:
name: Execute tutorial notebooks
# Skip unrelated label churn: a non-ready-for-ci label add/remove won't run this job.
if: >-
github.event_name != 'pull_request'
|| (contains(github.event.pull_request.labels.*.name, 'ready-for-ci')
&& (github.event.action != 'labeled' && github.event.action != 'unlabeled'
|| github.event.label.name == 'ready-for-ci'))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.11'
- name: Install dependencies
# Keep in sync with pyproject.toml [project.dependencies] and [project.optional-dependencies.dev]
run: |
pip install numpy pandas scipy matplotlib nbmake pytest ipykernel
# Add repo root to Python path so Jupyter kernels can import diff_diff
# (pip install -e . requires the Rust/maturin toolchain; .pth avoids that)
python -c "import site; print(site.getsitepackages()[0])" | xargs -I{} sh -c 'echo "$PWD" > {}/diff_diff_dev.pth'
- name: Execute notebooks
env:
DIFF_DIFF_BACKEND: python
run: |
pytest --nbmake docs/tutorials/ \
--nbmake-timeout=600 \
--ignore=docs/tutorials/06_power_analysis.ipynb \
--ignore=docs/tutorials/10_trop.ipynb \
--ignore=docs/tutorials/26_composition_drift_calibration.ipynb \
--ignore=docs/tutorials/29_mmm_calibration_pymc.ipynb \
--ignore=docs/tutorials/30_mmm_calibration_meridian.ipynb \
-v \
--tb=short
# Excluded notebooks (too slow for pure-Python CI without Rust backend):
# 06_power_analysis — SyntheticDiD simulate_power Monte Carlo (>600s)
# 10_trop — LOOCV grid search (>600s)
# Excluded notebooks (external interop dependency):
# 26_composition_drift_calibration — requires the balance package;
# runs in the isolated interop-notebooks job below so this job's
# minimal env keeps enforcing that tutorials add no dependencies
# 29/30_mmm_calibration_* — require pymc-marketing / google-meridian,
# which cannot even share ONE environment (arviz conflict) and run
# multi-minute MCMC; executed locally with committed outputs. Their
# drift guards run in the next step, and the mmm-interop.yml workflow
# smoke-tests the exporters against the real frameworks (no sampling).
- name: Run MMM tutorial drift guards
# The MMM notebooks are excluded from execution above, so their committed
# surface is protected here: DGP/sampler/integration needles + diff-diff
# recomputation of the DiD-side numbers (no MMM frameworks needed).
env:
DIFF_DIFF_BACKEND: python
run: |
pytest tests/test_t29_mmm_calibration_pymc_drift.py \
tests/test_t30_mmm_calibration_meridian_drift.py -v --tb=short
- name: Upload failed notebook outputs
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: failed-notebook-outputs
path: docs/tutorials/*.ipynb
retention-days: 7
interop-notebooks:
name: Execute balance-interop notebook
# Same ready-for-ci label gate as execute-notebooks (keep in sync).
if: >-
github.event_name != 'pull_request'
|| (contains(github.event.pull_request.labels.*.name, 'ready-for-ci')
&& (github.event.action != 'labeled' && github.event.action != 'unlabeled'
|| github.event.label.name == 'ready-for-ci'))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
# 3.12+: balance's legacy numpy<2 / scipy<1.14 / scikit-learn<1.4
# pins apply only to python < 3.12
python-version: '3.12'
- name: Install dependencies
# balance is a tutorial-only dependency: it is installed ONLY in this
# isolated job, never in package requirements or the main notebooks
# job. The weekly cron on this workflow doubles as a cross-package
# integration smoke of diff-diff HEAD against latest PyPI balance.
run: |
pip install numpy pandas scipy matplotlib nbmake pytest ipykernel "balance>=0.21"
# Add repo root to Python path so Jupyter kernels can import diff_diff
# (pip install -e . requires the Rust/maturin toolchain; .pth avoids that)
python -c "import site; print(site.getsitepackages()[0])" | xargs -I{} sh -c 'echo "$PWD" > {}/diff_diff_dev.pth'
- name: Execute interop notebook
env:
DIFF_DIFF_BACKEND: python
run: |
pytest --nbmake docs/tutorials/26_composition_drift_calibration.ipynb \
--nbmake-timeout=600 \
-v \
--tb=short
- name: Run interop drift guard
# balance is present only in this job, so this is the drift test's
# CI home (it importorskips balance everywhere else).
env:
DIFF_DIFF_BACKEND: python
run: |
pytest tests/test_t26_composition_drift_calibration_drift.py -v --tb=short
- name: Upload failed notebook outputs
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: failed-interop-notebook-outputs
path: docs/tutorials/26_composition_drift_calibration.ipynb
retention-days: 7