Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1178 +/- ##
=======================================
Coverage 87.32% 87.32%
=======================================
Files 57 57
Lines 7726 7726
Branches 7726 7726
=======================================
Hits 6747 6747
Misses 673 673
Partials 306 306 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
dbdc1b6 to
92cf49d
Compare
db1970a to
d57bcd8
Compare
d57bcd8 to
4f8c903
Compare
4f8c903 to
8866664
Compare
There was a problem hiding this comment.
Pull request overview
Adds multi-version documentation publishing to the GitHub Pages deployment by generating a versions TOC and building docs for historical release tags (optionally patched) into the deployed book/ output.
Changes:
- Generate a
versions.mdpage (from a Jinja template) listing links to per-release docs builds. - Add tooling to iterate git release tags, optionally apply per-release patch files, and build/copy old docs into
book/release/<tag>/. - Update Just/CI wiring so the deploy workflow builds
all_with_old(current + old versions) for GitHub Pages.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/templates/versions.md.jinja | Template for a generated page linking to historical docs versions. |
| docs/release/patches/v2.0.0/0001-remove-unrecognised-parameter.patch | Patch applied to v2.0.0 docs so it can build with current tooling. |
| docs/release/init.py | Utilities to detect and list release tags. |
| docs/generate_versions_docs.py | Script to render versions.md from tags via Jinja. |
| docs/build_old_docs.py | Script to clone, checkout tags, apply patches, and build/copy old docs. |
| docs/SUMMARY.md | Adds the “Documentation for old versions” page to the book TOC. |
| docs/.gitignore | Ignores generated versions.md. |
| build-docs.just | Adds versions generation to default docs build and all_with_old target for old docs builds. |
| .github/workflows/deploy-docs.yml | Fetches tags and runs all_with_old for deployments; configures git identity for patch application. |
| .github/actions/generate-docs/action.yml | Adds an input to select which build-docs target to run. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Build TOC for old versions | ||
| versions: | ||
| @echo Building TOC for old versions of documentation | ||
| @uv run docs/generate_versions_docs.py |
There was a problem hiding this comment.
The versions target invokes uv run docs/generate_versions_docs.py, which declares an unpinned jinja2 dependency in its # /// script dependencies header; uv will fetch and execute the latest jinja2 from PyPI at docs-build time, creating a supply-chain risk. If an attacker compromises the jinja2 package or the PyPI registry, they could run arbitrary code in the docs build environment (e.g. in CI with access to repository tokens or the deployed docs). To mitigate this, pin jinja2 (and any other script dependencies) to immutable versions via a lockfile or explicit version specifiers, or vendor these dependencies so the build does not perform on-the-fly installs from the public registry.
tsmbland
left a comment
There was a problem hiding this comment.
I've done just build-docs::all_with_old, but still getting "Document not found (404)" when I click the link for v2.0.0. Maybe I'm doing something wrong?
Assuming this does work, I guess it does the job quite nicely, but a bit annoying that we end up having to compile all previous releases of MUSE and build all previous versions of the documentation on every push to main. It's fine for now with only one previous release, but what if there were 100? Mostly concerned about energy use to be honest, and whether this is really worth it (although probably quite small in the grand scheme of things). Also annoying that old versions are sensitive to updates in mdbook and having to keep track of this, but hopefully that's a rare problem.
If this is the way it has to be then so be it, but just wondering if you've considered any alternatives? How is this problem addressed in other projects? Pandas, for example? Looks like they only keep documentation for the latest of each minor version (e.g. 2.3.x), which seems reasonable to me (we probably won't, and indeed shouldn't, have major documentation changes for patch versions).
Hmm... that's weird. You opened it via
Yeah, it is annoying 😞. I couldn't think of a cleaner way of doing it though. I guess it's a downside of the complex docs-generation pipeline we have. Bear in mind that the build artifacts should be cached in We might hit problems when we have many releases, but performance might be surprisingly good with 100 releases, if the code is in the We currently only need to run cargo to generate the command-line help and build the API docs. Another solution would be to skip these steps (maybe with the patching feature) for older versions. API docs are also available on
I'd be happy with this as an option. We can open an issue for it. |
There wasn't anything there (or I think just an index file). But now I can't even get the
Ah ok, thanks for explaining! I didn't fully appreciate the caching thing so this alleviates my concerns
Less concerned about this now |
I actually had a similar problem. I assumed it was because there was version of |
Aurashk
left a comment
There was a problem hiding this comment.
Looks like a good solution for now!
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
build-docs.just:13
docs/SUMMARY.mdnow referencesversions.md, which is generated and gitignored. If someone runs only thebookrecipe (or any recipe that ends up callingmdbook buildwithout first runningversions), mdBook will fail becausedocs/versions.mdwon’t exist. Consider makingbookdepend onversions(or generatingversions.mdinsidebook) so partial builds still work.
# Build book
book:
@echo Building book
@mdbook build
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| Previous versions of the MUSE2 documentation are available below. | ||
| {% for release in releases %} | ||
| - [{{ release }}](release/{{ release }}/index.html) |
There was a problem hiding this comment.
The links are relative to the current page (e.g. release/v2.0.0/index.html). If this versions page ever appears inside an old release build (e.g. under release/v2.1.0/), those links will resolve to release/v2.1.0/release/v2.0.0/... and be broken. Consider rendering absolute links (e.g. https://…/MUSE2/release/<tag>/index.html) or passing a base_url into the template that can differ between main docs and old-release docs builds.
| - [{{ release }}](release/{{ release }}/index.html) | |
| - [{{ release }}]({{ base_url | default('') }}release/{{ release }}/index.html) |
There was a problem hiding this comment.
Actually these versions.md files won't actually end up being reachable from anywhere, so it doesn't matter
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
docs/generate_versions_docs.py
Outdated
| with (DOCS_DIR / "versions.md").open("w", encoding="utf-8") as f: | ||
| f.write(out) |
There was a problem hiding this comment.
For consistency with the other doc-generation scripts (e.g. generate_example_docs.py), consider writing versions.md via Path.write_text(..., encoding="utf-8") (or open with an explicit UTF-8 encoding). This avoids locale-dependent output and keeps the scripts stylistically consistent.
| with (DOCS_DIR / "versions.md").open("w", encoding="utf-8") as f: | |
| f.write(out) | |
| (DOCS_DIR / "versions.md").write_text(out, encoding="utf-8") |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def apply_patches_for_release(release: str, repo_path: Path) -> None: | ||
| """Apply patches (if any) for the given release.""" | ||
| patches_dir = DOCS_DIR / "release" / "patches" / release | ||
| for patch_path in sorted(patches_dir.glob("*.patch")): | ||
| sp.run(("git", "-C", str(repo_path), "am", str(patch_path)), check=True) | ||
|
|
There was a problem hiding this comment.
git am requires a committer identity; on machines/CI environments without user.name/user.email configured, applying patches will fail with “Please tell me who you are”. Since this script is intended to run in a temp clone, consider setting a local identity for that clone (e.g. git -C <repo> config user.name/user.email, or passing -c user.name=... -c user.email=... to git am) so just build-docs::all_with_old works in a clean environment.
There was a problem hiding this comment.
We do this explicitly on the CI
84aed2f to
7932f0b
Compare
98b855c to
b19525a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {%- for release in releases %} | ||
| - [{{ release }}](release/{{ release }}/index.html) | ||
| {%- endfor %} |
There was a problem hiding this comment.
The Jinja whitespace control in {%- for release in releases %} will strip the newline before the loop, which is likely to merge the “Current development version” bullet with the first generated release bullet into a single line. Use {% for release in releases %} (and similarly for endfor) or move the - to the end tag ({% for ... -%}) if you only intended to trim trailing whitespace.
| {%- for release in releases %} | |
| - [{{ release }}](release/{{ release }}/index.html) | |
| {%- endfor %} | |
| {% for release in releases %} | |
| - [{{ release }}](release/{{ release }}/index.html) | |
| {% endfor %} |
|
I've opened an umbrella issue for extra polishing we could do: #1187 |
Description
I fancied doing something a bit different, so I had a go at including docs for previous releases in our GitHub Pages deployment.
My implementation treats the version of the docs in the current checked-out version of the repo as the main one and generates a TOC in a
versions.mdfile, which is linked to from the main documentation. I've added a Python script to check out each previous version of the docs in turn and runjust build-docson it. The previous versions of the docs are not included when you runjust build-docsby default, partly because this would be unnecessary and slow (you likely don't care about previous versions of the docs when developing locally) and also to avoid infinite recursion when callingjust build-docsfor previous versions. Instead, you have to runjust build-docs::all_with_old.Some of the old versions of the docs may have problems of one kind or another that prevent them from being built with this script without modification. For example, the
book.tomlconfig file in v2.0.0 is incompatible with the latest version ofmdbook. To work around these sorts of problems, I've added a feature where we can add patch files todocs/release/patchesand these are applied (using git) before the documentation is built. You can generate these files with thegit format-patchcommand. For v2.0.0, we just need @Aurashk's fix in 3129c56. In this particular case, we could just cherry-pick the commit instead, as it is inmain, but note that this may not be true of every change we need to make to old broken documentation. We don't want things to depend on commits in random unmerged branches, so it seemed cleaner to just allow for adding arbitrary patches. Let me know if you think this process should be documented, because I haven't done so yet 😄.I've tested this locally and by deploying directly from this branch and it all seems to work, at least at first glance...
Shortcomings/future work:
I figure this is probably good enough to merge for now. We can always polish in future.
Let me know what you think!
Closes #1072.
Type of change
Key checklist
$ cargo test$ cargo docpresent in the previous release
Further checks