mirror of
https://github.com/paperclipai/paperclip-docs.git
synced 2026-11-09 04:09:33 -10:00
Picks up the regression test from #104 (@cryppadotta) — closed as superseded, but its fixture design was the best part of it and worth landing on its own. ## Why this gap mattered The sitemap `lastmod` bug shipped twice, and **neither failure was detectable by any check in `docs:test`**: | | Symptom | Why nothing caught it | |---|---|---| | #117 | 0 dates in production for weeks | Shallow checkout doesn't make `git log` *fail* — it succeeds, returning one date per file | | #118 | 192 concurrent `git fetch --unshallow` fighting over `.git/shallow.lock`, dateless sitemap | Reproduces only on a shallow clone — never locally, never in CI | Both are Cloudflare-only failure modes. The only detector we had was reading the live sitemap, which is how this whole thread started. ## What landed `scripts/verify-sitemap-lastmod-history.mjs`, wired into `docs:test`. Three cases against **real depth-1 clones** — the fixture design and `--no-local` insight are @cryppadotta's: 1. Full history publishes real per-document dates 2. Shallow clone that can reach origin recovers history 3. Shallow clone with unreachable origin omits dates rather than lying Two changes on top of the original: **Overlay the working-tree builder into the clone.** The clone carries committed HEAD, so without this the shallow cases silently test the last commit instead of the change being made. No-op in CI; the difference is real locally, and it is what makes the check usable while iterating. **Assert no single date covers >75% of pages.** The existing "more than one distinct date" assertion passes at *2* distinct dates — precisely the state #118 fixed, where 190 of 193 pages carried the date of a frontmatter-only sweep. Bounding the largest cluster catches that class without pinning a date that legitimate edits will move. ## Verified by breaking it A check that has never failed proves nothing, so I reverted each fix in turn: **Revert body-aware dating (#118):** ``` ok lastmod values vary across documents (2 distinct) rather than one build date FAIL full history: no single date dominates (2026-08-25 covers 190/193, 98% <= 75%) ``` Note the pre-existing assertion passing right above the failure — that is the gap this closes. **Revert the single-flight memo (#118):** ``` FAIL unshallowed build dates every route (2/193) FAIL unshallowed build produces varied dates (1 distinct) ``` The `.git/shallow.lock` race, caught by Case 2 and nothing else. Restored, clean run is green: 193/193 dated, 31 distinct, largest cluster 28%. ## Cost **~55s** added to `docs:test` for three builds (`docs-test` was 32s). Steep for a test suite, and worth flagging rather than burying — but the alternative detector for this failure class is noticing the live sitemap is wrong. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
57 lines
1.6 KiB
YAML
57 lines
1.6 KiB
YAML
name: Docs checks
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main, nightly]
|
|
|
|
jobs:
|
|
docs-test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
# Sitemap <lastmod> is derived from per-file git history. A shallow
|
|
# checkout collapses every file to the same commit date, which the
|
|
# build detects and responds to by omitting the dates entirely.
|
|
fetch-depth: 0
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 20
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
# Separate steps with `if: always()` so one failure cannot mask the rest.
|
|
# An `&&` chain short-circuits, which silently skipped later gates.
|
|
- name: Static routes
|
|
run: npm run docs:test:static-routes
|
|
|
|
# Builds from real depth-1 clones: the shallow-checkout and
|
|
# concurrent-unshallow failures both reproduce only there, never on the
|
|
# full-history checkout the other gates run against.
|
|
- name: Sitemap lastmod history
|
|
if: always()
|
|
run: npm run docs:test:sitemap-lastmod-history
|
|
|
|
- name: Asset fingerprints
|
|
if: always()
|
|
run: npm run docs:test:asset-fingerprints
|
|
|
|
- name: Hierarchical skills nav
|
|
if: always()
|
|
run: npm run docs:test:hierarchical-skills-nav
|
|
|
|
- name: Crawlable links
|
|
if: always()
|
|
run: npm run docs:test:crawlable-links
|
|
|
|
- name: Authored SEO metadata
|
|
if: always()
|
|
run: npm run docs:test:seo-metadata
|
|
|
|
- name: Skill source blocks
|
|
if: always()
|
|
run: npm run docs:test:skill-source-blocks
|