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
138 changes: 130 additions & 8 deletions .github/workflows/fern-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,6 @@ jobs:
cp source-checkout/docs/fern/pages/home/index.mdx docs-checkout/fern/index.mdx
sed -i 's|\.\./\.\./assets/|./assets/|g' docs-checkout/fern/index.mdx

# Sync root-level assets/ (docs.yml logos/fonts and index.mdx reference
# ./assets/ relative to the Fern root, not pages-dev). Merge-copy without
# deleting so assets still referenced by older versioned pages survive.
if [ -d source-checkout/docs/fern/assets ]; then
echo "Syncing assets/ to docs-website branch..."
cp -r source-checkout/docs/fern/assets/. docs-checkout/fern/assets/
fi

# Sync legacy Digest asset mirror
if [ -d source-checkout/docs/fern/pages/blog/_assets ]; then
echo "Syncing Blog assets to the legacy digest/ compatibility path..."
Expand Down Expand Up @@ -276,6 +268,132 @@ jobs:
done
fi

- name: Generate, validate, and sync release assets
env:
IS_MAIN: ${{ steps.ctx.outputs.is_main }}
run: |
set -euo pipefail

# Sync assets/ into docs-checkout; force-add the generated pair
# because the synced fern/.gitignore ignores them, and an ignored
# bootstrap copy would be silently skipped by the commit step's
# `git add -A`, leaving the published raw URL 404 permanently.
sync_assets() {
if [ -d source-checkout/docs/fern/assets ]; then
echo "Syncing assets/ to docs-website branch..."
mkdir -p docs-checkout/fern/assets
cp -r source-checkout/docs/fern/assets/. docs-checkout/fern/assets/
for asset in releases.json releases-atom.xml; do
if [ -f "docs-checkout/fern/assets/$asset" ]; then
git -C docs-checkout add -f "fern/assets/$asset"
fi
done
fi
}

# Older maintained branches may carry a gen_llms_tables.py without
# --assets-only (or no generator at all); their previews still sync
# whatever assets they commit. Main must always be able to generate.
gen_script="source-checkout/docs/fern/scripts/gen_llms_tables.py"
if ! { [ -f "$gen_script" ] && python3 "$gen_script" --help 2>/dev/null | grep -q -- '--assets-only'; }; then
if [ "${IS_MAIN:-false}" = "true" ]; then
echo "::error::gen_llms_tables.py with --assets-only support is required to generate release assets on main"
exit 1
fi
echo "::notice::Source tree lacks gen_llms_tables.py --assets-only; skipping release-asset generation"
sync_assets
exit 0
fi
python3 "$gen_script" --assets-only
Comment thread
dagil-nvidia marked this conversation as resolved.

generated_json="source-checkout/docs/fern/assets/releases.json"
generated_atom="source-checkout/docs/fern/assets/releases-atom.xml"
for asset in "$generated_json" "$generated_atom"; do
if [ ! -s "$asset" ]; then
echo "::error::$asset is missing or empty after release-asset generation"
exit 1
fi
done

python3 - <<'PY'
import json
import os
import sys
from pathlib import Path

source_root = Path("source-checkout/docs/fern")
generated_path = source_root / "assets/releases.json"
published_path = Path("docs-checkout/fern/assets/releases.json")


def fail(message: str) -> None:
print(f"::error::{message}", file=sys.stderr)
raise SystemExit(1)


def load_json(path: Path, label: str) -> dict:
try:
payload = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
fail(f"{label} is not valid readable JSON: {exc}")
if not isinstance(payload, dict):
fail(f"{label} must contain a JSON object")
return payload


generated = load_json(generated_path, "generated releases.json")
releases = generated.get("releases")
if not isinstance(releases, list) or not releases:
fail("generated releases.json must contain a non-empty releases array")

if os.environ.get("IS_MAIN") != "true":
# Preview builds can lag main by a release; only a main publish
# is held to non-regression against the published copy.
print(
"::notice::Preview build; entry-count regression check skipped"
)
elif published_path.exists():
published = load_json(published_path, "previously published releases.json")
published_releases = published.get("releases")
if not isinstance(published_releases, list):
fail("previously published releases.json must contain a releases array")
if len(releases) < len(published_releases):
fail(
"generated releases.json has fewer entries than the previously "
f"published copy ({len(releases)} < {len(published_releases)})"
Comment thread
dagil-nvidia marked this conversation as resolved.
)
else:
print(
"::notice::No previously published releases.json exists; "
"entry-count regression check skipped"
)

sys.path.insert(0, str(source_root / "scripts"))
import gen_llms_tables # noqa: E402

try:
current_version = gen_llms_tables.parse_data_module(
source_root / "components/releases.data.ts"
)["CURRENT_VERSION"]
except (KeyError, OSError, gen_llms_tables.TSParseError) as exc:
fail(f"could not read CURRENT_VERSION from releases.data.ts: {exc}")

# Membership, not position: RELEASES may be headed by a platform-preview
# or model-build entry while CURRENT_VERSION stays on the prior stable
# (components resolve it with .find(), never [0]).
versions = [r.get("version") for r in releases if isinstance(r, dict)]
if current_version not in versions:
fail(
"generated releases.json does not contain CURRENT_VERSION "
f"from releases.data.ts ({current_version!r})"
)
PY

# Sync root-level assets/ (docs.yml logos/fonts and index.mdx reference
# ./assets/ relative to the Fern root, not pages-dev). Merge-copy without
# deleting so assets still referenced by older versioned pages survive.
sync_assets

- name: Transform paths in dev.yml for docs-website layout
run: |
# In the source repo, index.yml uses paths under pages/ (for example, pages/cli/getting-started/quickstart.mdx).
Expand Down Expand Up @@ -526,6 +644,10 @@ jobs:

release-version:
name: Release Version to docs-website
# This job does not touch fern/assets/: releases.json and releases-atom.xml
# on docs-website are whatever the last main-sync generated. A release lands
# its releases.data.ts bump on main before the tag, so that copy is current
# by the time this job runs; a tag-only rerun republishes it unchanged.
# Run on tag push OR manual dispatch with a tag specified
if: |
github.ref_type == 'tag' ||
Expand Down
5 changes: 2 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,8 @@ repos:
language: system
# The hook above proves the generator works; this one proves it was
# run. Without it, editing releases.data.ts and forgetting to
# regenerate leaves releases.json and every generated span stale,
# with nothing else in the repo checking.
files: ^docs/fern/(scripts/gen_llms_tables\.py|components/releases\.data\.ts|pages/reference/general/.*\.mdx|assets/releases(-atom\.xml|\.json))$
# regenerate leaves every committed generated span stale.
files: ^docs/fern/(scripts/gen_llms_tables\.py|components/releases\.data\.ts|pages/reference/general/.*\.mdx)$
pass_filenames: false
- id: check-component-imports
name: Check Fern components trigger no rolldown bundling
Expand Down
3 changes: 2 additions & 1 deletion docs/fern/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
**/.preview
**/.definition

/assets/releases.json
/assets/releases-atom.xml
Comment thread
dagil-nvidia marked this conversation as resolved.

# Include logos
!*.svg
6 changes: 6 additions & 0 deletions docs/fern/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ When creating or editing files under `docs/`, `examples/`, or `recipes/`, follow

The Dynamo Docs Bot enforces the deterministic subset pre-merge.

## Generated files: commit, publish-time, or post-merge

Commit the artifact when any input is external or time-varying. Generate at publish when the artifact is a pure function of sources committed in the same commit and the toolchain to compute it is already present in the publish runner. Where the toolchain is not in the publish runner, or committed history matters, regenerate post-merge: a workflow on push to main runs the generator and bot-commits changed outputs, so PRs carry source edits only.

`releases.json` and `releases-atom.xml` are generated at publish time; the marker-spliced pages stay committed for review.

## Generated API references

The pages under `pages/reference/api/` and `pages/reference/kubernetes-api/` are generated from
Expand Down
179 changes: 0 additions & 179 deletions docs/fern/assets/releases-atom.xml

This file was deleted.

Loading
Loading