From ac93430b57fff8832f86413220fe99824e43e3ed Mon Sep 17 00:00:00 2001 From: Will Killian Date: Fri, 29 May 2026 19:23:16 -0400 Subject: [PATCH] ci: snapshot release docs from tag source Signed-off-by: Will Killian --- .github/workflows/fern-docs.yml | 38 ++++++++++++++++++++++- scripts/docs/sync_fern_docs_branch.py | 43 +++++++-------------------- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/.github/workflows/fern-docs.yml b/.github/workflows/fern-docs.yml index b8c77ca1..b7c2c828 100644 --- a/.github/workflows/fern-docs.yml +++ b/.github/workflows/fern-docs.yml @@ -373,10 +373,11 @@ jobs: }} runs-on: ubuntu-latest environment: fern - timeout-minutes: 30 + timeout-minutes: 60 permissions: contents: write env: + NEMO_RELAY_CI_WORKSPACE: ${{ github.workspace }}/source-checkout UV_PYTHON_DOWNLOADS: never steps: - name: Determine version tag @@ -400,6 +401,7 @@ jobs: - name: Checkout source branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: + ref: ${{ steps.version.outputs.tag }} path: source-checkout fetch-depth: 1 @@ -419,6 +421,33 @@ jobs: with: node-version: ${{ steps.ci-config.outputs.node_version }} + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4 + with: + cache: false + toolchain: ${{ steps.ci-config.outputs.rust_version }} + rustflags: "" + + - name: Cache Rust docs dependencies + uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 + with: + shared-key: nemo-relay-rust-docs-${{ runner.os }}-${{ runner.arch }}-${{ steps.ci-config.outputs.rust_version }} + workspaces: source-checkout -> source-checkout/target + cache-all-crates: true + cache-bin: false + save-if: false + + - name: Install managed Python + working-directory: source-checkout + run: | + set -euo pipefail + UV_PYTHON_DOWNLOADS=manual uv python install --managed-python ${{ steps.ci-config.outputs.default_python_version }} + + - name: Install just + uses: taiki-e/install-action@c070f87102a1c75b3183910f391c1cb887fe13c8 # v2.77.6 + with: + tool: just@${{ steps.ci-config.outputs.just_version }} + - name: Install release docs dependencies working-directory: source-checkout run: | @@ -426,6 +455,12 @@ jobs: uv sync --no-default-groups --group dev --no-install-project npm ci --ignore-scripts + - name: Generate source API references + working-directory: source-checkout + env: + NEMO_RELAY_DOCS_DEPS_READY: "1" + run: just docs-api-reference + - name: Checkout docs website branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -439,6 +474,7 @@ jobs: run: | set -euo pipefail uv run --no-sync python scripts/docs/sync_fern_docs_branch.py release-version \ + --source-root "$GITHUB_WORKSPACE/source-checkout" \ --target-root "$GITHUB_WORKSPACE/docs-checkout" \ --tag "${{ steps.version.outputs.tag }}" diff --git a/scripts/docs/sync_fern_docs_branch.py b/scripts/docs/sync_fern_docs_branch.py index ac983699..35656f14 100644 --- a/scripts/docs/sync_fern_docs_branch.py +++ b/scripts/docs/sync_fern_docs_branch.py @@ -91,23 +91,6 @@ def rewrite_doc_references(value: Any, pages_directory: str) -> Any: return value -def rewrite_pages_directory(value: Any, source_directory: str, target_directory: str) -> Any: - source_prefix = f"../{source_directory}/" - target_prefix = f"../{target_directory}/" - if isinstance(value, dict): - return { - key: ( - item.replace(source_prefix, target_prefix, 1) - if key in {"folder", "path"} and isinstance(item, str) and item.startswith(source_prefix) - else rewrite_pages_directory(item, source_directory, target_directory) - ) - for key, item in value.items() - } - if isinstance(value, list): - return [rewrite_pages_directory(item, source_directory, target_directory) for item in value] - return value - - def parse_release_tag(tag: str) -> tuple[str, str, bool]: match = VERSION_RE.fullmatch(tag) if match is None: @@ -207,33 +190,26 @@ def update_github_links(pages_dir: Path, tag: str) -> None: path.write_text(updated, encoding="utf-8") -def release_version(target_root: Path, tag: str) -> None: +def release_version(target_root: Path, tag: str, source_root: Path) -> None: display_tag, availability, is_stable = parse_release_tag(tag) target_fern = target_root / "fern" - pages_dev = target_fern / "pages-dev" pages_version = target_fern / f"pages-{display_tag}" versions_dir = target_fern / "versions" - dev_yml = versions_dir / "dev.yml" version_yml = versions_dir / f"{display_tag}.yml" docs_yml_path = target_fern / "docs.yml" + source_docs = source_root / "docs" - if not pages_dev.is_dir(): - raise FileNotFoundError(f"dev pages directory not found: {pages_dev}") - if not dev_yml.is_file(): - raise FileNotFoundError(f"dev navigation file not found: {dev_yml}") + if not source_docs.is_dir(): + raise FileNotFoundError(f"source docs directory not found: {source_docs}") + versions_dir.mkdir(parents=True, exist_ok=True) if pages_version.exists(): shutil.rmtree(pages_version) if version_yml.exists(): version_yml.unlink() - shutil.copytree(pages_dev, pages_version, ignore=docs_ignore) + shutil.copytree(source_docs, pages_version, ignore=docs_ignore) update_github_links(pages_version, tag) - - version_navigation = rewrite_pages_directory( - read_yaml(dev_yml), - "pages-dev", - f"pages-{display_tag}", - ) + version_navigation = rewrite_doc_references(read_yaml(source_docs / "index.yml"), f"pages-{display_tag}") write_yaml(version_yml, version_navigation) docs_yml = read_yaml(docs_yml_path) @@ -294,7 +270,8 @@ def parse_args() -> argparse.Namespace: sync_parser.add_argument("--source-root", type=Path, required=True) sync_parser.add_argument("--target-root", type=Path, required=True) - release_parser = subparsers.add_parser("release-version", help="snapshot dev docs as a version") + release_parser = subparsers.add_parser("release-version", help="snapshot source docs as a version") + release_parser.add_argument("--source-root", type=Path, required=True) release_parser.add_argument("--target-root", type=Path, required=True) release_parser.add_argument("--tag", required=True) @@ -306,7 +283,7 @@ def main() -> None: if args.command == "sync-dev": sync_dev(args.source_root.resolve(), args.target_root.resolve()) elif args.command == "release-version": - release_version(args.target_root.resolve(), args.tag) + release_version(args.target_root.resolve(), args.tag, args.source_root.resolve()) else: raise AssertionError(f"unhandled command: {args.command}")