diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml index bf10369cc..6f9ec2cc3 100644 --- a/.github/workflows/docs-preview.yml +++ b/.github/workflows/docs-preview.yml @@ -1,13 +1,14 @@ name: Docs Preview -# Builds the mkdocs site for a PR and deploys it to Cloudflare Pages. +# Builds the docs site for a PR and deploys it to Cloudflare Pages. # -# Security: mkdocs executes Python from the PR (mkdocstrings imports src/mcp, -# `!!python/name:` directives). The build is gated by `authorize` (admin sender -# for auto-preview, admin/maintainer commenter for /preview-docs) and isolated -# from Cloudflare secrets — `build` runs PR code with no secrets and hands the -# static site to `deploy` via an artifact, so PR code never shares a runner -# with the Cloudflare token. +# Security: the build executes Python from the PR (mkdocstrings imports +# src/mcp, `!!python/name:` config directives run, and heads may ship their +# own build scripts). The build is gated by `authorize` (admin sender for +# auto-preview, admin/maintainer commenter for /preview-docs) and isolated +# from Cloudflare secrets — `build` runs PR code with no secrets and hands +# the static site to `deploy` via an artifact, so PR code never shares a +# runner with the Cloudflare token. # # Required configuration: # - secrets.CLOUDFLARE_API_TOKEN (scope: Account → Cloudflare Pages → Edit) @@ -21,6 +22,7 @@ on: - docs/** - docs_src/** - mkdocs.yml + - scripts/docs/** - pyproject.toml issue_comment: types: [created] @@ -128,17 +130,30 @@ jobs: enable-cache: false version: 0.9.5 - - run: uv sync --frozen --group docs - - run: uv run --frozen --no-sync mkdocs build - env: - # Silence mkdocs-material's MkDocs 2.0 warning banner in CI logs. - NO_MKDOCS_2_WARNING: "1" + # pull_request_target runs this workflow file from the base branch, so + # the whole recipe — dependency sync included — must come from the + # checkout itself: heads that ship scripts/docs/build.sh (the Zensical + # toolchain) build with it; older heads, and v1.x heads previewed via + # /preview-docs, still build with MkDocs. Both arms must write the site + # to site/. Keep the detection in sync with build_site() in + # scripts/build-docs.sh. + - run: | + if [ -f scripts/docs/build.sh ]; then + bash scripts/docs/build.sh + else + uv sync --frozen --group docs + # The env var silences mkdocs-material's MkDocs 2.0 warning banner. + NO_MKDOCS_2_WARNING=1 uv run --frozen --no-sync mkdocs build + fi - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: site path: site/ retention-days: 1 + # An empty site/ means the build arm broke its output contract; fail + # here instead of surfacing as a confusing download error in deploy. + if-no-files-found: error deploy: needs: [authorize, build]