feat: assemble the published site from declared content roots - #351
Merged
Conversation
The site is published straight from this repository today, which leaves no
place for pages that live somewhere else. This adds the assembler that will
build it from several roots, and the harness that proves it changes nothing.
`scripts/assemble.py` resolves the roots declared in `assemble.yaml`, validates
them, and emits the tree. There is one root for now — this repo's `docs/` — and
the output is byte-identical to it. Later phases add the open-source pages from
lancedb/lancedb and the Enterprise overlays from sophon by editing the config,
not the script. The overlay merge and version writer are stubs with their call
sites fixed, so adding a root does not mean restructuring the program.
CI checks the invariant that matters on every pull request:
mint export (assembled tree) == mint export (docs/ directly)
Both sides come from the same commit in the same run, so the check cannot go
stale. On main the tree is published to the `assembled` branch.
The REST reference spec is now tracked at a release tag rather than committed
by a bot, and CI fails if the two drift. Syncing to
lance-format/lance-namespace@v0.12.0 fixes the endpoint pages: 43-48 of the 55
currently render "A valid request URL is required to generate request examples"
instead of code samples. All 55 render after this change.
Review found that `emit` cleared the output directory before copying, so an `output` equal to, inside, or containing a source root deleted the source and then failed copying the files it had just removed. Verified against a sandbox: it destroys the tree. The current paths do not overlap, so this guards the edit that adds a root rather than today's configuration. `--sync-spec` gets the same containment rule its destination was missing. Navigation validation only trusted strings containing a slash, which exempted every top-level page from the check and left a missing `quickstart` to be caught by nothing but the link checker. Classifying strings by the key that holds them covers all of them — 179 page paths and 46 labels, no misclassification — and a reference to a page that does not exist now fails the build instead of warning. Two workflows disagreed with the new release pin. `sync-openapi.yml` copied the spec from a moving `main` and is superseded by the assembler, so it is removed. `docs-ci.yml` overwrote the tracked spec before checking links, meaning it validated a spec the site would never publish. With the spec fix pinned, a reference page that cannot generate request examples is a regression rather than the status quo, so the comparison fails on it instead of quarantining it. The assembler also no longer resolves the docs test environment to run a file-copying script: 0.2s against a full dependency solve.
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.
Phase A1 of the documentation migration. Adds the assembler the site will be built from, and the harness that proves it changes nothing.
What this does
scripts/assemble.pyresolves the content roots declared inassemble.yaml, validates them, and emits the published tree. There is one root today — this repo'sdocs/— and the output is byte-identical to it, verified bydiff -rq.Six stages:
resolve → validate → merge → nav → emit → check. The overlay merge and the version writer are stubs with their call sites and data shapes fixed. That is deliberate: later phases add a root by editingassemble.yaml, not by restructuring the script.The harness
CI checks one invariant on every pull request:
Both sides are exported from the same commit in the same run, so the check cannot go stale the way a stored baseline can.
scripts/compare_exports.pynormalizes the per-build UUIDs Mintlify regenerates each run, and quarantines only reference pages that failed to generate request examples at all — a quarantine that retires itself once those pages render.On
main, the assembled tree is force-pushed to theassembledbranch. Nothing serves from it yet.What green does and does not mean. With one root and no anchors, the assembler is close to a structured copy, so passing proves the plumbing, not the merge logic — which has nothing to exercise it until the overlay phase. Building the harness before the thing it must catch is the right order, but this is not the assembler proven.
The REST reference is fixed
The OpenAPI spec is now tracked at a release tag rather than committed by a bot, and
make check-specfails if the two drift.Syncing to
lance-format/lance-namespace@v0.12.0fixes the endpoint pages. Today 43–48 of the 55 render "A valid request URL is required to generate request examples" instead of cURL/Python/JavaScript samples, and which ones fail varies per build. All 55 render after this change, with real URLs.Validators
Each was negative-tested rather than assumed:
Not in this change
Mintlify still serves the frozen
deploy-freezebranch. Repointing it atassembledis the cutover, and it is deliberately a separate, deliberate step — it will be the first thing to reach users since the freeze, carrying every queued documentation pull request and the REST fix at once.