Skip to content
Merged
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
163 changes: 108 additions & 55 deletions .github/workflows/fern-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -284,37 +284,54 @@ jobs:

- name: Propagate shared Reference nav to released versions
run: |
# The Reference tab's General variant (Compatibility, Release
# Artifacts, Releases, Known Issues, Deprecations, Model EA Builds,
# Glossary) is SHARED across versions: release snapshots keep its nav
# paths on ../pages-dev/ so every version dropdown renders the
# The Reference tab's General group (Compatibility, Examples, Release
# Artifacts, Releases, Model EA Builds, Glossary, Releases
# machine-readable) is SHARED across versions: release snapshots keep
# its nav paths on ../pages-dev/ so every version dropdown renders the
# always-current reference. When a page is added to the shared
# reference on main (e.g. a new release-notes page), copy the
# variant's nav block from dev.yml into each released version's yml
# so the new page appears in every dropdown, not just dev. Version
# snapshots cut before the reference rework have no such variant and
# are left untouched (the yq selection matches nothing).
yq '[.navigation[] | select(.tab == "reference") | .variants[] | select(.title == "General")][0]' \
docs-checkout/fern/versions/dev.yml > /tmp/reference_general_variant.yml

if [ "$(yq 'length' /tmp/reference_general_variant.yml)" = "0" ] || \
[ "$(head -c4 /tmp/reference_general_variant.yml)" = "null" ]; then
echo "No shared Reference General variant in dev.yml; skipping propagation"
else
for vfile in docs-checkout/fern/versions/v*.yml; do
[ -e "$vfile" ] || continue
# Only rewrite files that actually carry the shared variant —
# yq -i normalizes whitespace, so touching pre-rework snapshots
# (which have no reference General variant) is pure churn.
if [ "$(yq '[.navigation[] | select(.tab == "reference") | .variants[] | select(.title == "General")] | length' "$vfile")" != "0" ]; then
yq -i '(.navigation[] | select(.tab == "reference") | .variants[] | select(.title == "General")) = load("/tmp/reference_general_variant.yml")' "$vfile"
echo "Synced shared Reference nav into $vfile"
else
echo "Skipped (no shared Reference variant): $vfile"
fi
done
# reference on main (e.g. a new release-notes page), copy those nav
# entries from dev.yml into each released version's yml so the new
# page appears in every dropdown, not just dev.
#
# The group is identified by CONTENT PATH (pages/reference/general/,
# rewritten to ../pages-dev/reference/general/ by the step above), not
# by a nav label. It used to key on `variants[] | select(.title ==
# "General")`; #12410 deliberately flattened the Reference tab into
# folded sections with no variant selector, and the label-keyed
# selector then matched nothing for six days without failing anything.
# Directory layout is the durable signal — IA work renames labels.
yq '[.navigation[] | select(.tab == "reference") | .layout[]
| select([.. | select(has("path")) | .path]
| all_c(test("/reference/general/")))]' \
docs-checkout/fern/versions/dev.yml > /tmp/reference_general_entries.yml

if [ "$(yq 'length' /tmp/reference_general_entries.yml)" = "0" ]; then
# Hard failure, not a warning. The pre-merge composition check
# (pre-merge.yml -> simulate_docs_website.sh) asserts the same
# condition, so this only trips if something bypassed it.
echo "::error::No shared Reference pages found under reference/general/ in dev.yml. Shared Reference is disabled and every version will freeze its own reference copy. Update the path key in this workflow and in docs/fern/scripts/simulate_docs_website.sh."
exit 1
fi

for vfile in docs-checkout/fern/versions/v*.yml; do
[ -e "$vfile" ] || continue
# Only rewrite files that already carry shared entries. Versions cut
# before the reference rework have no reference tab at all
# (v1.3.0.yml is `tab: docs`), and yq -i normalizes whitespace, so
# touching them is pure churn. This stays inert until the first tag
# is cut after the tab restructure.
if [ "$(yq '[.navigation[]? | select(.tab? == "reference") | .layout[]? | select([.. | select(has("path")) | .path] | all_c(test("/pages-dev/reference/general/")))] | length' "$vfile")" != "0" ]; then
ENTRIES=/tmp/reference_general_entries.yml \
yq -i '(.navigation[] | select(.tab == "reference") | .layout) |=
(load(strenv(ENTRIES))
+ [.[] | select([.. | select(has("path")) | .path]
| any_c(test("/pages-dev/reference/general/")) | not)])' "$vfile"
echo "Synced shared Reference nav into $vfile"
else
echo "Skipped (no shared Reference entries): $vfile"
fi
done

- name: Convert GitHub callouts to Fern format
run: |
echo "Converting GitHub-style callouts to Fern format in pages/..."
Expand Down Expand Up @@ -379,11 +396,17 @@ jobs:
# stylesheet in hosted builds, so previews of any fern/main.css change
# render unstyled. The repo main.css already carries the NVIDIA
# branding rules, so unthemed previews stay visually faithful.
if [ "${{ steps.ctx.outputs.is_main }}" = "true" ]; then
yq -i '.global-theme = "nvidia"' docs.yml
else
yq -i 'del(.global-theme)' docs.yml
fi
# Every hosted build gets the theme, previews included. The theme
# overrides the project css/js and the custom footer, so an unthemed
# preview renders under conditions that never ship -- it was faithful
# to `fern docs dev`, not to the live site, which is how unstyled Home,
# Community and blog pages reached production unnoticed.
#
# This does not change the source repo's docs.yml, which still omits
# global-theme so contributors can run `fern docs dev` without an
# nvidia-org FERN_TOKEN (#10073). The theme is injected only into the
# docs-checkout copy CI builds from.
yq -i '.global-theme = "nvidia"' docs.yml

echo "Updated docs.yml:"
cat docs.yml
Expand Down Expand Up @@ -476,6 +499,21 @@ jobs:
working-directory: docs-checkout/fern
run: fern generate --docs

# The global theme overrides the project `css:`/`js:` and the custom
# `footer:`, so any component relying on main.css publishes unstyled.
# Previews are themed too now, so this should be caught before merge --
# this is the backstop that proves it on the site people actually read.
# Retries cover CDN propagation.
#
# Runs on every main invocation, not only when has_changes: on a rerun
# the docs-website branch is already ahead of source-checkout, so
# has_changes flips false. The live pages still need re-verifying (a
# rerun is what a failed run turns into once triaged), so the check
# must not be gated on repository changes.
- name: Verify published pages carry their component CSS
if: steps.ctx.outputs.is_main == 'true'
run: python3 source-checkout/docs/fern/scripts/check_published_styles.py
Comment thread
dagil-nvidia marked this conversation as resolved.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
#############################################################################
# VERSION RELEASE - Run on new version tags (vX.Y.Z)
#############################################################################
Expand Down Expand Up @@ -601,22 +639,25 @@ jobs:
run: |
TAG="${{ steps.version.outputs.tag }}"

# The Reference tab's General variant is shared (always-current)
# across versions: its nav paths stay on ../pages-dev/ (see the
# version-config step), so drop exactly the files that variant
# references from the snapshot rather than freezing stale copies.
# Everything else under reference/ (observability pages, config
# references) belongs to versioned tabs and stays in the snapshot.
# If the selectors stop matching (tab or variant renamed), this and
# the version-config revert silently no-op and the reference quietly
# freezes per version again — warn loudly so the rename gets fixed.
if [ "$(yq '[.navigation[] | select(.tab == "reference") | .variants[] | select(.title == "General")] | length' docs-checkout/fern/versions/dev.yml)" = "0" ]; then
echo "::warning::No Reference General variant found in dev.yml — the shared-reference exclusion is a no-op and $TAG will freeze its own reference copy. If the tab or variant was renamed, update the yq selectors in this workflow."
# The Reference tab's General group is shared (always-current) across
# versions: its nav paths stay on ../pages-dev/ (see the
# version-config step), so drop those files from the snapshot rather
# than freezing stale copies. Everything else under reference/
# (Kubernetes API, Components, Backends, Observability, NIXL Connect)
# is genuinely per-version and stays in the snapshot.
#
# The group is a directory, so this is a plain path operation — no nav
# traversal, which also means no yq assignment that could auto-create
# keys in a file it is only meant to read.
SHARED="docs-checkout/fern/pages-$TAG/reference/general"
if [ ! -d "$SHARED" ]; then
# Hard failure: silently skipping is what let shared Reference rot
# unnoticed for six days. The pre-merge composition check asserts
# the same invariant, so reaching here means something bypassed it.
echo "::error::$SHARED not found — the shared-reference exclusion would be a no-op and $TAG would freeze its own reference copy. If reference/general/ was renamed, update the path key in this workflow and in docs/fern/scripts/simulate_docs_website.sh."
exit 1
fi
yq '.navigation[] | select(.tab == "reference") | .variants[] | select(.title == "General") | .. | select(has("path")) | .path' \
docs-checkout/fern/versions/dev.yml | sed 's|^\.\./pages-dev/||' | while read -r relpath; do
[ -n "$relpath" ] && rm -f "docs-checkout/fern/pages-$TAG/$relpath"
done
rm -rf "$SHARED"
find "docs-checkout/fern/pages-$TAG/reference" -type d -empty -delete 2>/dev/null || true

- name: Snapshot translation mirrors
Expand Down Expand Up @@ -732,13 +773,25 @@ jobs:
yq -i '(.. | select(has("path")).path) |= sub("^pages/home/index\.mdx$", "../index.mdx")' "$VERSION_FILE"
yq -i '(.. | select(has("path")).path) |= sub("^pages/", "../pages-'"$TAG"'/")' "$VERSION_FILE"

# Revert the Reference tab's General variant to the shared source:
# it is always-current across versions (release metadata is
# cumulative — each page carries per-release sections), so its pages
# render from pages-dev in every version (paired with the snapshot
# drop above). The Kubernetes API and Components variants stay on the
# frozen snapshot (CRD fields and config flags are genuinely per-version).
yq -i "(.navigation[] | select(.tab == \"reference\") | .variants[] | select(.title == \"General\") | .. | select(has(\"path\")).path) |= sub(\"\.\./pages-$TAG/\", \"../pages-dev/\")" "$VERSION_FILE"
# Revert the Reference tab's General group to the shared source: it is
# always-current across versions (release metadata is cumulative —
# each page carries per-release sections), so its pages render from
# pages-dev in every version (paired with the snapshot drop above).
# Kubernetes API, Components, Backends, Observability and NIXL Connect
# stay on the frozen snapshot (CRD fields and config flags are
# genuinely per-version).
#
# Keyed on the content path, and applied as a text substitution rather
# than a yq assignment. A yq assignment whose left-hand side traverses
# a missing key auto-creates it: the previous `.variants[]` form
# injected an empty `variants: []` once #12410 removed the variants,
# which invalidates the whole navigation against Fern's schema.
perl -pi -e "s|path: \.\./pages-$TAG/reference/general/|path: ../pages-dev/reference/general/|g" "$VERSION_FILE"

if ! grep -q "path: \.\./pages-dev/reference/general/" "$VERSION_FILE"; then
echo "::error::$VERSION_FILE has no shared reference/general/ paths after the revert; $TAG would freeze its own reference copy."
exit 1
fi

# Keep cross-navigation links within the selected documentation version.
sed -i "s|href: /dynamo/dev/|href: /dynamo/$TAG/|g" "$VERSION_FILE"
Expand Down
38 changes: 37 additions & 1 deletion .github/workflows/pre-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

pre-merge-status-check:
runs-on: ubuntu-latest
needs: [changed-files, pre-commit, fern-check, fern-broken-links, operator, snapshot, rust-tests, rust-clippy]
needs: [changed-files, pre-commit, fern-check, docs-website-composition, fern-broken-links, operator, snapshot, rust-tests, rust-clippy]
if: always()
steps:
- name: "Check all dependent jobs"
Expand Down Expand Up @@ -83,6 +83,42 @@ jobs:
working-directory: docs/fern
run: fern check

docs-website-composition:
name: Docs Website Composition Check
needs: changed-files
if: needs.changed-files.outputs.docs == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
# The sync and release-version composition (rsync scopes, nav path
# transforms, the shared-Reference machinery) only executes on main pushes
# and tag cuts, so fern check pre-merge validates the source tree rather
# than the tree that actually publishes. This replays both jobs against
# docs-website and runs fern check on the composed result.
- name: Fetch docs-website
run: git fetch --no-tags --depth=1 origin docs-website:refs/remotes/origin/docs-website
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install Fern CLI
run: npm install -g fern-api
- name: Install yq
run: |
Comment thread
dagil-nvidia marked this conversation as resolved.
# Runner-owned bin dir: no sudo, and $GITHUB_PATH puts it ahead of
# any preinstalled yq for the steps that follow.
mkdir -p "$RUNNER_TEMP/bin"
wget -qO "$RUNNER_TEMP/bin/yq" https://github.com/mikefarah/yq/releases/download/v4.52.5/yq_linux_amd64
chmod +x "$RUNNER_TEMP/bin/yq"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Replay the docs-website composition
env:
DOCS_WEBSITE_REF: origin/docs-website
run: bash docs/fern/scripts/simulate_docs_website.sh

fern-broken-links:
name: Fern Broken Links Check
needs: changed-files
Expand Down
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ repos:
entry: python3 docs/fern/scripts/check_asset_paths.py --test
language: system
files: ^docs/fern/scripts/check_asset_paths\.py$
- id: check-style-components
name: Check *Styles.tsx CSS template literals
entry: python3 docs/fern/scripts/check_style_components.py
language: system
files: ^docs/fern/(components/.*Styles\.tsx|scripts/check_style_components\.py)$
- id: check-published-styles-selftest
name: Self-test the published-styles regex helpers
entry: python3 docs/fern/scripts/check_published_styles.py --test
language: system
files: ^docs/fern/scripts/check_published_styles\.py$
pass_filenames: false
- id: pytest-marker-report
name: Report pytest markers (static + inherited)
Expand Down
Loading
Loading