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
128 changes: 128 additions & 0 deletions .github/workflows/fern-docs-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.

# Validates Fern docs configuration on pull requests that touch docs or fern/.

name: Fern Docs CI

on:
pull_request:
paths:
- 'docs/**'
- 'fern/**'
- '.github/workflows/fern-docs-ci.yml'
workflow_dispatch: {}
## --- OPTION: NVIDIA copy-PR-bot trigger ---
## Replace the pull_request block above with:
# push:
# branches:
# - "pull-request/[0-9]+"
# paths:
# - 'docs/**'
# - 'fern/**'
# - '.github/workflows/fern-docs-ci.yml'
## and add the changed-files gating job below (uncomment the full block).

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
## --- OPTION: copy-PR-bot changed-files gate ---
## Uncomment this job and add "needs: changed-files" +
## "if: needs.changed-files.outputs.docs == 'true'" to fern-check when
## using push-to-pull-request/* triggers without paths: filters.
#
# changed-files:
# runs-on: ubuntu-latest
# outputs:
# docs: ${{ steps.changes.outputs.docs }}
# steps:
# - name: Checkout code
# uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# with:
# fetch-depth: 0
#
# - name: Check for docs changes
# id: changes
# run: |
# if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
# echo "docs=true" >> $GITHUB_OUTPUT
# elif [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then
# echo "docs=true" >> $GITHUB_OUTPUT
# elif git diff --name-only "${{ github.event.before }}" HEAD 2>/dev/null | grep -qE '^(docs/|fern/)'; then
# echo "docs=true" >> $GITHUB_OUTPUT
# else
# echo "docs=false" >> $GITHUB_OUTPUT
# fi

fern-check:
name: Fern Check
runs-on: ubuntu-latest
# runs-on: linux-amd64-cpu8 # NVIDIA self-hosted runner
timeout-minutes: 10
Comment thread
coderabbitai[bot] marked this conversation as resolved.
steps:
- name: Checkout repository
uses: actions/checkout@v7

## --- OPTION: filename convention check (warning) ---
# - name: Warn on non-lowercase or underscore markdown filenames
# run: |
# find docs/ -name "*.md" | while read f; do
# base=$(basename "$f")
# if echo "$base" | grep -qE '[A-Z]|_'; then
# suggested=$(echo "$base" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
# echo "::warning file=$f::Filename '$base' should be lowercase with hyphens (e.g. '$suggested')"
# fi
# done

## --- OPTION: filename convention check (hard fail) ---
# - name: Check markdown filename conventions
# run: |
# BAD=$(find docs/ -name '*.md' | grep -E '[A-Z_]' || true)
# if [ -n "$BAD" ]; then
# echo "::error::Markdown filenames must be lowercase with hyphens only:"
# echo "$BAD"
# exit 1
# fi

- name: Setup Node.js
uses: actions/setup-node@v4
Comment thread
pdmack marked this conversation as resolved.
with:
node-version: '20'

- name: Install Fern CLI
run: npm install -g fern-api@$(jq -r .version fern/fern.config.json)

- name: Check MDX safety
run: |
BAD=$(grep -rn '<img\b[^>]*[^/]>\|<img>' docs/ fern/ --include="*.md" --include="*.mdx" || true)
if [ -n "$BAD" ]; then
echo "::error::Non-self-closing <img> tags found (MDX requires <img ... />):"
echo "$BAD"
exit 1
fi

- name: Fern check
run: fern check

- name: Check MDX validity
run: fern docs md check

- name: Check broken links
run: fern docs broken-links
144 changes: 144 additions & 0 deletions .github/workflows/fern-docs-preview-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# 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.

# Workflow 1 of 2 for Fern doc previews.
#
# Collects the fern/ and docs/ sources plus PR metadata from the PR branch and
# uploads them as an artifact. Both directories are needed because
# fern/docs.yml references ../docs/index.yml; omitting docs/ causes
# `fern generate --docs` to fail in the companion workflow. No secrets are
# used here, so this is safe to run on fork PRs via the regular pull_request
# trigger.
#
# The companion workflow (fern-docs-preview-comment.yml) picks up the artifact,
# builds the preview with DOCS_FERN_TOKEN, and posts the PR comment.

name: "Preview Fern Docs: Build"

on:
pull_request:
paths:
- 'docs/**'
- 'fern/**'
- '.github/workflows/fern-docs-preview-build.yml'
## --- OPTION: NVIDIA copy-PR-bot trigger ---
## Replace the pull_request block above with:
# push:
# branches:
# - "pull-request/[0-9]+"
# paths:
# - 'docs/**'
# - 'fern/**'
# - '.github/workflows/fern-docs-preview-build.yml'
## and switch the "Save PR metadata" step to the copy-PR-bot variant below.

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
## --- OPTION: copy-PR-bot changed-files gate ---
## Uncomment this job and add "needs: changed-files" +
## "if: needs.changed-files.outputs.docs == 'true'" to collect when using
## push-to-pull-request/* triggers without paths: filters.
#
# changed-files:
# runs-on: ubuntu-latest
# outputs:
# docs: ${{ steps.changes.outputs.docs }}
# steps:
# - name: Checkout code
# uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# with:
# fetch-depth: 0
#
# - name: Check for docs changes
# id: changes
# run: |
# if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then
# echo "docs=true" >> $GITHUB_OUTPUT
# elif git diff --name-only "${{ github.event.before }}" HEAD 2>/dev/null | grep -qE '^(docs/|fern/)'; then
# echo "docs=true" >> $GITHUB_OUTPUT
# else
# echo "docs=false" >> $GITHUB_OUTPUT
# fi

collect:
runs-on: ubuntu-latest
# runs-on: linux-amd64-cpu8 # NVIDIA self-hosted runner
timeout-minutes: 10
steps:
- name: Checkout PR
uses: actions/checkout@v7
Comment thread
pdmack marked this conversation as resolved.
with:
fetch-depth: 0
persist-credentials: false

- name: Save PR metadata
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
HEAD_REF: ${{ github.head_ref }}
BASE_REF: ${{ github.base_ref }}
run: |
mkdir -p preview-metadata
echo "$PR_NUMBER" > preview-metadata/pr_number
echo "$HEAD_REF" > preview-metadata/head_ref
git diff --name-only "origin/${BASE_REF}...HEAD" -- '*.md' '*.mdx' > preview-metadata/changed_md_files 2>/dev/null || true
## --- OPTION: copy-PR-bot metadata extraction ---
## Replace the step above with this when using push-to-pull-request/*:
# - name: Save PR metadata
# env:
# BRANCH_NAME: ${{ github.ref_name }}
# run: |
# mkdir -p preview-metadata
# echo "${BRANCH_NAME#pull-request/}" > preview-metadata/pr_number
# echo "$BRANCH_NAME" > preview-metadata/head_ref
# git diff --name-only "origin/main...HEAD" -- '*.md' '*.mdx' > preview-metadata/changed_md_files 2>/dev/null || true

- name: Checkout frozen version content
run: |
set -eo pipefail
for version_file in fern/versions/v*.yml; do
[ -f "$version_file" ] || continue
version=$(basename "$version_file" .yml)
# Registry files are named by the stripped version; the tag they were
# cut from still carries the chart/ prefix.
tag="chart/${version}"
if git show-ref --verify --quiet "refs/tags/${tag}"; then
mkdir -p "fern/versions/${version}-content"
git archive "refs/tags/${tag}" -- docs/ | tar -x --strip-components=1 -C "fern/versions/${version}-content"
find "fern/versions/${version}-content" -name '*.md' -print0 | xargs -0 -r sed -i \
-e 's/{/\\{/g' \
-e 's/}/\\}/g' \
-e 's/</\&lt;/g'
echo "Extracted docs from $version"
else
echo "::error::Tag $tag not found — cannot load frozen docs content"
exit 1
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
done

- name: Upload fern sources and metadata
uses: actions/upload-artifact@v4
with:
name: fern-preview
path: |
fern/
docs/
preview-metadata/
retention-days: 1
Loading
Loading