Skip to content

Notebook execution errors silently pass CI in three lecture repos — standardise -n -W on the sphinx-tojupyter build step #340

Description

@mmcky

Summary

Most lecture repos catch a broken notebook cell in CI, but three do not, because the ci.yml step that actually executes the notebooks — "Build Download Notebooks (sphinx-tojupyter)", jb build lectures ... --custom-builder=jupyter — is missing the -n -W flags in those three. Without -W on that step a CellExecutionError is a non-fatal warning; the later -W "Build HTML" step runs under execute_notebooks: "cache" and reuses the already-executed (possibly-errored) notebooks, so it never re-catches the failure. Net effect: a lecture whose code is broken passes CI green in those repos.

Audit (the execution step's flags)

Repo -W on the sphinx-tojupyter execution step Broken cell fails CI?
lecture-python.myst -n -W --keep-going yes
lecture-python-programming yes
lecture-python-programming.zh-cn yes
lecture-python-programming.fa yes
lecture-python.zh-cn ❌ missing no
lecture-intro.zh-cn ❌ missing no
lecture-python-intro ❌ missing no

It is not a translation-vs-source split: the programming family (source + editions) all catch it, the intro family masks on both the source and the edition, and the intermediate family catches on the source (myst) while the zh-cn edition dropped it. lecture-python-programming.fr has no custom-builder=jupyter step yet.

Evidence

Surfaced during the lecture-python.zh-cn resync wave (2026-07): a cold Build Cache run reported success while its execution-reports artifact held 19 notebook execution failures, and the resync only stayed safe because of a manual workaround — every fix was pushed as a new commit to force a cold rebuild, and the reports were read by hand. The repos that carry -W on the execution step (myst, programming) do not need that workaround; their CI goes red on a broken cell.

Fix

Add -n -W --keep-going to the "Build Download Notebooks (sphinx-tojupyter)" step in the three repos, matching the repos that already catch failures — no _config.yml change required, and the working repos prove the pattern:

- name: Build Download Notebooks (sphinx-tojupyter)
  run: |
    jb build lectures -n -W --keep-going --path-output ./ --builder=custom --custom-builder=jupyter

Repos to change: lecture-python.zh-cn, lecture-intro.zh-cn, lecture-python-intro. One caveat before flipping it on: any lecture with an intentionally-erroring cell needs a raises-exception tag first, or it will (correctly) start failing.

Secondary note — cache.yml

The weekly Build Cache job builds with the default HTML builder under execute_notebooks: "cache", which does not catch execution errors even with -W present (the HTML builder reuses the cache rather than re-executing — this is what let the 19 failures above pass). Aligning ci.yml fixes the PR gate, which is the priority; if the cache job should also gate on execution, that is a separate change (run the tojupyter execution builder in cache.yml, or set a raise-on-error config).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions