Skip to content

Enable HTML builds and per-PR preview deploys - #6

Merged
mmcky merged 3 commits into
mainfrom
enable-html-previews
Aug 6, 2026
Merged

Enable HTML builds and per-PR preview deploys#6
mmcky merged 3 commits into
mainfrom
enable-html-previews

Conversation

@mmcky

@mmcky mmcky commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Enables HTML builds so a native-speaker reviewer can read a rendered page instead of raw MyST markdown in the diff.

Why this is more than a workflow file

main had no build configuration of any kind — no lectures/, no _config.yml, no _toc.yml, no environment.yml. Each seed/* branch adds exactly one lectures/<name>.md against that empty base, so nothing in the repo was buildable and dropping in a preview workflow alone would have built nothing. Most of this PR is the scaffold; the workflows are the smaller half.

What's here

File Role
lectures/_config.yml .fr's config with ml substituted (baseurl, language, current_language, repository_url, tojupyter_*), plus an ml entry in the language switcher
lectures/_toc.yml, _static/, _admonition/, intro.md copied from QuantEcon/lecture-python-programming@main
environment.yml copied from .fr — conda quantecon, jupyter-book 1.x, theme 0.21.0
scripts/prune_toc.py prunes _toc.yml to translated lectures at build time
.github/workflows/ci.yml per-PR build → gh-pages/pr-N/ → PR comment with deep links
.github/workflows/publish.yml maingh-pages root, keep_files: true
.github/workflows/reap-previews.yml weekly reconcile of gh-pages against open PRs

intro.md is the English original for now — it is the TOC root, so the build needs it, and holding the scaffold until it is translated would block all five reviews. It should get its own translation PR.

Design notes

Jupyter Book, not mystmd. The whole fleet is Jupyter Book 1.x — the English origin/main, .fr, .fa, .zh-cn and QuantEcon.manual. The mystmd work in the English repo is on the unmerged jb2 branch. action-translation also has no mystmd code path; _toc.yml is hardcoded in its lecture discovery, so adopting myst.yml here would break translation sync.

GitHub Pages, not Netlify. .fr and .fa deploy previews to Netlify via quantecon/actions/preview-netlify, which needs a Netlify site and a NETLIFY_SITE_ID secret. This repo has no secrets at all, while GITHUB_TOKEN already has write permission — so the QuantEcon.manual pattern costs nothing to set up. .zh-cn has no preview mechanism at all.

_toc.yml is pruned at build time, not by hand. action-translation copies _toc.yml from the English source verbatim whenever an upstream PR touches it, so a pruned copy committed here would be silently overwritten on the next sync. The script preserves upstream ordering and part captions and is a no-op once every lecture is translated, at which point it and its CI step should be deleted.

No -n -W. The translated lectures reference lectures that do not exist yet — writing_good_code, python_advanced_features, scipy, getting_started, oop_intro, need_for_speed, plus the labels pyess_ex2 and oop_ex1. Those must stay warnings until the translation is complete; .fa and .fr relax the same flag for the same reason.

Google Analytics dropped. .fr inherits the shared G-X7DH1M2DPY property. An in-progress translation and its per-PR previews should not report into the published site's stream. Easy to reinstate — it is a two-line addition under html_theme_options.

Two deliberate departures from QuantEcon.manual

Checkout ref. Its preview job pins pull_request.head.sha. The seed/* branches were cut from an empty main and carry only their one lecture, so that ref has no scaffold and would not build. This uses the default merge ref, which also means the preview shows the post-merge state.

Publish lock scope. Its publish job holds the gh-pages concurrency lock across the whole conda solve and build, roughly two minutes. Since GitHub evicts an already-pending run when a newer one queues into a group (cancel-in-progress: false only protects the running job), that long hold drops queued cleanups — a merge train there on 2026-08-02 lost two runs in 68 seconds, and pr-145 is still live on that site days after merging. publish.yml here splits build from deploy so the lock is held for seconds, and reap-previews.yml catches what still slips through.

Verification

Built locally with jb 1.0.4.post1 in two configurations:

  • Simulated PR Malayalam translation: numpy — native-speaker calibration review #5 (scaffold + numpy.md only): build succeeded, 11 warnings, all of them the expected dangling references. Output carries 6,885 Malayalam characters in numpy.html, lang="ml", correct canonical URL, favicon and logo resolved.
  • Simulated post-merge (scaffold + all five seed lectures): build succeeded, 15 warnings, 10 HTML pages. The prune script correctly reduced the 26-entry TOC to 3 parts / 5 chapters in upstream order.

Not verified locally: the language switcher. The local conda env has theme 0.15.1, which reports unsupported theme option 'languages' — no edition's entry renders there, including the existing fr/fa/zh-cn ones. CI installs the pinned 0.21.0. Execution was left "off" for these local runs to avoid the lectures' own !pip install cells mutating the environment; a separate full run with execution forced completed with zero cell errors on CPU, including pandas.md's live FRED / World Bank / Yahoo calls.

Required after merge

  1. publish.yml runs on merge and creates the gh-pages branch.
  2. Settings → Pages → Deploy from a branch → gh-pages / / (root). Preview links 404 until this is done.
  3. Reopen PRs Malayalam translation: python_by_example — native-speaker calibration review #1Malayalam translation: numpy — native-speaker calibration review #5 to trigger a build — they predate this workflow. Do this after step 1, or cleanup-preview's gh-pages checkout fails on the close event.

Previews will then appear at https://quantecon.github.io/lecture-python-programming.ml/pr-N/.

Out of scope, but worth knowing

  • rebase-translations.yml never fires for these PRs — it matches translation-sync-* and resync/* head branches, not seed/*.
  • review-translations.yml fails on all five seed PRs by design: review mode needs a ### Source PR marker that hand-staged seeds do not carry.
  • Do not run translate init after this lands — it re-copies every non-markdown file from the English source and would overwrite the localised _config.yml.
  • Each preview is a full ~16 MB site copy committed to gh-pages, and those blobs stay in branch history even after the directory is reaped. If the branch gets unwieldy, re-orphan it.

🤖 Generated with Claude Code

The repo had no build configuration at all: main carried only the
translation workflows, and each seed/* branch adds a single
lectures/<name>.md against it. Nothing was buildable, so there was no way
for a native-speaker reviewer to see a rendered page.

Adds the Jupyter Book scaffold (_config.yml, _toc.yml, _static, intro.md,
environment.yml) and three workflows:

- ci.yml builds every PR and deploys it to gh-pages under pr-N/, then
  comments with a deep link to the lectures that PR translates. Ported
  from QuantEcon.manual, the only repo in the fleet serving previews off
  GitHub Pages rather than Netlify — this edition has no Netlify site and
  no repo secrets, while GITHUB_TOKEN already has write.
- publish.yml deploys main to the gh-pages root with keep_files so live
  previews survive.
- reap-previews.yml reconciles gh-pages against open PRs weekly.

Two deliberate departures from QuantEcon.manual. Its preview job checks
out the PR head; here that would miss the scaffold, since the seed
branches were cut from an empty main, so the default merge ref is used
instead. And its publish job holds the gh-pages concurrency lock across
the whole conda solve and build; because GitHub evicts an already-pending
run when a newer one queues into a group, that long hold drops queued
cleanups and has left orphaned previews live on that site. publish.yml
here splits build from deploy so the lock is held for seconds, and
reap-previews.yml covers the remainder.

_toc.yml is pruned at build time by scripts/prune_toc.py rather than
maintained by hand: action-translation copies it from the English source
verbatim whenever an upstream PR touches it, so a pruned copy committed
here would be overwritten on the next sync.

The build runs without -n -W. The translated lectures carry references
into lectures that do not exist yet (writing_good_code,
python_advanced_features, scipy, getting_started, oop_intro,
need_for_speed, and the labels pyess_ex2 and oop_ex1); those must stay
warnings until the translation is complete. The fa and fr editions relax
the same flag for the same reason.

_config.yml is fr's, with ml substituted and the shared English Google
Analytics property dropped so an in-progress translation and its previews
do not report into the published site's stream.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 6, 2026 00:46
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📖 HTML build - view preview (5311036)

Translated pages in this PR:

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

Adds the minimal Jupyter Book scaffold plus GitHub Actions workflows needed to build and deploy rendered HTML for this edition, including per-PR preview deployments to gh-pages/pr-N/.

Changes:

  • Add Jupyter Book configuration (lectures/_config.yml), TOC (lectures/_toc.yml), and root page (lectures/intro.md) to make the repo buildable as HTML.
  • Add a build-time TOC pruning script (scripts/prune_toc.py) to avoid missing-lecture build failures during incremental translation.
  • Add GH Pages publish + per-PR preview workflows (.github/workflows/*.yml) and supporting build environment (environment.yml), plus required static lecture assets under lectures/_static/.

Reviewed changes

Copilot reviewed 17 out of 85 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
scripts/prune_toc.py Prunes _toc.yml to only translated lectures at build time to keep Jupyter Book builds green during partial translation.
lectures/intro.md Adds the Jupyter Book root page that anchors the TOC build.
lectures/_toc.yml Defines the lecture structure for the book build and navigation.
lectures/_config.yml Adds Jupyter Book + theme configuration, language switching, and site metadata for the Malayalam edition.
lectures/_admonition/gpu.md Adds a reusable admonition snippet used by lecture content.
environment.yml Defines the conda/pip environment used by CI and publish workflows to build the HTML site.
.github/workflows/ci.yml Builds HTML on PRs, deploys per-PR previews to gh-pages/pr-N/, and comments deep links back to the PR.
.github/workflows/publish.yml Builds on main and deploys the root site to gh-pages while preserving preview directories.
.github/workflows/reap-previews.yml Periodically deletes orphaned pr-* preview directories on gh-pages for closed PRs.
lectures/_static/includes/lecture_howto_py.raw Adds raw HTML include used in rendered outputs.
lectures/_static/includes/header.raw Adds raw HTML header include used in rendered outputs.
lectures/_static/lecture_specific/about_py/qs.py Adds lecture-specific example code used by content.
lectures/_static/lecture_specific/python_foundations/us_cities.txt Adds lecture-specific sample data file.
lectures/_static/lecture_specific/python_advanced_features/numbers.txt Adds lecture-specific sample data file.
lectures/_static/lecture_specific/pandas/wb_download.py Adds lecture-specific example script for downloading/plotting World Bank data.
lectures/_static/lecture_specific/pandas/data/ticker_data.csv Adds lecture dataset used by pandas-related content/examples.
lectures/_static/lecture_specific/pandas/data/test_pwt.csv Adds small test dataset used by pandas-related content/examples.

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

Comment thread environment.yml Outdated
Comment thread lectures/_toc.yml
Comment thread lectures/_static/lecture_specific/python_foundations/us_cities.txt
Comment thread lectures/_static/lecture_specific/pandas/wb_download.py
Comment thread .github/workflows/ci.yml Outdated
QuantEcon.manual passes `cname: false` intending "no CNAME on previews",
but YAML stringifies that to "false" and the action writes a CNAME file
containing the literal text `false` at the gh-pages root. GitHub then
reads it as a custom domain and the site fails to serve. The first run of
this workflow reproduced it exactly.

It is masked in QuantEcon.manual because its publish.yml overwrites the
root CNAME with the real domain. This edition has no custom domain, so
nothing would ever correct it.

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

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📖 HTML build - view preview (2bbe79c)

Translated pages in this PR:

`default` is not a channel; conda adds it as a literal name and the build
only resolves because conda still adds `defaults` implicitly, which it
warns about and is deprecating. The zh-cn edition already uses `defaults`;
en, fr and fa carry the same typo and should be fixed upstream.

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

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📖 HTML build - view preview (4e349f8)

Translated pages in this PR:

@mmcky
mmcky merged commit 23ef144 into main Aug 6, 2026
4 checks passed
@mmcky
mmcky deleted the enable-html-previews branch August 6, 2026 02:14
github-actions Bot added a commit that referenced this pull request Aug 6, 2026
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