Enable HTML builds and per-PR preview deploys - #6
Merged
Conversation
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>
Contributor
|
📖 HTML build - view preview (5311036) Translated pages in this PR: |
There was a problem hiding this comment.
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 underlectures/_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.
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>
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>
Contributor
|
📖 HTML build - view preview (4e349f8) Translated pages in this PR: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
mainhad no build configuration of any kind — nolectures/, no_config.yml, no_toc.yml, noenvironment.yml. Eachseed/*branch adds exactly onelectures/<name>.mdagainst 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
lectures/_config.yml.fr's config withmlsubstituted (baseurl,language,current_language,repository_url,tojupyter_*), plus anmlentry in the language switcherlectures/_toc.yml,_static/,_admonition/,intro.mdQuantEcon/lecture-python-programming@mainenvironment.yml.fr— condaquantecon, jupyter-book 1.x, theme 0.21.0scripts/prune_toc.py_toc.ymlto translated lectures at build time.github/workflows/ci.ymlgh-pages/pr-N/→ PR comment with deep links.github/workflows/publish.ymlmain→gh-pagesroot,keep_files: true.github/workflows/reap-previews.ymlgh-pagesagainst open PRsintro.mdis 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-cnandQuantEcon.manual. The mystmd work in the English repo is on the unmergedjb2branch.action-translationalso has no mystmd code path;_toc.ymlis hardcoded in its lecture discovery, so adoptingmyst.ymlhere would break translation sync.GitHub Pages, not Netlify.
.frand.fadeploy previews to Netlify viaquantecon/actions/preview-netlify, which needs a Netlify site and aNETLIFY_SITE_IDsecret. This repo has no secrets at all, whileGITHUB_TOKENalready has write permission — so theQuantEcon.manualpattern costs nothing to set up..zh-cnhas no preview mechanism at all._toc.ymlis pruned at build time, not by hand.action-translationcopies_toc.ymlfrom 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 labelspyess_ex2andoop_ex1. Those must stay warnings until the translation is complete;.faand.frrelax the same flag for the same reason.Google Analytics dropped.
.frinherits the sharedG-X7DH1M2DPYproperty. 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 underhtml_theme_options.Two deliberate departures from QuantEcon.manual
Checkout ref. Its preview job pins
pull_request.head.sha. Theseed/*branches were cut from an emptymainand 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-pagesconcurrency 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: falseonly protects the running job), that long hold drops queued cleanups — a merge train there on 2026-08-02 lost two runs in 68 seconds, andpr-145is still live on that site days after merging.publish.ymlhere splits build from deploy so the lock is held for seconds, andreap-previews.ymlcatches what still slips through.Verification
Built locally with
jb 1.0.4.post1in two configurations:numpy.mdonly): build succeeded, 11 warnings, all of them the expected dangling references. Output carries 6,885 Malayalam characters innumpy.html,lang="ml", correct canonical URL, favicon and logo resolved.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 existingfr/fa/zh-cnones. CI installs the pinned 0.21.0. Execution was left"off"for these local runs to avoid the lectures' own!pip installcells mutating the environment; a separate full run with execution forced completed with zero cell errors on CPU, includingpandas.md's live FRED / World Bank / Yahoo calls.Required after merge
publish.ymlruns on merge and creates thegh-pagesbranch.gh-pages// (root). Preview links 404 until this is done.cleanup-preview'sgh-pagescheckout 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.ymlnever fires for these PRs — it matchestranslation-sync-*andresync/*head branches, notseed/*.review-translations.ymlfails on all five seed PRs by design: review mode needs a### Source PRmarker that hand-staged seeds do not carry.translate initafter this lands — it re-copies every non-markdown file from the English source and would overwrite the localised_config.yml.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