Deploy Static Docs #43
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
| name: Deploy Static Docs | |
| # Renders the published docs site to static HTML and uploads it to Cloudflare | |
| # Pages using the public fernenterprise/docs-static-build container. | |
| # | |
| # Runs AFTER "Publish Docs" completes successfully, so the ledger manifest + CAS | |
| # blobs the container reads from S3 are already up to date. Also runnable | |
| # manually via workflow_dispatch. | |
| # | |
| # The container takes three logical inputs (see the fern-platform astro | |
| # package README): the docs URL, an S3 key to READ the ledger blobs, and a CF | |
| # Pages key to UPLOAD the built site. All are provided as GitHub secrets. | |
| # workflow_run is required so this runs after "Publish Docs" updates the ledger. | |
| # It's safe here: the job checks out no (untrusted) code, is granted no token | |
| # permissions (permissions: {}), and only runs a pinned public container with | |
| # read-only S3 + Cloudflare deploy credentials. | |
| on: # zizmor: ignore[dangerous-triggers] | |
| workflow_run: | |
| workflows: ["Publish Docs"] | |
| types: | |
| - completed | |
| workflow_dispatch: | |
| inputs: | |
| image_tag: | |
| description: "fernenterprise/docs-static-build tag to run" | |
| required: false | |
| default: "latest" | |
| type: string | |
| concurrency: | |
| group: ${{ github.workflow }} | |
| cancel-in-progress: false | |
| permissions: {} | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| # For workflow_run: only proceed when the upstream "Publish Docs" run | |
| # succeeded (a failed/cancelled publish leaves the ledger unchanged, so | |
| # there's nothing new to build). workflow_dispatch runs always proceed. | |
| if: >- | |
| github.event_name == 'workflow_dispatch' || | |
| github.event.workflow_run.conclusion == 'success' | |
| steps: | |
| - name: Build static docs and deploy to Cloudflare Pages | |
| env: | |
| # 1. Docs URL — the site to build. | |
| NEXT_PUBLIC_DOCS_DOMAIN: fern.docs.buildwithfern.com/learn | |
| # This is the real production deploy of buildwithfern.com/learn. Off | |
| # Vercel there is no VERCEL_ENV, so without this the build treats itself | |
| # as a preview and bakes `noindex, nofollow` + `robots.txt: Disallow: /` | |
| # into every page. | |
| FERN_DOCS_DEPLOYMENT_ENV: production | |
| # 2. S3 key — read the published ledger manifest + CAS blobs. | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| AWS_REGION: us-east-1 | |
| DOCS_DEFINITION_S3_BUCKET_NAME: fdr-prod-docs-definitions-public | |
| CONTENT_ADDRESSABLE_FILES_S3_BUCKET_NAME: fdr-prod-content-addressable-storage | |
| # 3. CF Pages key — upload the built dist/ to Cloudflare Pages. | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| CF_PAGES_PROJECT: ${{ secrets.CF_PAGES_PROJECT }} | |
| CF_PAGES_BRANCH: ${{ secrets.CF_PAGES_BRANCH }} | |
| # Optional: used only to resolve Ask AI enablement at build time. | |
| FERN_TOKEN: ${{ secrets.FERN_TOKEN }} | |
| # Vercel Edge Config connection string. Read at build time to resolve | |
| # per-domain edge flags (e.g. `isWhitelabeled`, which hides the | |
| # "Built with Fern" footer badge). If empty, the edge-config read | |
| # returns undefined and getEdgeFlags falls back to all-false defaults, | |
| # leaking the badge onto every page — see the guard in the run step. | |
| EDGE_CONFIG: ${{ secrets.EDGE_CONFIG }} | |
| IMAGE_TAG: ${{ github.event.inputs.image_tag || 'latest' }} | |
| run: | | |
| IMAGE="fernenterprise/docs-static-build:${IMAGE_TAG}" | |
| echo "Running $IMAGE for $NEXT_PUBLIC_DOCS_DOMAIN" | |
| # Hard guard: this workflow only ever builds one known-whitelabeled | |
| # site (fern.docs.buildwithfern.com), so a missing EDGE_CONFIG means the | |
| # edge flags default to false and the "Built with Fern" badge leaks — | |
| # that's always wrong here. Fail the deploy rather than ship it green. | |
| if [ -z "${EDGE_CONFIG:-}" ]; then | |
| echo "::error title=EDGE_CONFIG missing::EDGE_CONFIG is empty — edge flags (whitelabel, etc.) would fall back to defaults and leak the 'Built with Fern' badge. Set the EDGE_CONFIG repo secret." | |
| exit 1 | |
| fi | |
| docker pull "$IMAGE" | |
| # Forward each secret by name (values come from this step's env), so no | |
| # secret is interpolated into the command line. | |
| docker run --rm \ | |
| -e NEXT_PUBLIC_DOCS_DOMAIN \ | |
| -e FERN_DOCS_DEPLOYMENT_ENV \ | |
| -e AWS_ACCESS_KEY_ID \ | |
| -e AWS_SECRET_ACCESS_KEY \ | |
| -e AWS_REGION \ | |
| -e DOCS_DEFINITION_S3_BUCKET_NAME \ | |
| -e CONTENT_ADDRESSABLE_FILES_S3_BUCKET_NAME \ | |
| -e CLOUDFLARE_API_TOKEN \ | |
| -e CLOUDFLARE_ACCOUNT_ID \ | |
| -e CF_PAGES_PROJECT \ | |
| -e CF_PAGES_BRANCH \ | |
| -e FERN_TOKEN \ | |
| -e EDGE_CONFIG \ | |
| "$IMAGE" |