docs.ymlyaml · 127 linesall
name: Deploy Docs

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      # The twoslash showcase gallery is rendered from these at docs-build time
      # (docs/scripts/build-twoslash-showcase.sh), so a fixture/renderer change
      # must redeploy the docs too.
      - 'libs/twoslash/**'
      - 'package.json'
      - 'yarn.lock'
      - '.yarnrc.yml'
  # No `branches` filter: a stacked PR's base is a feature branch, and its
  # preview matters as much as a PR against main. The deploy is a preview
  # either way — `ci/deploy-cloudflare-pages.sh` keys it on the PR's head
  # branch (`GITHUB_HEAD_REF`), never on the base — so only the push to main
  # above is a production deploy.
  pull_request:
    paths:
      - 'docs/**'
      # The twoslash showcase gallery is rendered from these at docs-build time
      # (docs/scripts/build-twoslash-showcase.sh), so a fixture/renderer change
      # must redeploy the docs too.
      - 'libs/twoslash/**'
      - 'package.json'
      - 'yarn.lock'
      - '.yarnrc.yml'
  workflow_dispatch:

concurrency:
  group: docs-${{ github.ref }}
  cancel-in-progress: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      # Corepack asks before downloading the packageManager pin. CI must not.
      COREPACK_ENABLE_DOWNLOAD_PROMPT: '0'
    # yarn install + the wasm nix build + VitePress build + Cloudflare deploy run ~5m
    # uncontended; runner contention during stacked-PR storms stretches the
    # nix setup/teardown past 15m, cancelling after the deploy had succeeded.
    timeout-minutes: 30

    permissions:
      contents: read
      deployments: write
      pull-requests: write

    steps:
      - name: Checkout
        uses: actions/checkout@v7

      # `yarn docs:build` first runs `build:wasm`, which invokes
      # `nix build .#table-wasm` to compile the drawTable playground module.
      # Install Nix and wire up the binary cache so the ldc-wasm toolchain is
      # pulled from the cache rather than built from source.
      - name: Setup Nix
        uses: ./.github/actions/setup-nix
        with:
          push-to-cache: true
          cachix-cache: ${{ vars.CACHIX_CACHE }}
          cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
          trusted-public-keys: ${{ vars.TRUSTED_PUBLIC_KEYS }}
          substituters: ${{ vars.SUBSTITUTERS }}
          use-nix-cache: true

      - name: Setup Node.js
        uses: actions/setup-node@v7
        with:
          node-version: 24

      # setup-node's `cache: yarn` calls `yarn --version` while the action
      # runs, before Corepack has put Yarn on PATH. Enable Corepack first,
      # then cache the folder Yarn itself reports.
      - name: Enable Corepack
        env:
          COREPACK_ENABLE_DOWNLOAD_PROMPT: '0'
        run: corepack enable

      - name: Get Yarn cache directory
        id: yarn-cache
        run: echo "dir=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT"

      - name: Cache Yarn
        uses: actions/cache@v6
        with:
          path: ${{ steps.yarn-cache.outputs.dir }}
          key: yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
          restore-keys: yarn-${{ runner.os }}-

      - name: Install dependencies
        run: yarn install --immutable

      # The README badges read these from the deployed site. Regenerating them
      # here rather than committing them keeps the number honest: it is
      # computed from the same aggregate `ci --ci-stats --merges` prints, and a
      # committed JSON would be stale from the merge after the one that wrote
      # it. A failure here is not worth failing a docs deploy over -- the
      # previously deployed badge simply stays up.
      - name: Refresh the merge badges
        continue-on-error: true
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          nix run .#ci-minimal -- --ci-stats --merges \
            --repo "$GITHUB_REPOSITORY" --limit 1000 \
            --badge-dir docs/public/badges

      # Same headroom as the CI job's build — see the note there.
      - name: Build VitePress site
        env:
          NODE_OPTIONS: --max-old-space-size=8192
        run: yarn docs:build

      # Shared with CircleCI — see ci/README.md. The script wraps the same two
      # calls `cloudflare/wrangler-action` and `actions/github-script` made:
      # `wrangler pages deploy`, then a marker-keyed upsert of the preview
      # comment (so a re-run edits its own comment rather than appending).
      - name: Deploy to Cloudflare Pages & comment the preview URL
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          GITHUB_TOKEN: ${{ github.token }}
        run: ci/deploy-cloudflare-pages.sh