fix(docs-site): publish function pages under /reference/
Generate documentation / build-docs (push) Successful in 2m59s
Generate documentation / build-docs (push) Successful in 2m59s
Cloudflare Pages reserves a top-level `functions/` directory in the deploy output for Pages Functions (server-side handlers) and strips it from the static-asset upload. The wrangler log for run 812 shows the collision exactly: 159 files uploaded, which is precisely the number of files in dist/ outside functions/ — all 108 files under it were dropped. Nothing failed loudly. Astro built all 120 pages, wrangler reported success, and the site worked under `astro preview`; only the deployed copy 404'd on every function entry and category index. Move the generated tree to /reference/ and add a test asserting the site output never emits a name Pages reserves.
This commit is contained in:
@@ -279,7 +279,14 @@ def build_site(root: Path, out: Path) -> list[dict]:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Section 5: category index page keeps its slot; entries explode.
|
# Section 5: category index page keeps its slot; entries explode.
|
||||||
slug_dir = "functions"
|
#
|
||||||
|
# Deliberately NOT "functions": Cloudflare Pages reserves a top-level
|
||||||
|
# `functions/` directory in the deploy output for Pages Functions
|
||||||
|
# (server-side handlers) and silently drops it from the static-asset
|
||||||
|
# upload. The pages build fine and never arrive — every entry 404s in
|
||||||
|
# production while working locally. test_site_avoids_reserved_dir
|
||||||
|
# guards this.
|
||||||
|
slug_dir = "reference"
|
||||||
if rel.name == "index.md":
|
if rel.name == "index.md":
|
||||||
target = out / slug_dir / "index.md"
|
target = out / slug_dir / "index.md"
|
||||||
target.parent.mkdir(parents=True, exist_ok=True)
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|||||||
+24
-1
@@ -203,7 +203,7 @@ def test_site_build_produces_function_pages():
|
|||||||
sidebar = build_manual.build_site(docs / "manual", out)
|
sidebar = build_manual.build_site(docs / "manual", out)
|
||||||
pages = list(out.rglob("*.md*"))
|
pages = list(out.rglob("*.md*"))
|
||||||
assert (out / "index.md").exists(), "landing page missing"
|
assert (out / "index.md").exists(), "landing page missing"
|
||||||
fn_pages = [p for p in pages if "functions" in p.parts and p.name != "index.mdx"]
|
fn_pages = [p for p in pages if "reference" in p.parts and p.name != "index.mdx"]
|
||||||
assert len(fn_pages) > 80, f"expected >80 function pages, got {len(fn_pages)}"
|
assert len(fn_pages) > 80, f"expected >80 function pages, got {len(fn_pages)}"
|
||||||
assert not (out / "00-name.md").exists(), "site:false page was published"
|
assert not (out / "00-name.md").exists(), "site:false page was published"
|
||||||
assert sidebar, "sidebar structure is empty"
|
assert sidebar, "sidebar structure is empty"
|
||||||
@@ -293,6 +293,29 @@ def test_sidebar_has_no_duplicate_functions_entry():
|
|||||||
assert len(labels) == 15, f"expected Overview + 14 categories, got {len(labels)}"
|
assert len(labels) == 15, f"expected Overview + 14 categories, got {len(labels)}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_site_avoids_reserved_dir():
|
||||||
|
"""No output directory may collide with a Cloudflare Pages reserved name.
|
||||||
|
|
||||||
|
Pages treats a top-level `functions/` directory in the deploy output as
|
||||||
|
Pages Functions (server-side handlers) and drops it from the static-asset
|
||||||
|
upload. The build succeeds, wrangler reports success, and every page under
|
||||||
|
it 404s in production while working perfectly under `astro preview` — so
|
||||||
|
only a check on the emitted tree catches it.
|
||||||
|
"""
|
||||||
|
import build_manual
|
||||||
|
|
||||||
|
reserved = {"functions", "_worker.js", "_routes.json"}
|
||||||
|
docs = Path(__file__).parent
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
out = Path(d)
|
||||||
|
build_manual.build_site(docs / "manual", out)
|
||||||
|
clashes = {p.name for p in out.iterdir()} & reserved
|
||||||
|
assert not clashes, (
|
||||||
|
f"site output has Cloudflare Pages reserved name(s): {sorted(clashes)} "
|
||||||
|
"— these are silently excluded from the deployed assets"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
|
TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user