feat: add per-PR documentation preview deployments#333
Open
Nonnyjoe wants to merge 2 commits into
Open
Conversation
Build every pull request and publish it to a unique, navigable GitHub Pages URL so reviewers can see the rendered docs before merging. Production (AWS Amplify at docs.cartesi.io) is unaffected; previews are served from a separate origin (https://<owner>.github.io/<repo>/pr-preview/pr-<N>/). Fork-safe by design (no PAT or secrets), via a two-workflow split: - .github/workflows/preview-build.yml (pull_request): builds the PR with a read-only token and NO access to secrets, then uploads the static site as an artifact. Replaces the build-only build.yml so each PR builds exactly once. - .github/workflows/preview-deploy.yml (workflow_run): runs from the default branch in the trusted base-repo context, downloads the artifact, publishes it to the gh-pages branch under pr-preview/pr-<N>/, posts a sticky comment with the URL, and removes the preview when the PR is closed. It never executes PR code, so previews work for pull requests from forks without exposing any secret. - docusaurus.config.js: url/baseUrl are now env-overridable (DOCS_URL/DOCS_BASE_URL) and default to docs.cartesi.io and "/", so local builds and Amplify are unchanged. - src/pages/index.js and src/components/SelectVersion/DropdownVersion.js: resolve the homepage redirect and the version dropdown against baseUrl so they work under the preview sub-path. Both are no-ops in production (baseUrl "/"). One-time setup (maintainer): - Settings -> Actions -> General -> Workflow permissions: "Read and write". - After the first preview deploy creates the gh-pages branch, set Settings -> Pages source to the gh-pages branch (root). - If branch protection requires the old "Build" check, update it to "preview-build".
This was referenced Jun 3, 2026
lynoferraz
approved these changes
Jun 3, 2026
…aren't empty The plugin keyed its URL map on doc.permalink, which includes the site baseUrl. Under a sub-path baseUrl (GitHub Pages PR previews at /<repo>/pr-preview/pr-<N>/), postBuild wrote each page's full .md to a baseUrl-nested dead path, so the URL people request (.../page.md) only got the title-only generated-index stub. Normalize permalinks to baseUrl-relative in buildUrlMap — one change that fixes the .md output paths, the llms.txt index/alias route matching, and the llms-full.txt page URLs. No-op at baseUrl "/", so production is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds per-PR documentation preview deployments: every pull request is built and published to a unique, navigable URL so reviewers can see exactly how the change renders before merging.
docs.cartesi.iostays on AWS Amplify. Previews are served from a separate origin on GitHub Pages:https://<owner>.github.io/<repo>/pr-preview/pr-<N>/.How it works (two-workflow split)
A forked PR's workflow gets a read-only token and no secrets by design. To support fork previews securely, the work is split:
preview-build.yml(pull_request) — runs untrusted PR code withcontents: readand no secrets. It builds the site (pointed at the Pages sub-path viaDOCS_URL/DOCS_BASE_URL) and uploads it as an artifact. Replaces the build-onlybuild.ymlso each PR builds once.preview-deploy.yml(workflow_run) — runs from the default branch in the trusted base-repo context, so it has write access. It downloads the already-built artifact, publishes it to thegh-pagesbranch underpr-preview/pr-<N>/, posts a sticky PR comment with the URL, and removes the preview when the PR closes. It never executes PR code — only the inert static artifact — so this is safe for forked PRs.pull_request_targetis deliberately not used. The deploy job validates the PR number (which arrives via the artifact) before using it in any path/API call, and serializes writes togh-pages.Changes
.github/workflows/preview-build.yml.github/workflows/preview-deploy.ymlgh-pages, sticky comment, teardown on close.github/workflows/build.ymlpreview-buildto avoid building twicedocusaurus.config.jsurl/baseUrlmade env-overridable; defaults unchanged (docs.cartesi.io,/)src/pages/index.jsuseBaseUrl(no-op in prod)src/components/SelectVersion/DropdownVersion.jsbaseUrl(no-op in prod)The last two are required for previews to be navigable under a sub-path; both are no-ops in production (where
baseUrlis/).One-time setup
Previews activate only after the workflows are on the default branch (this PR) and:
gh-pagesand comment).gh-pagesbranch: Settings → Pages → Source =gh-pages// (root). Enabling Pages does not affect Amplify ordocs.cartesi.io(separate origin).Buildstatus check, topreview-build.