diff --git a/docs/.gitignore b/docs/.gitignore index c84232d732..f63378d3e9 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -20,3 +20,6 @@ node_modules/ # Hugo .hugo_build.lock + +# Netlify CLI (auto-generated, contains local paths) +.netlify/ diff --git a/docs/README.md b/docs/README.md index 4355dc0865..04a390f985 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,7 @@ The source files for the documentation are located in the [content](https://gith # Website -The PipeCD documentation website is built with [Hugo](https://gohugo.io/) and published at https://pipecd.dev +The PipeCD documentation website is built with [hugo](https://gohugo.io/) and hosted on [Netlify](https://www.netlify.com/), published at https://pipecd.dev # Docs workflow and versioning @@ -26,18 +26,37 @@ Here are the recommended flows for common documentation updates: If you find any issues related to the docs, we're happy to accept your help. -# How to run the website locally +# Hosting + +The site is hosted on Netlify with the following setup: +- **Build tool**: Hugo (extended) via `netlify.toml` configuration +- **Deploy trigger**: Automatic on push to `master` branch and version tags +- **Deploy previews**: Automatically generated for pull requests that modify `docs/` +- **Redirects**: `/docs/` redirects to the latest released version (configured in `netlify.toml`) + +# How to run website locally ## Prerequisite - [Hugo 0.148.2+extended](https://gohugo.io/) +- [Node.js 24+](https://nodejs.org/) ## Commands - -Run `make run/site` at the root directory of the repository and then access http://localhost:1313 - -> **Note for Windows users:** -> The `make run/site` command uses `make` and `grep`, which are not natively available in Windows PowerShell. You can either use an environment like WSL or run the Hugo command manually in PowerShell: -> ```powershell -> $env:RELEASE = (Select-String -Path RELEASE -Pattern "^tag:").Line.Split(":")[1].Trim() -> hugo server --source=docs -> ``` +1. Install Hugo theme dependencies: +``` +cd docs && npm install +``` +2. Run the development server: +``` +hugo server +``` +3. Access http://localhost:1313 + +# Netlify Configuration + +The Netlify build configuration is defined in [`netlify.toml`](./netlify.toml). Key settings: +- **Build command**: `npm ci && hugo --gc --minify` +- **Publish directory**: `public/` +- **Redirects**: `/docs/` → latest version docs +- **Security headers**: X-Frame-Options, X-XSS-Protection, etc. + +When a new release version is created, the `hack/gen-release-docs.sh` script automatically updates the redirect target in `netlify.toml`. diff --git a/docs/netlify.toml b/docs/netlify.toml new file mode 100644 index 0000000000..f726749d98 --- /dev/null +++ b/docs/netlify.toml @@ -0,0 +1,54 @@ +# Netlify configuration for PipeCD documentation site. +# Ref: https://docs.netlify.com/configure-builds/file-based-configuration/ + +[build] + # Build command reads the RELEASE tag from the root RELEASE file + # and passes it as an env var to Hugo (used by the latest_version shortcode). + command = "npm ci && RELEASE=$(grep '^tag:' ../RELEASE | awk '{print $2}') hugo --gc --minify" + publish = "public" + +[build.environment] + HUGO_VERSION = "0.148.2" + HUGO_ENV = "production" + NODE_VERSION = "24" + +# Redirect /docs/ to the latest released version. +# Don't update here manually. hack/gen-release-docs.sh does. +[[redirects]] + from = "/docs/*" + to = "/docs-v1.0.x/:splat" + status = 302 + force = true + +# Redirect /docs (without trailing slash) as well. +[[redirects]] + from = "/docs" + to = "/docs-v1.0.x/" + status = 302 + force = true + +# Custom 404 page. +[[redirects]] + from = "/*" + to = "/404.html" + status = 404 + +# Headers for security and caching. +[[headers]] + for = "/*" + [headers.values] + X-Frame-Options = "DENY" + X-XSS-Protection = "1; mode=block" + X-Content-Type-Options = "nosniff" + Referrer-Policy = "strict-origin-when-cross-origin" + +# Cache static assets aggressively. +[[headers]] + for = "/images/*" + [headers.values] + Cache-Control = "public, max-age=31536000, immutable" + +[[headers]] + for = "/favicons/*" + [headers.values] + Cache-Control = "public, max-age=31536000, immutable" diff --git a/hack/gen-release-docs.sh b/hack/gen-release-docs.sh index c90e702505..f742a34293 100755 --- a/hack/gen-release-docs.sh +++ b/hack/gen-release-docs.sh @@ -65,4 +65,10 @@ mv docs/config.toml.tmp docs/config.toml sed "s/const latestPath.*/const latestPath = \"\/docs-"$VERSION"\/\"/g" docs/main.go > docs/main.go.tmp mv docs/main.go.tmp docs/main.go +# Update docs/netlify.toml redirect to point to new latest version +sed "s|to = \"/docs-.*/:splat\"|to = \"/docs-$VERSION/:splat\"|g" docs/netlify.toml > docs/netlify.toml.tmp +mv docs/netlify.toml.tmp docs/netlify.toml +sed "s|to = \"/docs-.*/\"|to = \"/docs-$VERSION/\"|g" docs/netlify.toml > docs/netlify.toml.tmp +mv docs/netlify.toml.tmp docs/netlify.toml + echo "Version docs has been prepared successfully at $CONTENT_DIR/docs-$VERSION/"