Skip to content

fix(docs): make the documentation build reach a page, then pass strict - #8

Merged
livingstaccato merged 3 commits into
mainfrom
fix/docs-reference-warnings
Aug 27, 2026
Merged

fix(docs): make the documentation build reach a page, then pass strict#8
livingstaccato merged 3 commits into
mainfrom
fix/docs-reference-warnings

Conversation

@livingstaccato

Copy link
Copy Markdown
Member

docs.yml has failed every time it has run, most recently 2026-04-21, and never reached a page. Two failures stacked; the third piece is in provide-foundry.

1. The build died at config load

mkdocs.yml:2 is INHERIT: .provide/foundry/base-mkdocs.yml, and .gitignore:408 excludes .provide/foundry/ because it is an extract of provide-foundry, not source of ours. Nothing in a checkout creates it:

Error: Inherited config file '.provide/foundry/base-mkdocs.yml' does not exist

It exists on a developer machine, which is exactly why this looked like a link problem locally and was nothing of the kind. Reproduced by building from git archive HEAD into a clean tree, which fails with that line verbatim — the same line in the CI log for this PR's parent.

extract_base_mkdocs() in provide-foundry already writes it: the base config, the theme custom_dir points at, the shared partials, the helper scripts, and gen_ref_pages.py. It is now a docs dependency, and scripts/extract_docs_scaffolding.py runs before mkdocs.

The two mkdocs steps became uv run one-liners rather than activate-and-run blocks, per the no-inline-scripts rule. The extraction lives in scripts/ beside sbom_from_wheel.sh, which release.yml already invokes the same way.

2. The nine warnings underneath

Unreachable until now — the reference generator never ran, so mkdocs never rendered a page that could raise them.

Five are Google-style Raises: entries written as prose, which griffe cannot parse into an ExceptionType: description pair. Four name the exception they re-raise; the fifth (scoped_cache.py:84) documented the absence of exceptions, which is not what a Raises: section is for, and is removed rather than reworded.

hub/decorators.py:118 documented force_options as a parameter of register_command, which has no such parameter. It is not stale documentation: cli/click/commands.py:65 reads it out of info.metadata, so it arrives through **metadata and works. Moved to where it actually lives.

docs/reference/index.md linked hub/container/index.md, but container is a module rather than a package, so the generator emits container.md. Its "Full Module Index" link pointed at the built URL SUMMARY/; mkdocs validates against source filenames, and SUMMARY.md resolves to the same page.

Also gitignores the generated reference tree — mkdocs-gen-files keeps it in a temp overlay during a build, but running gen_ref_pages.py directly writes 351 files into docs/ for real.

Verified end to end

From git archive HEAD into a clean tree, running CI's exact sequence:

$ python scripts/extract_docs_scaffolding.py
✅ Docs scaffolding extracted to .../.provide/foundry
$ mkdocs build --clean --strict
EXIT=0   warnings: 0   reference pages: 353

Before: config-load failure. With scaffolding but the old generator: 1 page, 91 warnings.

⚠️ This does not turn the workflow green by itself

The extracted gen_ref_pages.py never invokes itself — provide-foundry#3. No provide-foundry release carries that fix yet (0.4.0 is the only published version), so CI here will still extract the broken generator and fail on the 91 warnings.

Order: merge provide-foundry#3 → release provide-foundry 0.4.1 → this goes green. The verification above used the fixed generator to prove that.

These have been unreachable: the API reference generator never ran, so
mkdocs never rendered a page that could raise them. With it running they
are the only nine warnings left, and --strict fails on all of them.

Five are Google-style `Raises:` entries written as prose rather than
`ExceptionType: description`, which griffe cannot parse into a pair:

  errors/handlers.py:199   "The original error if reraise=True."
  errors/handlers.py:280   "The original error if reraise_unhandled=..."
  resilience/retry.py:226  "Last exception if all retries are exhausted"
  resilience/retry.py:298  (the same, on the async path)
  utils/scoped_cache.py:84 "No exceptions - cleanup is guaranteed..."

The first four name the exception they re-raise. The fifth documented the
absence of exceptions, which is not what a Raises section is for; it is
removed rather than reworded.

hub/decorators.py:118 documented `force_options` as a parameter of
register_command, which has no such parameter. It is not stale, though:
cli/click/commands.py:65 reads it out of `info.metadata`, so it arrives
through **metadata and works. Documented where it actually lives.

docs/reference/index.md linked `hub/container/index.md`, but container is
a module rather than a package, so the generator emits `container.md`.
Its "Full Module Index" link pointed at the built URL `SUMMARY/` instead
of the source file; mkdocs validates links against source filenames, and
`SUMMARY.md` resolves to the same page.

`mkdocs build --clean --strict` now exits 0 with zero warnings, against
353 generated reference pages. It was 91 warnings and one page.
Every run of this workflow has failed, and none of them reached a page.
mkdocs.yml opens with

    INHERIT: .provide/foundry/base-mkdocs.yml

and .gitignore excludes .provide/foundry/, because it is an extract of
provide-foundry rather than source of ours. Nothing in a checkout creates
it, so the build aborts at config load:

    Error: Inherited config file '.provide/foundry/base-mkdocs.yml'
    does not exist at '/home/runner/work/.../.provide/foundry/base-mkdocs.yml'

The directory happens to exist on a developer machine, which is why this
looked like a link problem locally and was nothing of the kind. Reproduced
by building from `git archive HEAD` into a clean tree, which fails with
exactly the line above.

provide-foundry already knows how to write it -- extract_base_mkdocs()
lays down the base config, the theme that `custom_dir` points at, the
shared partials, the helper scripts and gen_ref_pages.py. It is now a
`docs` dependency and a step runs it before mkdocs.

The two mkdocs steps are one-liners under `uv run` rather than activate-
and-run blocks, per the no-inline-scripts rule; the extraction itself is
scripts/extract_docs_scaffolding.py, alongside sbom_from_wheel.sh, which
release.yml already calls the same way.

Also ignores the generated reference tree. mkdocs-gen-files keeps those
files in a temporary overlay during a build, but running gen_ref_pages.py
directly writes 351 of them into docs/ for real.

This does not turn the workflow green on its own: the extracted
gen_ref_pages.py never invokes itself, which is provide-foundry#3, and no
release carries that fix yet. It removes the first of the two failures,
and the second is fixed and pending release.
…reference

0.4.0 extracts a gen_ref_pages.py that never invokes itself under
mkdocs-gen-files, so the reference section comes out empty and --strict
fails on the dangling links out of docs/reference/index.md. The floor was
>=0.4.0 only because that was the newest release when this branch opened.

0.4.1 carries the fix and is the first release where this builds, so the
floor says so rather than leaving the lock as the only thing standing
between CI and a version that cannot work.

Verified end to end against the published package, not a local checkout:
removed .provide/foundry entirely, `uv sync --group docs` installed
provide-foundry 0.4.1 from PyPI, the extraction script rewrote the
directory, and `mkdocs build --clean --strict` exited 0 with zero warnings
across 353 generated reference pages. docs/ was left clean afterwards.
@livingstaccato
livingstaccato merged commit 038f016 into main Aug 27, 2026
12 checks passed
@livingstaccato
livingstaccato deleted the fix/docs-reference-warnings branch August 27, 2026 09:28
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.

1 participant