Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/deploy-trigger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Lives on the release/* branches. A push to a release branch cannot run main's
# deploy workflow directly (push-triggered workflows run from the pushed branch),
# so this dispatches the deploy workflow (hugo.yaml) on main, which rebuilds
# every version and deploys to GitHub Pages.
#
# It also sits on main (harmless — main never matches release/**) so that future
# release branches cut from main inherit it automatically.
name: Trigger docs deploy

on:
push:
branches:
- 'release/**'

permissions:
actions: write

jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Dispatch deploy on main
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh workflow run hugo.yaml --repo "${{ github.repository }}" --ref main
23 changes: 11 additions & 12 deletions .github/workflows/hugo.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Sample workflow for building and deploying a Hugo site to GitHub Pages
# Builds every released version (apex + /vX.Y/ subpaths) from the release/*
# branches and deploys them to GitHub Pages. Run manually, or dispatched by
# deploy-trigger.yml (which lives on the release/* branches) on each release push.
name: Deploy Hugo site to Pages

on:
Expand Down Expand Up @@ -32,30 +34,27 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
- name: Fetch release branches
run: git fetch --no-tags origin '+refs/heads/release/*:refs/remotes/origin/release/*'
- name: Setup Hugo
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with:
hugo-version: '0.147.7'
hugo-version: '0.122.0' # version every release site was built with; .Err needs < 0.141
extended: true
- name: Install Dart Sass
run: sudo snap install dart-sass
- name: Install yq
run: sudo snap install yq
- name: Setup Pages
id: pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
- name: Install Node.js dependencies
run: " npm install --save-dev autoprefixer postcss-cli && npm ci || true"
- name: Update Hugo Modules
run: hugo mod get -u ./...
- name: Build with Hugo
- name: Build all versions
env:
# For maximum backward compatibility with Hugo modules
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
hugo \
--gc \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/"
BASE_URL: ${{ steps.pages.outputs.base_url }}
run: bash scripts/build-site.sh
- name: Upload artifact
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
with:
Expand Down
26 changes: 25 additions & 1 deletion netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,28 @@ HUGO_VERSION = "0.145.0"
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"
GO_VERSION = "1.24.1"
NODE_VERSION = "23.6.0"
NODE_VERSION = "23.6.0"

# Versioned docs now build on GitHub Pages at /vX.Y/ subpaths. Redirect the
# legacy per-version subdomains there; add each release-0-XX.projectcapsule.dev
# as a domain alias of this site so the host-based matches fire.
[[redirects]]
from = "https://release-0-10.projectcapsule.dev/*"
to = "https://projectcapsule.dev/v0.10/:splat"
status = 301
force = true
[[redirects]]
from = "https://release-0-11.projectcapsule.dev/*"
to = "https://projectcapsule.dev/v0.11/:splat"
status = 301
force = true
[[redirects]]
from = "https://release-0-12.projectcapsule.dev/*"
to = "https://projectcapsule.dev/v0.12/:splat"
status = 301
force = true
[[redirects]]
from = "https://release-0-13.projectcapsule.dev/*"
to = "https://projectcapsule.dev/v0.13/:splat"
status = 301
force = true
93 changes: 93 additions & 0 deletions scripts/build-site.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env bash
#
# Build every released version of the docs for GitHub Pages:
# $OUTPUT/ -> latest release (apex)
# $OUTPUT/vX.Y/ -> each release/X.Y branch, pinned
# Per-version config is injected at build time, so release branches carry only
# content. Env overrides: BASE_URL, OUTPUT.
set -euo pipefail

BASE_URL="${BASE_URL:-https://projectcapsule.dev}"
BASE_URL="${BASE_URL%/}"
OUTPUT="${OUTPUT:-public}"
[[ "${OUTPUT}" == /* ]] || OUTPUT="$(pwd)/${OUTPUT}"
readonly BASE_URL OUTPUT

# Emit the version-selector dropdown list as YAML (newest first; latest tagged).
# Globals: versions, latest, BASE_URL.
dropdown_yaml() {
local v label url
for v in "${versions[@]}"; do
label="v${v}"
url="${BASE_URL}/v${v}/"
if [[ "${v}" == "${latest}" ]]; then
label="${label} (latest)"
url="${BASE_URL}/" # latest is served at the apex, not /vX.Y/
fi
printf -- '- version: %s\n url: %s\n' "${label}" "${url}"
done
}

# Build one version with the per-version config injected.
# Arguments: version (X.Y), baseURL, dest dir, archived (true|false).
# Globals: latest, VERSIONS_YAML.
build_one() {
local version="$1" baseurl="$2" dest="$3" archived="$4"
local menu wt
menu="v${version}"
[[ "${version}" == "${latest}" ]] && menu="${menu} (latest)"
# Worktree under $RUNNER_TEMP, not /tmp: snap yq/dart-sass have a private /tmp
wt="$(mktemp -d "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/build-site.XXXXXX")"
echo "==> building v${version} (archived=${archived})"
git worktree add --force --detach "${wt}" \
"origin/release/${version}" >/dev/null
(
Comment on lines +42 to +44
cd "${wt}" || exit 1
VERSION="v${version}" MENU="${menu}" ARCHIVED="${archived}" \
LATEST_URL="${BASE_URL}/" yq -i '
.version = strenv(VERSION)
| .version_menu = strenv(MENU)
| .archived_version = (strenv(ARCHIVED) == "true")
| .url_latest_version = strenv(LATEST_URL)
| .versions = (strenv(VERSIONS_YAML) | from_yaml)
' config/_default/params.yaml
# Subpath builds: point the selector at each version's home.
yq -i '.params.version_menu_pagelinks = false' config/_default/hugo.yaml
npm ci --no-audit --no-fund >/dev/null 2>&1 \
|| npm install --no-audit --no-fund >/dev/null 2>&1 || true
Comment on lines +56 to +57
hugo --gc --minify --baseURL "${baseurl}" --destination "${dest}"
)
git worktree remove --force "${wt}"
}

main() {
rm -rf "${OUTPUT}"
mkdir -p "${OUTPUT}"

# release/X.Y branches, newest first (ignores patch/preview branches).
mapfile -t versions < <(
git for-each-ref --format='%(refname:lstrip=-1)' \
"refs/remotes/origin/release/" \
| grep -E '^[0-9]+\.[0-9]+$' \
| sort -rV)
if [[ "${#versions[@]}" -eq 0 ]]; then
echo "no release/X.Y branches found" >&2
exit 1
fi
latest="${versions[0]}"

VERSIONS_YAML="$(dropdown_yaml)"
export VERSIONS_YAML

local v archived
for v in "${versions[@]}"; do
archived=true
[[ "${v}" == "${latest}" ]] && archived=false
build_one "${v}" "${BASE_URL}/v${v}/" "${OUTPUT}/v${v}" "${archived}"
done
build_one "${latest}" "${BASE_URL}/" "${OUTPUT}" false

echo "==> done: ${versions[*]} (latest v${latest})"
}

main "$@"