Skip to content

Commit 8e56bca

Browse files
committed
fern ci items
Signed-off-by: Lawrence Lane <llane@nvidia.com>
1 parent f38a095 commit 8e56bca

File tree

3 files changed

+260
-0
lines changed

3 files changed

+260
-0
lines changed

.github/workflows/fern-docs-ci.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Validates Fern autodocs generation (fern/product-docs) on pull requests.
17+
# Output is gitignored; see fern/AUTODOCS_GUIDE.md and docs.yml `libraries`.
18+
19+
name: Fern docs (autodocs)
20+
21+
on:
22+
pull_request:
23+
paths:
24+
- 'fern/**'
25+
- '.github/workflows/fern-docs-ci.yml'
26+
27+
permissions:
28+
contents: read
29+
30+
jobs:
31+
generate-library-reference:
32+
runs-on: ubuntu-latest
33+
steps:
34+
- name: Checkout repository
35+
uses: actions/checkout@v6
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v6
39+
with:
40+
node-version: '20'
41+
42+
- name: Install Fern CLI
43+
run: npm install -g fern-api
44+
45+
- name: Generate library reference MDX (product-docs)
46+
env:
47+
FERN_TOKEN: ${{ secrets.DOCS_FERN_TOKEN }}
48+
working-directory: ./fern
49+
run: fern docs md generate
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Workflow 1 of 2 for Fern doc previews.
17+
#
18+
# Collects the fern/ sources and PR metadata from the (possibly untrusted) PR
19+
# branch and uploads them as an artifact. No secrets are used here, so this is
20+
# safe to run on fork PRs via the regular pull_request trigger.
21+
#
22+
# The companion workflow (fern-docs-preview-comment.yml) picks up the artifact,
23+
# builds the preview with DOCS_FERN_TOKEN, and posts the PR comment.
24+
25+
name: "Preview Fern Docs: Build"
26+
27+
on:
28+
pull_request:
29+
paths:
30+
- 'fern/**'
31+
- '.github/workflows/fern-docs-preview-build.yml'
32+
33+
permissions:
34+
contents: read
35+
36+
jobs:
37+
collect:
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Checkout PR
41+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
42+
with:
43+
fetch-depth: 0
44+
45+
- name: Save PR metadata
46+
env:
47+
PR_NUMBER: ${{ github.event.pull_request.number }}
48+
HEAD_REF: ${{ github.head_ref }}
49+
BASE_REF: ${{ github.base_ref }}
50+
run: |
51+
mkdir -p .preview-metadata
52+
echo "$PR_NUMBER" > .preview-metadata/pr_number
53+
echo "$HEAD_REF" > .preview-metadata/head_ref
54+
git diff --name-only "origin/${BASE_REF}...HEAD" -- '*.mdx' > .preview-metadata/changed_mdx_files 2>/dev/null || true
55+
56+
- name: Upload fern sources and metadata
57+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
58+
with:
59+
name: fern-preview
60+
path: |
61+
fern/
62+
.preview-metadata/
63+
retention-days: 1
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Workflow 2 of 2 for Fern doc previews.
17+
#
18+
# Triggered by workflow_run after "Preview Fern Docs: Build" completes.
19+
# Downloads the fern/ artifact, builds a preview with DOCS_FERN_TOKEN, and
20+
# posts a stable :herb: comment on the PR. This workflow never checks out the
21+
# PR branch directly, keeping secrets isolated from untrusted code.
22+
#
23+
# Required configuration:
24+
# - Organization secret: DOCS_FERN_TOKEN (from `fern token` for the nvidia Fern org)
25+
26+
name: "Preview Fern Docs: Comment"
27+
28+
on:
29+
workflow_run:
30+
workflows: ["Preview Fern Docs: Build"]
31+
types: [completed]
32+
33+
permissions:
34+
pull-requests: write
35+
actions: read
36+
37+
jobs:
38+
preview:
39+
runs-on: ubuntu-latest
40+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
41+
steps:
42+
- name: Download fern sources and metadata
43+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
44+
with:
45+
name: fern-preview
46+
run-id: ${{ github.event.workflow_run.id }}
47+
github-token: ${{ secrets.GITHUB_TOKEN }}
48+
49+
- name: Read PR metadata
50+
id: metadata
51+
run: |
52+
echo "pr_number=$(cat .preview-metadata/pr_number)" >> "$GITHUB_OUTPUT"
53+
echo "head_ref=$(cat .preview-metadata/head_ref)" >> "$GITHUB_OUTPUT"
54+
55+
- name: Setup Node.js
56+
uses: actions/setup-node@v6
57+
with:
58+
node-version: '20'
59+
60+
- name: Install Fern CLI
61+
run: npm install -g fern-api
62+
63+
- name: Generate library reference MDX (autodocs)
64+
env:
65+
FERN_TOKEN: ${{ secrets.DOCS_FERN_TOKEN }}
66+
working-directory: ./fern
67+
run: fern docs md generate
68+
69+
- name: Generate preview URL
70+
id: generate-docs
71+
env:
72+
FERN_TOKEN: ${{ secrets.DOCS_FERN_TOKEN }}
73+
HEAD_REF: ${{ steps.metadata.outputs.head_ref }}
74+
working-directory: ./fern
75+
run: |
76+
OUTPUT=$(fern generate --docs --preview --id "$HEAD_REF" 2>&1)
77+
echo "$OUTPUT"
78+
URL=$(echo "$OUTPUT" | grep -oP 'Published docs to \K.*(?= \()')
79+
if [ -z "$URL" ]; then
80+
echo "::error::Failed to generate preview URL. See fern output above."
81+
exit 1
82+
fi
83+
echo "preview_url=$URL" >> "$GITHUB_OUTPUT"
84+
85+
- name: Build page links for changed MDX files
86+
id: page-links
87+
env:
88+
FERN_TOKEN: ${{ secrets.DOCS_FERN_TOKEN }}
89+
PREVIEW_URL: ${{ steps.generate-docs.outputs.preview_url }}
90+
run: |
91+
CHANGED_FILES=""
92+
if [ -f .preview-metadata/changed_mdx_files ]; then
93+
CHANGED_FILES=$(cat .preview-metadata/changed_mdx_files)
94+
fi
95+
96+
if [ -z "$CHANGED_FILES" ] || [ -z "$PREVIEW_URL" ]; then
97+
echo "page_links=" >> "$GITHUB_OUTPUT"; exit 0
98+
fi
99+
100+
BASE_URL=$(echo "$PREVIEW_URL" | grep -oP 'https?://[^/]+')
101+
FILES_PARAM=$(echo "$CHANGED_FILES" | tr '\n' ',' | sed 's/,$//' \
102+
| python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip(), safe=',/'))")
103+
RESPONSE=$(curl -sf -H "FERN_TOKEN: $FERN_TOKEN" "${PREVIEW_URL}/api/fern-docs/get-slug-for-file?files=${FILES_PARAM}" 2>/dev/null) || {
104+
echo "page_links=" >> "$GITHUB_OUTPUT"; exit 0
105+
}
106+
107+
PAGE_LINKS=$(echo "$RESPONSE" | jq -r --arg url "$BASE_URL" \
108+
'.mappings[] | select(.slug != null) | "- [\(.slug)](\($url)/\(.slug))"')
109+
110+
if [ -n "$PAGE_LINKS" ]; then
111+
{ echo "page_links<<EOF"; echo "$PAGE_LINKS"; echo "EOF"; } >> "$GITHUB_OUTPUT"
112+
else
113+
echo "page_links=" >> "$GITHUB_OUTPUT"
114+
fi
115+
116+
- name: Post or update PR comment
117+
env:
118+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119+
PR_NUMBER: ${{ steps.metadata.outputs.pr_number }}
120+
PREVIEW_URL: ${{ steps.generate-docs.outputs.preview_url }}
121+
PAGE_LINKS: ${{ steps.page-links.outputs.page_links }}
122+
run: |
123+
# Build comment body
124+
BODY=":herb: **Preview your docs:** <${PREVIEW_URL}>"
125+
if [ -n "${PAGE_LINKS}" ]; then
126+
BODY="${BODY}
127+
128+
Here are the markdown pages you've updated:
129+
${PAGE_LINKS}"
130+
fi
131+
132+
# Hidden marker for upsert
133+
MARKER="<!-- preview-docs -->"
134+
BODY="${BODY}
135+
136+
${MARKER}"
137+
138+
# Find existing comment with marker
139+
COMMENT_ID=$(gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
140+
--jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -1)
141+
142+
if [ -n "$COMMENT_ID" ]; then
143+
gh api "repos/${{ github.repository }}/issues/comments/${COMMENT_ID}" \
144+
-X PATCH -f body="$BODY"
145+
else
146+
gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
147+
-f body="$BODY"
148+
fi

0 commit comments

Comments
 (0)