ci(MIC-100): cache text/build to skip unchanged Sphinx pages#482
Merged
Conversation
Sphinx writes its build outputs to text/build/. Both 'make pdfs' (latex builder + xelatex) and 'make json' (json + json_kr builders) share that directory and the doctrees pickle inside it. Restoring it lets Sphinx skip pages whose source content hasn't changed. Cache key invalidates on any change to text/source/**, the KR locale catalog, text/Makefile, or the workflow file (which captures the builder-image bump).
The Makefile already has a CI_BUILD mode that drops the specs/results/images
deps from the Sphinx targets. The original design uploaded those outputs to
S3 ('uploadCIdeps' target) and downloaded them in CI to skip 'dvc repro'.
Replicate with actions/cache: cache text/results, text/plots, text/docs-dir
keyed on dvc.lock + .mo files + specs.py. When the key hits, set CI_BUILD=1
so Sphinx targets stop triggering 'dvc repro' (which today walks 30+
already-cached stages and burns ~8 min on overhead alone, per per-step
measurement on this PR).
When the key misses (e.g. .mo source changed), CI_BUILD=0 and 'dvc repro'
runs normally, then the new cache is saved for future runs.
Two bugs were preventing CI_BUILD from doing what its comment promised: 1. text/Makefile used 'CI_BUILD=0' (unconditional), which clobbered any env-var override. Switched to 'CI_BUILD ?= 0' so callers can actually set it via env or sub-make. 2. The root Makefile's json/dirhtml targets always pulled in the 'results' target (which runs 'dvc repro'). text/Makefile's CI_BUILD optimization only short-circuited deps INSIDE text/, so the root forced full regeneration regardless. Mirrored the same CI_BUILD switch in root Makefile so 'make json' / 'make dirhtml' skip results when CI_BUILD=1. With both fixes, CI_BUILD=1 + a populated cache should let generate_results skip 'dvc repro' entirely (the ~8 min cost identified by per-step measurement on earlier runs in this PR).
Last run skipped too much: with SPHINXDEPS empty, the latex builder hit WARNINGs for every SVG (no .pdf companion present), and the build failed because the converted PDFs aren't checked in (only the SVGs are). svg->pdf via rsvg-convert is cheap, so keep 'images' in SPHINXDEPS even under CI_BUILD=1. The expensive deps we actually want to skip are 'specs' and 'results' (dvc repro).
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.
Result
generate_resultsdrops from ~12m to ~3m 28s on a no-source-change rerun (most of the remaining time is GitHub-runner container init, not work).Verified on commit
16453b57(run 28406940388).What was actually wrong
The first cache I tried (Sphinx
text/build) saved <30s because the real bottleneck wasn't Sphinx. Drilling into the logs showeddvc repro dvc.yamlwas eating 2m 43s in Make PDFs and ~6m in Generate JSON, just walking 30+ already-cached stages to confirm they're up to date.Then it turned out
CI_BUILD=1(which exists intext/Makefileprecisely to skip this) didn't work for two reasons:text/MakefilehadCI_BUILD=0instead ofCI_BUILD ?= 0— clobbering any env-var override. The comment promised "to enable the CI build domake CI_BUILD=1 pdf", but the line below unconditionally reset it.Makefile'sjson:target depended onresults:unconditionally, so even whentext/MakefilehonoredCI_BUILD, the root invocation forced a full DVC run.Fixing both, then keeping
images(svg→pdf) in the build chain (the latex builder needs the converted PDFs, which aren't checked in), gives the speedup.Changes
text/Makefile:CI_BUILD=0→CI_BUILD ?= 0; keepimagesinSPHINXDEPSeven under CI_BUILD=1.Makefile(root): mirror theCI_BUILDswitch on thejson:anddirhtml:targets so they drop theresultsdep when set..github/workflows/build.yaml:text/results,text/plots,text/docs-dirkeyed ondvc.lock+.mofiles +specs.py+ workflow.CI_BUILD: 1env on Make PDFs / Generate JSON when that cache hits;CI_BUILD: 0when it misses (preserves correctness for source changes).text/buildcache; modest extra win on xelatex.Behavior matrix
.moeditspecs.py/dvc.lockchangeRisks
text/results+text/plots+text/docs-dirare the complete set ofdvc reprooutputs Sphinx consumes. If a future Sphinx extension reaches into another DVC-produced location, it'll silently get a stale file. Mitigation is the hash-key invalidation ondvc.lock.Closes MIC-100.