ci: snapshot release docs from tag source#194
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Enterprise Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🧰 Additional context used📓 Path-based instructions (10).github/workflows/*.{yml,yaml}📄 CodeRabbit inference engine (.agents/skills/maintain-ci/SKILL.md)
Files:
.{github/workflows/*.{yml,yaml},gitlab-ci.yml}📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Files:
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}⚙️ CodeRabbit configuration file
Files:
{pyproject.toml,**/*.py}📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Files:
**/*.{py,txt,toml,cfg,yaml,yml}📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)
Files:
{scripts/**,third-party/**}📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
Files:
**/*.py📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
Files:
**/*.{md,mdx,py,sh,yaml,yml,toml,json}📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)
Files:
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{rs,py,go,js,ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2026-05-03T04:23:07.497ZApplied to files:
🪛 Ruff (0.15.14)scripts/docs/sync_fern_docs_branch.py[warning] 203-203: Avoid specifying long messages outside the exception class (TRY003) 🪛 zizmor (1.25.2).github/workflows/fern-docs.yml[warning] 378-378: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment (undocumented-permissions) [info] 444-444: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 432-432: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default (cache-poisoning) 🔇 Additional comments (9)
WalkthroughRefactors release-version doc snapshotting to copy from repository ChangesRelease Docs Snapshot Refactor
Sequence DiagramsequenceDiagram
participant GitHubActions
participant CheckoutAction
participant JustTool
participant SyncScript
participant SourceDocs
GitHubActions->>CheckoutAction: checkout ref=${{ steps.version.outputs.tag }}
GitHubActions->>JustTool: run `just docs-api-reference`
JustTool->>GitHubActions: generated API reference artifacts
GitHubActions->>SyncScript: invoke `sync_fern_docs_branch.py release-version --source-root "$GITHUB_WORKSPACE/source-checkout"`
SyncScript->>SourceDocs: read and copy `source_root/docs` into `fern/pages-{display_tag}`
SyncScript->>GitHubActions: updated `fern/pages-{display_tag}` and versions files
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
07a4125 to
cecf183
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/fern-docs.yml:
- Around line 377-381: Add a short inline comment next to the permissions block
explaining why contents: write is required (e.g., the job needs the token to
push/commit artifacts, create or update PRs, or write to the repository
workspace during CI), so reviewers and the zizmor linter understand the
permission's purpose; update the permissions: contents: write stanza in the
workflow to include that explanatory comment adjacent to the block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: b9e0fdd0-943e-4644-83b3-c55b990f4fc5
📒 Files selected for processing (2)
.github/workflows/fern-docs.ymlscripts/docs/sync_fern_docs_branch.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Check / Run
- GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (10)
.github/workflows/*.{yml,yaml}
📄 CodeRabbit inference engine (.agents/skills/maintain-ci/SKILL.md)
.github/workflows/*.{yml,yaml}: Putpermissions:on each job that needs token access in GitHub Actions workflows
Avoid workflow-level permissions unless the repository intentionally centralizes them and the inheritance tradeoff is documented
Keep third-party actions pinned to full commit SHAs and preserve the readable version comment after the SHA
Prefer action-native or ecosystem-native caching over genericactions/cache
Use lockfiles or dependency manifests to drive cache invalidation in GitHub Actions workflows
Keep deploy and publish permissions isolated to the jobs that need them in GitHub Actions
Read both caller and callee when a workflow usesworkflow_callin GitHub Actions
Put release-tag validation in the earliest practical caller job when the pipeline has tag-based publish behavior
Keep release-tag policy aligned withRELEASING.md: raw SemVer tags only, no leadingv
contents: readis the default minimum permission for checkout-based build, test, docs, and packaging jobs
pull-requests: readis required for PR metadata lookup jobs in GitHub Actions workflows
pages: writeandid-token: writeshould be limited to Pages deployment jobs and callers that invoke them through reusable workflows
For reusable workflows, the caller must grant every permission the called jobs require; the callee cannot elevate beyond what the caller provides
Preferastral-sh/setup-uvcache support withcache-dependency-globanchored touv.lock
PreferSwatinem/rust-cachewith explicitshared-keyandworkspacesinstead of ad hoc target-directory caching
Avoid caching generated outputs that can hide stale behavior unless the repo already relies on them deliberately
Files:
.github/workflows/fern-docs.yml
.{github/workflows/*.{yml,yaml},gitlab-ci.yml}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Ensure CI workflows reference the same package names, install commands, and build commands as local development workflows
Files:
.github/workflows/fern-docs.yml
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}
⚙️ CodeRabbit configuration file
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}: Review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.
Pay attention to commands that need generated native artifacts, FFI libraries, or platform-specific environment variables.
Files:
.github/workflows/fern-docs.ymlscripts/docs/sync_fern_docs_branch.py
{pyproject.toml,**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Maintain consistency between Python package names in
pyproject.tomland import paths used throughout the codebase
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{py,txt,toml,cfg,yaml,yml}
📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)
Update Python package names and top-level module imports during coordinated rename operations
Files:
scripts/docs/sync_fern_docs_branch.py
{scripts/**,third-party/**}
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
{scripts/**,third-party/**}: For third-party integration or patch changes, run patch validation with./scripts/apply-patches.sh --checkand relevant integration tests. Keep root./scripts/*.shwrappers for third-party flows
Run third-party patch bootstrap with./scripts/bootstrap-third-party.sh
Run third-party patch validation with./scripts/apply-patches.sh --check
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.py
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
**/*.py: Run Python formatting withuv run ruff format python
Run Python testing withuv run pytest -k "<pattern>"
**/*.py: Use Ruff with rule sets E, F, W, I for Python linting
Use Ruff formatter with line length 120 and double quotes for Python code formatting
Runtyfor Python type checking
Use Python snake_case naming convention for Python identifiers
Include SPDX license header in all Python source files using hash comment syntax
Validate Python code withuv run pre-commit run --all-filesto enforce Ruff linting and formatting, and ty type checking
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{md,mdx,py,sh,yaml,yml,toml,json}
📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)
Keep package names, repo references, and build commands current
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}
📄 CodeRabbit inference engine (AGENTS.md)
Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{rs,py,go,js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Follow binding naming conventions: Rust and Python use
snake_case, C FFI exports prefixednemo_relay_, Go usesPascalCasefor public APIs, Node.js usescamelCase.
Files:
scripts/docs/sync_fern_docs_branch.py
🧠 Learnings (1)
📚 Learning: 2026-05-03T04:23:07.497Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Flow PR: 46
File: .github/workflows/ci_rust.yml:31-64
Timestamp: 2026-05-03T04:23:07.497Z
Learning: In GitHub Actions workflow YAML, it’s valid to conditionally disable a service container by setting the service container’s `image` to an empty string (`''`) via a matrix variable (e.g., `redis_service_image: ''`). This intentionally makes the runner skip service initialization for that matrix entry rather than failing the job. When reviewing workflows, don’t flag this as an error if the workflow uses an empty `image` to disable the service on specific matrix entries (e.g., OS-specific setups); verify the `image` is sourced from the matrix variable and that the service is only expected to be available when a non-empty image is provided.
Applied to files:
.github/workflows/fern-docs.yml
🪛 Ruff (0.15.14)
scripts/docs/sync_fern_docs_branch.py
[warning] 203-203: Avoid specifying long messages outside the exception class
(TRY003)
🪛 zizmor (1.25.2)
.github/workflows/fern-docs.yml
[warning] 378-378: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 444-444: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 432-432: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🔇 Additional comments (6)
scripts/docs/sync_fern_docs_branch.py (2)
193-212: LGTM!The refactored
release_version()correctly sources docs from the newsource_root/docsdirectory, validates the source exists before proceeding, and properly clears existing version artifacts before copying fresh content. The flow is clean: validate → clear → copy → rewrite → write.
272-276: LGTM!CLI wiring is correct:
--source-rootis required forrelease-version, andmain()passes resolved paths in the correct order matching the function signature.Also applies to: 284-285
.github/workflows/fern-docs.yml (4)
401-406: LGTM!The checkout now correctly uses the validated SemVer tag as ref, ensuring docs are built from the release commit rather than the default branch. Tag validation at lines 395-398 prevents arbitrary ref injection.
424-449: LGTM!Rust toolchain and cache setup follows the project's established pattern. The
save-if: falsesetting ensures this job only reads from cache (built by other jobs), mitigating the cache-poisoning concern flagged by static analysis.
458-463: LGTM!The docs generation step is correctly placed before snapshotting, ensuring generated reference content originates from the release tag rather than stale dev-branch artifacts.
473-480: LGTM!The
--source-rootargument correctly points to the tag checkout (source-checkout), completing the end-to-end wiring of the new snapshot flow.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/docs/sync_fern_docs_branch.py`:
- Around line 197-212: The script sets versions_dir and computes version_yml but
never ensures the directory exists before calling write_yaml, which causes
FileNotFoundError; before writing version_yml (and before any file operations
that assume the directory) create the directory for versions_dir (e.g., call
mkdir with parents=True and exist_ok=True) so that write_yaml can safely write
version_yml; update the block around versions_dir/version_yml (and any cleanup
logic for pages_version) to ensure versions_dir exists first.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 81e456fc-d995-476f-9469-692d668182bc
📒 Files selected for processing (2)
.github/workflows/fern-docs.ymlscripts/docs/sync_fern_docs_branch.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Check / Run
- GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (10)
.github/workflows/*.{yml,yaml}
📄 CodeRabbit inference engine (.agents/skills/maintain-ci/SKILL.md)
.github/workflows/*.{yml,yaml}: Putpermissions:on each job that needs token access in GitHub Actions workflows
Avoid workflow-level permissions unless the repository intentionally centralizes them and the inheritance tradeoff is documented
Keep third-party actions pinned to full commit SHAs and preserve the readable version comment after the SHA
Prefer action-native or ecosystem-native caching over genericactions/cache
Use lockfiles or dependency manifests to drive cache invalidation in GitHub Actions workflows
Keep deploy and publish permissions isolated to the jobs that need them in GitHub Actions
Read both caller and callee when a workflow usesworkflow_callin GitHub Actions
Put release-tag validation in the earliest practical caller job when the pipeline has tag-based publish behavior
Keep release-tag policy aligned withRELEASING.md: raw SemVer tags only, no leadingv
contents: readis the default minimum permission for checkout-based build, test, docs, and packaging jobs
pull-requests: readis required for PR metadata lookup jobs in GitHub Actions workflows
pages: writeandid-token: writeshould be limited to Pages deployment jobs and callers that invoke them through reusable workflows
For reusable workflows, the caller must grant every permission the called jobs require; the callee cannot elevate beyond what the caller provides
Preferastral-sh/setup-uvcache support withcache-dependency-globanchored touv.lock
PreferSwatinem/rust-cachewith explicitshared-keyandworkspacesinstead of ad hoc target-directory caching
Avoid caching generated outputs that can hide stale behavior unless the repo already relies on them deliberately
Files:
.github/workflows/fern-docs.yml
.{github/workflows/*.{yml,yaml},gitlab-ci.yml}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Ensure CI workflows reference the same package names, install commands, and build commands as local development workflows
Files:
.github/workflows/fern-docs.yml
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}
⚙️ CodeRabbit configuration file
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}: Review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.
Pay attention to commands that need generated native artifacts, FFI libraries, or platform-specific environment variables.
Files:
.github/workflows/fern-docs.ymlscripts/docs/sync_fern_docs_branch.py
{pyproject.toml,**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Maintain consistency between Python package names in
pyproject.tomland import paths used throughout the codebase
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{py,txt,toml,cfg,yaml,yml}
📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)
Update Python package names and top-level module imports during coordinated rename operations
Files:
scripts/docs/sync_fern_docs_branch.py
{scripts/**,third-party/**}
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
{scripts/**,third-party/**}: For third-party integration or patch changes, run patch validation with./scripts/apply-patches.sh --checkand relevant integration tests. Keep root./scripts/*.shwrappers for third-party flows
Run third-party patch bootstrap with./scripts/bootstrap-third-party.sh
Run third-party patch validation with./scripts/apply-patches.sh --check
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.py
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
**/*.py: Run Python formatting withuv run ruff format python
Run Python testing withuv run pytest -k "<pattern>"
**/*.py: Use Ruff with rule sets E, F, W, I for Python linting
Use Ruff formatter with line length 120 and double quotes for Python code formatting
Runtyfor Python type checking
Use Python snake_case naming convention for Python identifiers
Include SPDX license header in all Python source files using hash comment syntax
Validate Python code withuv run pre-commit run --all-filesto enforce Ruff linting and formatting, and ty type checking
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{md,mdx,py,sh,yaml,yml,toml,json}
📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)
Keep package names, repo references, and build commands current
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}
📄 CodeRabbit inference engine (AGENTS.md)
Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.
Files:
scripts/docs/sync_fern_docs_branch.py
**/*.{rs,py,go,js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Follow binding naming conventions: Rust and Python use
snake_case, C FFI exports prefixednemo_relay_, Go usesPascalCasefor public APIs, Node.js usescamelCase.
Files:
scripts/docs/sync_fern_docs_branch.py
🧠 Learnings (1)
📚 Learning: 2026-05-03T04:23:07.497Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Flow PR: 46
File: .github/workflows/ci_rust.yml:31-64
Timestamp: 2026-05-03T04:23:07.497Z
Learning: In GitHub Actions workflow YAML, it’s valid to conditionally disable a service container by setting the service container’s `image` to an empty string (`''`) via a matrix variable (e.g., `redis_service_image: ''`). This intentionally makes the runner skip service initialization for that matrix entry rather than failing the job. When reviewing workflows, don’t flag this as an error if the workflow uses an empty `image` to disable the service on specific matrix entries (e.g., OS-specific setups); verify the `image` is sourced from the matrix variable and that the service is only expected to be available when a non-empty image is provided.
Applied to files:
.github/workflows/fern-docs.yml
🪛 Ruff (0.15.14)
scripts/docs/sync_fern_docs_branch.py
[warning] 203-203: Avoid specifying long messages outside the exception class
(TRY003)
🪛 zizmor (1.25.2)
.github/workflows/fern-docs.yml
[warning] 378-378: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 444-444: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 432-432: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🔇 Additional comments (2)
scripts/docs/sync_fern_docs_branch.py (1)
272-273: LGTM!Also applies to: 285-285
.github/workflows/fern-docs.yml (1)
376-380: LGTM!Also applies to: 404-404, 424-450, 458-463, 477-477
Signed-off-by: Will Killian <wkillian@nvidia.com>
cecf183 to
ac93430
Compare
|
/merge |
Overview
Fix Fern release publishing so version snapshots are built from the selected release tag source docs instead of whatever
docs-websitealready has infern/pages-dev.Details
release-version-docsfor both tag pushes and manual dispatches.sync_fern_docs_branch.py release-versionrequire--source-rootand copy source docs directly into the versioned Fern pages, removing the stalepages-devfallback.Validation:
ruby -e 'require "yaml"; Dir[".github/workflows/*.{yml,yaml}"].each { |f| YAML.load_file(f) }; puts "yaml-ok"'uv run --no-sync python -m py_compile scripts/docs/sync_fern_docs_branch.pyrelease-version --source-root ... --tag 0.3.0snapshot check verified the detailed release highlights land infern/pages-v0.3.0.uv run pre-commit run --files .github/workflows/fern-docs.yml scripts/docs/sync_fern_docs_branch.pyuv run pre-commit run --all-filesWhere should the reviewer start?
Start with
.github/workflows/fern-docs.yml, specifically therelease-version-docsjob, then reviewscripts/docs/sync_fern_docs_branch.pyfor the simplified source-to-version snapshot path.Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
Summary by CodeRabbit