@@ -2,7 +2,7 @@ name: Execute notebooks
22
33on :
44 schedule :
5- # Weekly: Mondays 04:00 UTC — re-executes ALL notebooks against latest releases.
5+ # Weekly: Mondays 04:00 UTC; re-executes ALL notebooks against latest releases.
66 - cron : " 0 4 * * 1"
77 pull_request :
88 branches : [main]
@@ -22,36 +22,45 @@ jobs:
2222 timeout-minutes : 60
2323 steps :
2424 - uses : actions/checkout@v5
25- with :
26- # Need full history so we can diff PR HEAD against the merge base.
27- fetch-depth : 0
2825
2926 - uses : actions/setup-python@v5
3027 with :
3128 python-version : " 3.13"
29+ cache : pip
30+ cache-dependency-path : pyproject.toml
3231
3332 - name : Cache pooch datasets
3433 uses : actions/cache@v4
3534 with :
3635 path : ~/.cache/pooch
37- key : pooch-${{ runner.os }}-${{ hashFiles('**/*.ipynb') }}
36+ # Datasets are pinned by URL inside notebook code, not by the
37+ # notebook's surrounding markdown — bump the v* suffix when an
38+ # actually-new dataset URL lands.
39+ key : pooch-${{ runner.os }}-v1
3840 restore-keys : |
3941 pooch-${{ runner.os }}-
4042
4143 - name : Install execution environment
4244 run : |
4345 pip install --upgrade pip
44- pip install -e ".[exec]" nbdime
46+ pip install -e ".[exec]"
47+
48+ - name : Detect changed notebooks (PR only)
49+ if : github.event_name == 'pull_request'
50+ id : changed
51+ uses : tj-actions/changed-files@v45
52+ with :
53+ files : |
54+ tutorials/**/*.ipynb
55+ examples/**/*.ipynb
4556
4657 - name : Determine notebooks to execute
4758 id : pick
4859 run : |
49- # On the weekly schedule and manual dispatch, run all notebooks.
50- # On PR, run only notebooks the PR touched, to keep CI fast as the
51- # gallery grows. (sklearn does the same.)
5260 if [ "${{ github.event_name }}" = "pull_request" ]; then
53- base="${{ github.event.pull_request.base.sha }}"
54- nbs=$(git diff --name-only --diff-filter=AMR "$base"...HEAD -- '*.ipynb' | grep -E '^(tutorials|examples)/' || true)
61+ nbs="${{ steps.changed.outputs.all_changed_files }}"
62+ # tj-actions emits space-separated; one-per-line for the loop below.
63+ nbs=$(printf '%s\n' $nbs)
5564 else
5665 nbs=$(find tutorials examples -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" 2>/dev/null || true)
5766 fi
7584 echo "Executing $nb"
7685 jupyter nbconvert --to notebook --execute --inplace "$nb"
7786 done <<< "${{ steps.pick.outputs.files }}"
78-
79- - name : Diff outputs against committed
80- if : steps.pick.outputs.files != ''
81- run : |
82- # If outputs drift from what's committed, fail the job. Authors are
83- # expected to commit re-executed notebooks; CI catches drift between
84- # commits (e.g., upstream lib changes).
85- if ! git diff --quiet -- '*.ipynb'; then
86- echo "Notebook outputs drifted from committed state:"
87- nbdime diff
88- exit 1
89- fi
0 commit comments