Files
OpenShell/.github/workflows/sync-docs.yml
Piotr Mlocek a0814443f1 feat(docs): publish versioned release snapshots (#3149)
* feat(docs): add version availability labels

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(docs): use supported Python for sync

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* feat(docs): publish versioned docs from releases

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(docs): format dev version label

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* chore(docs): upgrade Fern CLI to 5.112.0

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(docs): make release publishing monotonic

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(docs): preserve snapshot release identity

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* docs(fern): document versioned publishing

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* test(docs): cover explicit snapshot rollback

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* refactor(docs): use Fern refs for versions

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(docs): bundle components for ref versions

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* revert(docs): keep complete version copies

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

* fix(docs): publish latest and dev channels

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>

---------

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
2026-09-09 23:34:34 +00:00

254 lines
8.3 KiB
YAML

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
name: Sync Docs Website
on:
workflow_call:
inputs:
operation:
description: "Whether to sync or remove a docs snapshot"
required: true
type: string
channel:
description: "Docs channel to update or remove"
required: true
type: string
source_ref:
description: "Source commit SHA, branch, or tag to snapshot when operation=sync"
required: false
type: string
release_version:
description: "Release version used to order mutable channels"
required: false
type: string
version_slug:
description: "Version slug when channel=version"
required: false
type: string
display_name:
description: "Optional version selector display name"
required: false
type: string
availability:
description: "Optional Fern availability status"
required: false
type: string
publish:
description: "Publish production docs after syncing"
required: false
default: false
type: boolean
allow_rollback:
description: "Allow an explicitly requested mutable-channel rollback"
required: false
default: false
type: boolean
secrets:
FERN_TOKEN:
required: false
workflow_dispatch:
inputs:
operation:
description: "Whether to sync or remove a docs snapshot"
required: true
default: sync
type: choice
options:
- sync
- remove
channel:
description: "Docs channel to update or remove"
required: true
type: choice
options:
- dev
- latest
- stable
- version
source_ref:
description: "Source commit SHA, branch, or tag to snapshot when operation=sync"
required: false
type: string
release_version:
description: "Release version, e.g. 0.1.2 or 0.1.3.dev4"
required: false
type: string
version_slug:
description: "Version slug when channel=version, e.g. v0.0.36"
required: false
type: string
display_name:
description: "Optional selector name, e.g. Dev"
required: false
type: string
availability:
description: "Optional Fern status: beta, deprecated, ga, or stable"
required: false
type: string
publish:
description: "Publish production docs after syncing"
required: false
default: false
type: boolean
allow_rollback:
description: "Allow an explicitly requested mutable-channel rollback"
required: false
default: false
type: boolean
permissions:
contents: write
concurrency:
group: docs-website
cancel-in-progress: false
queue: max
defaults:
run:
shell: bash
jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout automation
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: automation
- name: Validate inputs
# Pass dispatch inputs through env vars rather than interpolating
# ${{ inputs.* }} directly into the script. source_ref/version_slug are
# free-form strings, so inlining them would allow shell injection into
# the runner (e.g. version_slug = "$(...)"). Quoted env vars are inert.
env:
OPERATION: ${{ inputs.operation }}
CHANNEL: ${{ inputs.channel }}
SOURCE_REF: ${{ inputs.source_ref }}
RELEASE_VERSION: ${{ inputs.release_version }}
VERSION_SLUG: ${{ inputs.version_slug }}
run: |
set -euo pipefail
if [[ "$OPERATION" == "sync" && -z "$SOURCE_REF" ]]; then
echo "source_ref is required when operation=sync" >&2
exit 1
fi
if [[ "$CHANNEL" =~ ^(dev|latest|stable)$ && -z "$RELEASE_VERSION" ]]; then
echo "release_version is required for dev, latest, and stable channels" >&2
exit 1
fi
if [[ "$CHANNEL" =~ ^(stable|version)$ && -z "$VERSION_SLUG" ]]; then
echo "version_slug is required for stable and version channels" >&2
exit 1
fi
- name: Checkout source docs
if: ${{ inputs.operation == 'sync' }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.source_ref }}
fetch-depth: 0
path: source
- name: Checkout docs website branch
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: docs-website
fetch-depth: 0
path: docs-website
- name: Install uv
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
with:
version: "0.10.12"
python-version: "3.13"
- name: Update docs snapshot
# Inputs flow in as quoted env vars to avoid shell injection; see the
# Validate inputs step above.
env:
OPERATION: ${{ inputs.operation }}
CHANNEL: ${{ inputs.channel }}
SOURCE_REF: ${{ inputs.source_ref }}
RELEASE_VERSION: ${{ inputs.release_version }}
VERSION_SLUG: ${{ inputs.version_slug }}
DISPLAY_NAME: ${{ inputs.display_name }}
AVAILABILITY: ${{ inputs.availability }}
ALLOW_ROLLBACK: ${{ inputs.allow_rollback }}
run: |
SOURCE_SHA=""
if [[ "$OPERATION" == "sync" ]]; then
SOURCE_SHA=$(git -C source rev-parse HEAD)
fi
rollback_args=()
if [[ "$ALLOW_ROLLBACK" == "true" ]]; then
rollback_args+=(--allow-rollback)
fi
uv run automation/tasks/scripts/sync_docs_website.py \
--operation "$OPERATION" \
--source-root source \
--docs-website-root docs-website \
--channel "$CHANNEL" \
--source-ref "$SOURCE_REF" \
--source-sha "$SOURCE_SHA" \
--release-version "$RELEASE_VERSION" \
--version-slug "$VERSION_SLUG" \
--display-name "$DISPLAY_NAME" \
--availability "$AVAILABILITY" \
"${rollback_args[@]}"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "24"
- name: Install Fern CLI
working-directory: docs-website
run: |
FERN_VERSION=$(node -p "require('./fern/fern.config.json').version")
npm install -g "fern-api@${FERN_VERSION}"
- name: Validate docs website
working-directory: docs-website/fern
run: fern check
- name: Commit docs website changes
working-directory: docs-website
# Inputs flow in as quoted env vars to avoid shell injection (the commit
# message embeds free-form source_ref/version_slug); see Validate inputs.
env:
OPERATION: ${{ inputs.operation }}
CHANNEL: ${{ inputs.channel }}
SOURCE_REF: ${{ inputs.source_ref }}
VERSION_SLUG: ${{ inputs.version_slug }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
# https://api.github.com/users/github-actions%5Bbot%5D
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
if git diff --cached --quiet; then
echo "No docs website changes to commit."
exit 0
fi
target="$VERSION_SLUG"
if [[ -z "${target}" ]]; then
target="$CHANNEL"
fi
if [[ "$OPERATION" == "sync" ]]; then
git commit -m "docs(website): sync ${target} docs from ${SOURCE_REF}"
else
git commit -m "docs(website): remove ${target} docs"
fi
git push origin HEAD:docs-website
- name: Publish Fern docs
if: ${{ inputs.publish }}
env:
FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
working-directory: docs-website/fern
run: fern generate --docs