feat(site): add versioned docs infrastructure#1314
Conversation
Wire up the `site/v10` branch as the production deploy target for videojs.org, with `main` serving next.videojs.org for pre-release docs. - CD workflow force-pushes `site/v10` to main's HEAD after npm publish - Astro site URL resolves per Netlify context (production / branch / preview) - Turbo SCM base set to HEAD~1 so deploy-ignore works on all branches - Branch deploys get X-Robots-Tag: noindex to prevent search indexing Closes #645 https://claude.ai/code/session_01W6Sb7pTX66ZMbekoJKrnU7
✅ Deploy Preview for vjs10-site ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📦 Bundle Size Report🎨 @videojs/html — no changesPresets (7)
Media (8)
Players (3)
Skins (17)
UI Components (24)
Sizes are marginal over the root entry point. ⚛️ @videojs/react — no changesPresets (7)
Media (7)
Skins (14)
UI Components (19)
Sizes are marginal over the root entry point. 🧩 @videojs/core — no changesEntries (8)
🏷️ @videojs/element — no changesEntries (2)
📦 @videojs/store — no changesEntries (3)
🔧 @videojs/utils — no changesEntries (10)
📦 @videojs/spf — no changesEntries (3)
ℹ️ How to interpretAll sizes are standalone totals (minified + brotli).
Run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Context-scoped headers not supported in netlify.toml
- Replaced unsupported context-scoped headers with a branch-deploy build command that writes a publish-directory
_headersfile containingX-Robots-Tag: noindex.
- Replaced unsupported context-scoped headers with a branch-deploy build command that writes a publish-directory
- ✅ Fixed:
BRANCHenv var missing from turboglobalEnvcache key- Added
BRANCHtoglobalEnvinturbo.jsonso Turbo cache invalidates when branch-dependent site URL logic changes.
- Added
Or push these changes by commenting:
@cursor push 9424c4f07d
Preview (9424c4f07d)
diff --git a/site/netlify.toml b/site/netlify.toml
--- a/site/netlify.toml
+++ b/site/netlify.toml
@@ -11,15 +11,11 @@
TURBO_SCM_BASE = "HEAD~1"
# Prevent search engines from indexing branch deploys (next.videojs.org).
-# Stable docs at videojs.org (production context) are not affected.
-[context.branch-deploy.environment]
- X_ROBOTS_TAG = "noindex"
+# Netlify cannot scope headers by context, so branch deploys generate a
+# context-specific _headers file in the publish directory during build.
+[context.branch-deploy]
+ command = "pnpm build:site && echo '/*' > site/dist/_headers && echo ' X-Robots-Tag: noindex' >> site/dist/_headers"
-[[context.branch-deploy.headers]]
- for = "/*"
- [context.branch-deploy.headers.values]
- X-Robots-Tag = "noindex"
-
# PostHog reverse proxy (ad-blocker bypass)
[[redirects]]
from = "/ph/static/*"
diff --git a/turbo.json b/turbo.json
--- a/turbo.json
+++ b/turbo.json
@@ -2,7 +2,7 @@
"$schema": "https://turbo.build/schema.json",
"ui": "stream",
"concurrency": "20",
- "globalEnv": ["CONTEXT", "DEPLOY_PRIME_URL"],
+ "globalEnv": ["CONTEXT", "DEPLOY_PRIME_URL", "BRANCH"],
"tasks": {
"build": {
"dependsOn": ["^build", "^build:cdn"],This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
|
Review note: branch protection needed on The cherry-pick hotfix workflow depends on the rule that all fixes land on After merge, add a branch protection rule for
This keeps the force-push safe by design rather than by team policy. |
- Replace invalid [[context.branch-deploy.headers]] in netlify.toml with a <meta name="robots" content="noindex"> tag in Base.astro. Netlify headers can't be scoped per deploy context, but comparing Astro.site against PRODUCTION_URL achieves the same result and works with any host. - Add BRANCH to turbo.json globalEnv so the build cache invalidates when the Netlify branch changes (SITE_URL now depends on it). https://claude.ai/code/session_01W6Sb7pTX66ZMbekoJKrnU7
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 75222bf. Configure here.
|
|
||
| - name: Update site/v10 branch | ||
| if: ${{ steps.release.outputs.releases_created == 'true' }} | ||
| run: git push origin HEAD:refs/heads/site/v10 --force |
There was a problem hiding this comment.
Force-push uses GITHUB_TOKEN, incompatible with planned branch protection
High Severity
The git push --force to site/v10 uses the default GITHUB_TOKEN credentials (from actions/checkout at line 35, which doesn't specify a token). The GITHUB_TOKEN cannot bypass branch protection rules. Once the planned branch protection is added to site/v10 (restricting pushes to the CD bot's PAT), this force-push will fail, breaking the entire release-to-production docs pipeline. The actions/checkout step needs to use token: ${{ secrets.V10_WORKFLOW_TRIGGER_WORKFLOW_GH_TOKEN }} (the PAT already available in this workflow) so the push inherits credentials that can bypass branch protection.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 75222bf. Configure here.



Summary
Implements the infrastructure for versioned docs (#645). After this PR merges, the docs deploy pipeline works like this:
How it works
Two sites, two branches:
site/v10(production)main(branch deploy)Release flow:
Between releases,
mainkeeps advancing with new features and docs.site/v10stays pinned to the last release point. Netlify buildsmainon every push and deploys it tonext.videojs.org, so unreleased docs are always accessible without polluting the stable site.Docs hotfixes between releases:
If a typo or content fix lands on
mainand needs to go live before the next release, cherry-pick it frommaintosite/v10:All fixes must land on
mainfirst. Thesite/v10branch should have branch protection restricting direct pushes to the CD bot (see manual steps below). On the next release, the force-push resetssite/v10tomain's HEAD, which already includes the cherry-picked commit.Changes
.github/workflows/cd.ymlHEADtosite/v10. This ensures the docs branch only advances after packages are successfully published. Usescontents: writepermission already present on the job.site/astro.config.mjsSITE_URLto resolve per Netlify deploy context using theCONTEXTandBRANCHenv vars that Netlify provides automatically:CONTEXT=production→https://videojs.org(stable docs fromsite/v10)BRANCH=main→https://next.videojs.org(pre-release docs)DEPLOY_PRIME_URL(Netlify subdomain, for PR previews)PRODUCTION_URLinconsts.tsis unchanged — canonical URLs and JSON-LD always point tovideojs.orgregardless of deploy context.site/netlify.tomlTURBO_SCM_BASE = "HEAD~1"scoped tocontext.productionandcontext.branch-deploy. Without this,turbo query affectedcomputes the merge-base of the current branch withmain. Onsite/v10(which is a point onmain's history) and onmainitself, that merge-base isHEAD— meaning zero changes, meaning the build gets skipped.HEAD~1compares against the previous commit instead. This is scoped to production and branch-deploy only so PR previews keep the default merge-base behavior (which correctly detects all changes across a PR's commits).X-Robots-Tag: noindexheader for branch deploys. This prevents search engines from indexingnext.videojs.org, so pre-release docs don't compete with stable docs in search results. The production context (videojs.org) is not affected.site/CLAUDE.mdandsite/README.mdManual steps required after merge
These are Netlify UI settings that can't be configured via
netlify.toml:maintosite/v10in Netlify site settings → Build & deploy → Continuous Deployment → Branches and deploy contextsmainin the same settings panelnext.videojs.orgfor themainbranch deploy (exact approach TBD — branch subdomain vs. separate domain alias)site/v10— restrict direct pushes to the CD workflow's token only. Human contributors cherry-pick via PR targetingsite/v10.Future versioning
When v11 ships someday, the pattern extends naturally:
site/v11becomes the new production branch →videojs.orgsite/v10gets pointed atv10.videojs.org(the existing redirect would be updated)maincontinues servingnext.videojs.orgRelated
Test plan
cd.ymlchange: theUpdate site/v10 branchstep has the correctifguard and runs after publishastro.config.mjs: local dev still works (CONTEXTandBRANCHare undefined → falls back tohttps://videojs.org)site/v10, enable branch deploys formain, set upnext.videojs.orgdomainsite/v10(restrict pushes to CD bot)mainX-Robots-Tag: noindexheader is present on next.videojs.org responsessite/v10gets force-pushed to the release commitNote
Medium Risk
Introduces a force-push-based release step and deploy-context URL/SEO behavior changes, which can affect production docs publishing and indexing if misconfigured.
Overview
Implements a two-branch docs deployment flow: releases now publish to npm and then force-push the release commit to
site/v10so Netlify production can track stable docs, whilemainremains a pre-release branch deploy.Updates the Astro/Netlify build and SEO behavior for this split:
SITE_URLnow resolves based on NetlifyCONTEXT/BRANCH, Turbo build skipping is avoided viaTURBO_SCM_BASE=HEAD~1on production/branch-deploy, and non-production origins emitrobots: noindex.Adds documentation in
site/CLAUDE.mdandsite/README.mddescribing the release sync, hotfix cherry-pick workflow, and branch protection expectations.Reviewed by Cursor Bugbot for commit 75222bf. Bugbot is set up for automated code reviews on this repo. Configure here.