Skip to content

CI: gate notebook execution errors on the sphinx-tojupyter step - #809

Merged
mmcky merged 2 commits into
mainfrom
ci/gate-notebook-execution-errors
Jul 30, 2026
Merged

CI: gate notebook execution errors on the sphinx-tojupyter step#809
mmcky merged 2 commits into
mainfrom
ci/gate-notebook-execution-errors

Conversation

@mmcky

@mmcky mmcky commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Closes the lecture-python-intro half of QuantEcon/meta#340.

The problem

Two independent defects meant a broken notebook could pass CI green in this repo.

1. The gate was on no step that could fail. lectures/_config.yml sets execute_notebooks: "cache", so only the first jb build in the workflow actually executes notebooks — every later builder reads the cache. The first build here is "Build PDF from LaTeX", and it ran with -n --keep-going and no -W, so a CellExecutionError was a non-fatal warning.

2. That step's exit code was cp's, not jb build's. It runs three commands under shell: bash -l {0}. GitHub only injects -eo pipefail for the bare shell: bash shorthand; an explicit custom shell spec gets neither -e nor -o pipefail. So a failing jb build was followed by mkdir and cp, and the step exited with cp's status. --keep-going makes this worse rather than better, because it forces Sphinx to emit output despite the errors, guaranteeing the PDF exists for cp to succeed on.

Either fix alone is insufficient. Both are applied, to one step.

The change

set -eo pipefail and -W on the "Build PDF from LaTeX" step — the first jb build, and therefore the one that executes. No other step is touched and no _config.yml change is needed.

On why it is this step and not the notebooks step: the first revision of this PR gated Build Download Notebooks (sphinx-tojupyter), copying the equivalent change already merged in lecture-python.zh-cn. That was wrong here. It is correct there because that repo's LaTeX step is commented out, which makes tojupyter its first jb build. The portable rule is "gate the first jb build", not "gate a particular step name" — and which step that is varies across the six repos in QuantEcon/meta#340. Caught by @copilot's review and by @mmcky.

Checks done before making the change

  • No raises-exception tags anywhere in lectures/, and no intentionally-erroring cells — nothing is relying on an error being tolerated.
  • All 47 published lecture pages on intro.quantecon.org were scanned for execution-error markers (output_error, tracebacks, ANSI red). Zero hits — the lectures execute cleanly today.
  • suppress_warnings: [mystnb.unknown_mime_type, myst.domains] is already configured, so the two known-noisy warning classes will not be promoted by -W.

What CI on this PR is testing

This step has never been able to fail, so this PR is the first real exercise of it. The scan above covers execution errors on published content; -W also promotes Sphinx warnings to errors, and the LaTeX builder emits warnings the HTML builder does not — that class has been invisible here.

If CI goes red, it has found something genuine that was previously silent, and that should be fixed before this merges rather than the flags being softened.

Refs QuantEcon/meta#340

🤖 Generated with Claude Code

The "Build Download Notebooks (sphinx-tojupyter)" step is the one that
actually executes the notebooks, and in this repo it could not fail:

- it carried no `-n -W`, so a CellExecutionError was a non-fatal warning
- its exit code was `cp`'s, not `jb build`'s

The second point is the less obvious one. The step runs three commands
under `shell: bash -l {0}`. GitHub only injects `-eo pipefail` for the
bare `shell: bash` shorthand; an explicit custom shell spec gets neither
`-e` nor `-o pipefail`. So a failing `jb build` was followed by `mkdir`
and `cp`, and the step exited with `cp`'s status. `--keep-going` makes
that worse rather than better, since it forces Sphinx to emit output
despite the errors, guaranteeing the .ipynb files exist for `cp` to
succeed on.

Adding the flags alone would therefore not have gated anything. Both
changes are needed together.

This matches the step already merged in lecture-python.zh-cn. Checked
before making the change: the repo has no `raises-exception` tags and no
intentionally-erroring cells, and all 47 published lecture pages render
without error output, so this should not turn CI red on existing content.

Refs QuantEcon/meta#340

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 04:32
@netlify

netlify Bot commented Jul 30, 2026

Copy link
Copy Markdown

Deploy Preview for taupe-gaufre-c4e660 ready!

Name Link
🔨 Latest commit a7d98f3
🔍 Latest deploy log https://app.netlify.com/projects/taupe-gaufre-c4e660/deploys/6a6ad56110cf2e00088a8f86
😎 Deploy Preview https://deploy-preview-809--taupe-gaufre-c4e660.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CI workflow to ensure notebook execution failures are treated as fatal during the sphinx-tojupyter notebook-generation step, so CI reliably fails when notebook execution produces errors or warnings that should gate merges.

Changes:

  • Adds set -eo pipefail to prevent subsequent commands from masking jb build failures under shell: bash -l {0}.
  • Runs jb build with -n -W --keep-going for the custom/jupyter builder to promote warnings to errors and enforce execution gating.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yml Outdated
Corrects the previous commit, which gated the wrong step.

`lectures/_config.yml` sets `execute_notebooks: "cache"`, so only the
FIRST `jb build` in the workflow executes notebooks — every later builder
reads the cache. In this repo the first build is "Build PDF from LaTeX",
not the sphinx-tojupyter step. Gating tojupyter therefore caught nothing
that matters: by the time it runs, execution has already happened.

The LaTeX step was the real hole. It had `-n --keep-going` with no `-W`,
so a CellExecutionError was a non-fatal warning, and it carries the same
trailing-cp exit-code masking. Both are fixed here; the tojupyter step is
reverted to its original form, so there is exactly one gate and it sits on
the step that executes.

Note for anyone porting this: the equivalent change in lecture-python.zh-cn
sits on the tojupyter step, and that is correct there — its LaTeX step is
commented out, making tojupyter the first jb build. The rule is "gate the
first jb build", not "gate a particular step name".

Refs QuantEcon/meta#340

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants