From c4dfa3e49b80f3f0f1037316c3253d6d737d7d78 Mon Sep 17 00:00:00 2001 From: Darius Cepulis Date: Tue, 14 Apr 2026 07:50:29 -0500 Subject: [PATCH] feat(site): add versioned docs infrastructure (#1314) Co-authored-by: Claude --- .github/workflows/cd.yml | 4 ++++ site/CLAUDE.md | 23 +++++++++++++++++++++++ site/README.md | 13 +++++++++++++ site/astro.config.mjs | 15 ++++++++++----- site/netlify.toml | 11 +++++++++++ site/src/layouts/Base.astro | 1 + turbo.json | 2 +- 7 files changed, 63 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index db53e206..c2b01fde 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -77,3 +77,7 @@ jobs: - name: Publish if: ${{ steps.release.outputs.releases_created == 'true' }} run: pnpm -r publish --filter "./packages/*" --access public --provenance --no-git-checks + + - name: Update site/v10 branch + if: ${{ steps.release.outputs.releases_created == 'true' }} + run: git push origin HEAD:refs/heads/site/v10 --force diff --git a/site/CLAUDE.md b/site/CLAUDE.md index 1109706f..4dda848d 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -8,6 +8,29 @@ The **Video.js v10 documentation site** is an Astro-based static site generator Key architectural feature: **Multi-framework documentation** — the same content generates separate routes for different framework/style combinations (e.g., HTML + CSS, React + CSS), allowing framework-specific documentation from shared MDX sources. +## Deployment + +The site deploys via Netlify from two branches: + +| Branch | Deploys to | Content | +| --- | --- | --- | +| `site/v10` (production) | **videojs.org** | Stable docs matching the latest release | +| `main` (branch deploy) | **next.videojs.org** | Pre-release docs (may include unreleased APIs) | + +**On release:** The CD workflow (`.github/workflows/cd.yml`) publishes packages to npm, then force-pushes `main`'s HEAD to `site/v10`. This keeps the production docs in sync with the latest release. + +**Docs hotfixes between releases:** Fix the content on `main` first, then cherry-pick to `site/v10`: + +```bash +git checkout site/v10 +git cherry-pick +git push origin site/v10 +``` + +The next release force-pushes `main` to `site/v10`, which already includes the cherry-picked commit (since it originated on `main`). All fixes must land on `main` first — the `site/v10` branch has branch protection that restricts direct pushes to the CD bot. + +**Branch deploys (next.videojs.org)** serve `X-Robots-Tag: noindex` headers to prevent search engines from indexing pre-release docs. + ## Commands From `site/` directory: diff --git a/site/README.md b/site/README.md index 9ac80beb..0e2fbc1b 100644 --- a/site/README.md +++ b/site/README.md @@ -66,6 +66,19 @@ If you're in `site/`... | `pnpm test:ui` | Run Vitest with its web-based UI | | `pnpm test:coverage` | Generate test coverage report | +## Deployment + +The site deploys via Netlify from two branches: + +| Branch | Deploys to | Content | +| :--- | :--- | :--- | +| `site/v10` | **videojs.org** | Stable docs matching the latest release | +| `main` | **next.videojs.org** | Pre-release docs (may include unreleased APIs) | + +On each release, the CD workflow force-pushes `main` to `site/v10`, keeping production docs in sync with published packages. + +**Fixing a typo without cutting a release:** Land the fix on `main` first, then cherry-pick to `site/v10`. The next release's force-push already includes the fix (since it came from `main`), so nothing gets lost. The `site/v10` branch is protected — direct pushes are restricted to the CD bot. + ## Environment Variables The installation page's video uploader uses OAuth + Mux. See [CLAUDE.md](CLAUDE.md) for the full list of environment variables. The site works without these — the uploader just won't be available. diff --git a/site/astro.config.mjs b/site/astro.config.mjs index f74281fd..109c3261 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -17,15 +17,20 @@ import { remarkReadingTime } from './src/utils/remarkReadingTime.mjs'; import { shikiNotationTransformers } from './src/utils/shikiNotationTransformers'; import shikiTransformMetadata from './src/utils/shikiTransformMetadata'; -// On production deploys, use the custom domain — DEPLOY_PRIME_URL always returns -// the Netlify subdomain (e.g. main--vjs10-site.netlify.app), not the custom -// domain. On deploy previews, use DEPLOY_PRIME_URL so OG images point to a -// reachable URL for crawlers. +// Netlify sets CONTEXT and BRANCH for each deploy. We use them to determine +// the correct site URL: +// - production (site/v10 branch) → https://videojs.org +// - branch-deploy (main branch) → https://next.videojs.org +// - deploy-preview (PR branches) → DEPLOY_PRIME_URL (Netlify subdomain) // // For URLs that must always point to production regardless of deploy context // (e.g. canonical, JSON-LD), use PRODUCTION_URL from src/consts.ts instead. const SITE_URL = - process.env.CONTEXT === 'production' ? 'https://videojs.org' : process.env.DEPLOY_PRIME_URL || 'https://videojs.org'; + process.env.CONTEXT === 'production' + ? 'https://videojs.org' + : process.env.BRANCH === 'main' + ? 'https://next.videojs.org' + : process.env.DEPLOY_PRIME_URL || 'https://videojs.org'; // https://astro.build/config export default defineConfig({ diff --git a/site/netlify.toml b/site/netlify.toml index 7ba80a0d..3ffe1114 100644 --- a/site/netlify.toml +++ b/site/netlify.toml @@ -3,6 +3,17 @@ publish = "site/dist" ignore = "pnpm turbo query affected --packages site --tasks build --exit-code" +# turbo query affected defaults to comparing against the merge-base with main. +# On the production branch (site/v10) and main itself, that merge-base is HEAD, +# so turbo finds zero changes and skips the build. HEAD~1 compares against the +# previous commit instead. We scope this to production and branch-deploy only — +# PR previews keep the default merge-base behavior so multi-commit pushes work. +[context.production.environment] + TURBO_SCM_BASE = "HEAD~1" + +[context.branch-deploy.environment] + TURBO_SCM_BASE = "HEAD~1" + # PostHog reverse proxy (ad-blocker bypass) [[redirects]] from = "/ph/static/*" diff --git a/site/src/layouts/Base.astro b/site/src/layouts/Base.astro index 5b3c47b2..6dcbfc81 100644 --- a/site/src/layouts/Base.astro +++ b/site/src/layouts/Base.astro @@ -58,6 +58,7 @@ const fullTitle = /> + {Astro.site?.origin !== PRODUCTION_URL.origin && } {/* Analytics (production only) */} {import.meta.env.PROD && } diff --git a/turbo.json b/turbo.json index 229b70bb..d2d50115 100644 --- 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": ["BRANCH", "CONTEXT", "DEPLOY_PRIME_URL"], "tasks": { "build": { "dependsOn": ["^build", "^build:cdn"],