Skip to content
Open
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
12 changes: 9 additions & 3 deletions docs/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ archived_version = false
version = "latest"

# The version of the latest code build
latestTag = "1.5.7"
latestTag = "1.5.9"

# latest tested versions
version_docker = "v28.1.1"
Expand All @@ -102,7 +102,7 @@ version_kpt = "v1.0.0-beta.62.1"
# A link to latest version of the docs. Used in the "version-banner" partial to
# point people to the main doc site.

url_latest_version = "https://docs.porch.nephio.org/docs/"
url_latest_version = "/docs/"

# Repository configuration (URLs for in-page links to opening issues and suggesting changes)

Expand Down Expand Up @@ -239,7 +239,13 @@ enable = false
# desc = "Discuss development issues around the project"

# Add your release versions here
# Each entry appears in the version selector dropdown in the navbar.
# The first entry should be the current/latest version.

[[params.versions]]
version = "latest"
url = "https://docs.porch.nephio.org/docs/"
url = "/"

[[params.versions]]
version = "v1.5"
url = "/v1.5/"
2 changes: 1 addition & 1 deletion docs/netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[build]
base = "docs"
command = "hugo --environment $HUGO_ENV --config config.toml,config/$HUGO_ENV.toml"
command = "../scripts/build-versioned-docs.sh"
publish = "public"
ignore = "false" # Always build

Expand Down
12 changes: 12 additions & 0 deletions docs/versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"version": "latest",
"tag": null,
"path": "/"
},
{
"version": "v1.5",
"tag": "v1.5.9",
"path": "/v1.5/"
}
Comment on lines +1 to +11
]
162 changes: 162 additions & 0 deletions scripts/build-versioned-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/usr/bin/env bash
# Copyright 2026 The kpt and Nephio Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# build-versioned-docs.sh
#
# Builds versioned Hugo documentation from git tags.
# Reads docs/versions.json to determine which versions to build.
# Produces a combined output directory suitable for Netlify deployment.
#
# Usage:
# ./scripts/build-versioned-docs.sh [output-dir]
#
# Environment:
# HUGO_ENV - Hugo environment (default: production)

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
DOCS_DIR="${REPO_ROOT}/docs"
OUTPUT_DIR="${1:-${DOCS_DIR}/public}"
HUGO_ENV="${HUGO_ENV:-production}"

# Ensure required tools are available
for cmd in hugo git npm; do
if ! command -v "${cmd}" &> /dev/null; then
echo "ERROR: ${cmd} is required but not installed." >&2
exit 1
fi
done
Comment on lines +36 to +42

VERSIONS_FILE="${DOCS_DIR}/versions.json"
if [[ ! -f "${VERSIONS_FILE}" ]]; then
echo "ERROR: ${VERSIONS_FILE} not found." >&2
exit 1
fi

echo "==> Building versioned docs"
echo " Output: ${OUTPUT_DIR}"
echo " Versions file: ${VERSIONS_FILE}"
echo ""

# Ensure we have all tags (Netlify may do shallow clones)
echo "==> Fetching tags..."
git -C "${REPO_ROOT}" fetch --unshallow 2>/dev/null || true
git -C "${REPO_ROOT}" fetch --tags --force 2>/dev/null || true
echo ""

# Clean output directory
rm -rf "${OUTPUT_DIR}"
mkdir -p "${OUTPUT_DIR}"

# Build the main/latest version from the current working tree
echo "==> Building latest (main) docs..."
(
cd "${DOCS_DIR}"

# Install npm dependencies (needed for PostCSS/autoprefixer)
if [[ -f "package.json" ]]; then
npm install --quiet 2>/dev/null || true
fi

hugo --gc --minify \
--environment "${HUGO_ENV}" \
--destination "${OUTPUT_DIR}" \
-b "/"
)
echo " Done: latest -> /"
echo ""

# Parse versions.json and build each tagged version.
# Uses grep/sed to extract entries — versions.json has a known, simple structure.
# Outputs tab-separated lines: version\ttag\tpath (skipping entries with null tag)
TAGGED_VERSIONS=$(awk '
/"version"/ { gsub(/[",]/, ""); version=$2 }
/"tag"/ { gsub(/[",]/, ""); tag=$2 }
/"path"/ { gsub(/[",]/, ""); path=$2; if (tag != "null" && tag != "") print version "\t" tag "\t" path }
' "${VERSIONS_FILE}")

while IFS=$'\t' read -r VERSION TAG URL_PATH; do
[[ -z "${VERSION}" ]] && continue

echo "==> Building ${VERSION} from tag ${TAG}..."

# Verify tag exists
if ! git -C "${REPO_ROOT}" rev-parse "${TAG}" &>/dev/null; then
echo " WARNING: Tag ${TAG} not found, skipping." >&2
continue
fi

# Create a temporary directory for the tagged docs
TEMP_DIR=$(mktemp -d)

# Extract the docs directory from the tag
git -C "${REPO_ROOT}" archive "${TAG}" -- docs/ | tar -x -C "${TEMP_DIR}"

# Remove existing [[params.versions]] entries from the tagged config
# to prevent duplication when our override config is merged
sed -i '/^\[\[params\.versions\]\]/,/^$/d' "${TEMP_DIR}/docs/config.toml"

# Fix hardcoded absolute paths in content files so they respect the versioned baseURL.
# Raw HTML links in Hugo shortcodes bypass baseURL processing.
find "${TEMP_DIR}/docs/content" -name "*.md" -exec \
sed -i "s|href=\"/docs|href=\"${URL_PATH}docs|g" {} \;
Comment on lines +109 to +116
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI discovered potential issue as i would not have found this but apparently on MacOS sed parses slightly differently e.g. On macOS, sed -i requires an empty string argument (sed -i '') and If contributors build docs locally on macOS, this will fail. Since it runs on Netlify (Linux), it's fine for CI.

We would need someone using MacOS to confirm it.

Did a bit of digging and found the following which explains it here

Suggested change
# Remove existing [[params.versions]] entries from the tagged config
# to prevent duplication when our override config is merged
sed -i '/^\[\[params\.versions\]\]/,/^$/d' "${TEMP_DIR}/docs/config.toml"
# Fix hardcoded absolute paths in content files so they respect the versioned baseURL.
# Raw HTML links in Hugo shortcodes bypass baseURL processing.
find "${TEMP_DIR}/docs/content" -name "*.md" -exec \
sed -i "s|href=\"/docs|href=\"${URL_PATH}docs|g" {} \;
# Remove existing [[params.versions]] entries from the tagged config
# to prevent duplication when our override config is merged
sed -i'' -e '/^\[\[params\.versions\]\]/,/^$/d' "${TEMP_DIR}/docs/config.toml"
# Fix hardcoded absolute paths in content files so they respect the versioned baseURL.
# Raw HTML links in Hugo shortcodes bypass baseURL processing.
find "${TEMP_DIR}/docs/content" -name "*.md" -exec \
sed -i'' -e "s|href=\"/docs|href=\"${URL_PATH}docs|g" {} \;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is well known by MacOS users, especially the different behavoiour of the -i parameter. We usually just do some hackery to override the MacOS stock sed with gsed, the Linux-compatible one. I have done this

% which sed
/usr/local/bin/sed
% ls -l /usr/local/bin/sed
lrwxr-xr-x  1 root  admin  22 15 May 14:10 /usr/local/bin/sed -> /opt/homebrew/bin/gsed
% sed --version
sed (GNU sed) 4.10

So in short it is fine to ignore this comment.


# Create a config overlay to mark this as an archived version
VERSION_OUTPUT="${OUTPUT_DIR}${URL_PATH}"
mkdir -p "${VERSION_OUTPUT}"

# Generate the versions list for the override config from versions.json
VERSIONS_TOML=$(awk '
/"version"/ { gsub(/[",]/, ""); ver=$2 }
/"path"/ { gsub(/[",]/, ""); path=$2; print "[[params.versions]]"; print " version = \"" ver "\""; print " url = \"" path "\""; print "" }
' "${VERSIONS_FILE}")

cat > "${TEMP_DIR}/docs/config-version-override.toml" <<EOF
[params]
archived_version = true
version = "${VERSION}"
url_latest_version = "/docs/"
version_menu = "Releases"

${VERSIONS_TOML}
EOF

(
cd "${TEMP_DIR}/docs"

# Install npm dependencies if package.json exists (needed for PostCSS/autoprefixer)
if [[ -f "package.json" ]]; then
npm install --quiet 2>/dev/null || true
fi

hugo --gc --minify \
--environment "${HUGO_ENV}" \
--destination "${VERSION_OUTPUT}" \
-b "${URL_PATH}" \
--config config.toml,config-version-override.toml
)

echo " Done: ${VERSION} -> ${URL_PATH}"
echo ""

# Clean up temp dir
rm -rf "${TEMP_DIR}"
Comment on lines +156 to +157
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will only cleanup if its reached no? what if the script exists early for some reason? on github netlify build runners that's not an issue and these get wiped anyways but if people build locally and crash occurs their tmp dir's will leave a the temp_dir behind on every crash no?

Not a big deal but just a thought

done <<< "${TAGGED_VERSIONS}"

echo "==> All versions built successfully."
echo " Output directory: ${OUTPUT_DIR}"
ls -la "${OUTPUT_DIR}"
Loading