feat: swagger-ui from node_modules
Serve Swagger UI from node_modules instead of a committed vendor copy
Summary
/api loads Swagger UI from files copied out of the locked swagger-ui-dist package at build time. Nothing from the distribution is committed, so a Dependabot bump no longer needs a manual re-vendor step and no longer turns the Netlify build red.
flowchart LR
lock[yarn.lock<br/>version + integrity] --> nm[node_modules/swagger-ui-dist]
nm -->|swagger-ui-assets plugin<br/>on start/build| gen[generated-static/swagger-ui/<br/>gitignored, 11 files]
static[static/<br/>api.html, swagger-initializer.js] --> build[build/]
gen -->|staticDirectories| build
build:netlify
verify-git-history
verify-indexnow-vendor
- verify-swagger-ui-vendor # failed on every swagger-ui-dist bump
npm ci site-build-gate
docusaurus build
+ swagger-ui-assets plugin # copies the files api.html loads
run-post-build-gates
src/plugins/
+└── swagger-ui-assets.js # copy list + staging, fails if a file disappears upstream
static/
├── api.html # unchanged
├── swagger-initializer.js # unchanged
-├── swagger-ui*.js|css|map|LICENSE.txt, index.css, favicon-*.png # 19 files
-├── oauth2-redirect.html|js # unused: the API spec has no OAuth2 scheme
-└── swagger-ui-vendor.json # version/integrity/SHA-256 contract
scripts/
-└── verify-swagger-ui-vendor.js
tests/
-├── swagger_ui_vendor.test.js
+└── swagger_ui_assets.test.js # api.html refs ⊆ copy list; installed package ships them
Also in this PR:
- Drops the unused
swagger-uidependency. Nothing imports it; it removes about 80 packages fromyarn.lockand no remaining package changes version. - Moves
swagger-ui-distinto thebrowser-runtimeDependabot group.tests/dependency_authority.test.jsis updated to match, and its "Swagger must stay independent" assertion is removed. - Removes
oauth2-redirect.htmlfrom the Cloudflare analytics gate's sensitive routes and from two tests.api.htmlstays protected. - Rewrites the README's Swagger section, including how to restore the OAuth2 redirect page if the API ever adds OAuth2.
- dependency-impact workflow is not only triggered for Dependabot.
Evidence
-
Before: a Dependabot-style bump (only
package.jsonand theyarn.lockentry changed) fails before Docusaurus even starts:$ node scripts/verify-swagger-ui-vendor.js # swagger-ui-dist 5.33.1 → 5.33.0 Swagger UI vendor verification failed: Swagger UI vendor contract does not match the locked distribution exit=1#3082 (5.32.14 → 5.33.1) shows the same thing in practice: every GitHub check was green,
netlify/netdata-docusaurus/deploy-previewwas red, and the PR was closed until #3136 re-vendored by hand.After: the plugin stages whatever version is installed, with no manual step:
stageSwaggerUiAssets(<site with swagger-ui-dist 5.33.0>) { version: '5.33.0', files: 11 } -
Full Netlify build (
npm run build:netlify, Node 22.23.2): passes. Site build gate: 0 findings across 2,030 pages. Cloudflare analytics gate: "1 credential-handling route" (api.html). Broken-anchor warnings: 297, the same asmaster. -
Tests:
yarn test:runpasses: Vitest 494 passed and 1 skipped, plus the first-touch (26), IndexNow (64), swagger-ui-assets (3), dependency-authority (3) and site-build-gate (4) suites. -
Browser (headless Chromium, local
docusaurus serve):/apirenders 72 API operations.swagger-ui.css,index.css,swagger-ui-bundle.js,swagger-ui-standalone-preset.jsandswagger-initializer.jsall return 200. No console errors or warnings. -
Build output,
mastervs this branch (both built from directories at the same depth, compared file by file):Output Result All JS chunks, sitemap identical Files /apiloads (bundle, preset, CSS,index.css, favicons, bundle source map)byte-identical es-bundle*,swagger-ui.js,oauth2-redirect.*,swagger-ui-vendor.jsonremoved (never loaded by /api)styles.cssabout 4 KB smaller: Tailwind no longer generates unused utilities from strings inside the committed Swagger bundles main.jsonly the new plugin entry and the extra staticDirectoriesvalueHTML pages new main/styleshash names and one extra blank line; no content change
Merge Danger
Door: two-way
Reverting this PR restores the vendored files and the check exactly. The one thing that doesn't come back on its own is the /oauth2-redirect.html URL: it returns 404 from the first deploy after merge. It is an OAuth callback page, not content, but backlinks for that path haven't been checked yet.
Blast Radius: /api
- If the copy step broke, the cause is visible and blocking: the build fails, or the dep-impact
/apicheck (.swagger-ui .opblockcount) shows the page as broken. - Other pages change only by losing unused Tailwind utilities that came from Swagger's bundles. Those classes weren't used anywhere else in Learn's sources.
- This changes earlier policy decisions: Swagger kept out of Dependabot groups, and the vendor contract required at build time. @ktsaou needs to agree before merge.
Summary by cubic
/api now serves Swagger UI copied from the locked swagger-ui-dist package at build/start time instead of a committed vendor copy, so Dependabot bumps no longer fail the Netlify build or require a manual re-vendor step.
Notable changes
- The new
swagger-ui-assetsplugin stages the 11 filesapi.htmlloads into the gitignoredgenerated-static/swagger-ui/directory; the committed vendor copy, its contract, and the build-time verification script are removed. - The unused
swagger-uidependency is dropped (~80 fewer packages inyarn.lock), andswagger-ui-distis now grouped withbrowser-runtimein Dependabot. /oauth2-redirect.htmland its script are removed; the URL now 404s, but it was dead because the API spec has no OAuth2 scheme.- The
dependency-impactworkflow's author filter is commented out, so its advisory job also runs for non-Dependabot PR authors.
Merge notes
- The first deploy after merging will 404 on
/oauth2-redirect.html; backlinks to that path haven't been checked yet. - This reverses earlier decisions to keep Swagger out of Dependabot groups and to require a build-time vendor contract, so sign-off is needed before merge.
Summary by CodeRabbit
- Documentation
- Updated the API documentation to explain that Swagger UI assets are prepared during site builds and that builds fail if required assets are missing.
- Clarified that the site does not publish an OAuth2 redirect page and documented the assets needed if OAuth2 support is added.
- Updated analytics guidance to exclude only the API page from beacon and third-party analytics checks.
- Changes
- The OAuth2 redirect page is no longer published.