diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index f97103ea..7aec0be5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -65,3 +65,101 @@ jobs:
run: pnpm install
- name: Test
run: pnpm test
+
+ build:
+ name: Build site
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #6.0.2
+ # Pulls version from packageManager key in package.json
+ - name: Setup pnpm
+ uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 #v6.1.0
+ - name: Setup Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e #v6.4.0
+ with:
+ node-version-file: '.nvmrc'
+ cache: 'pnpm'
+ - name: Install dependencies
+ run: pnpm install
+ - name: Build
+ # Production only, the Pages project had it that way so previews don't count as traffic.
+ env:
+ GTAG_TRACKING_ID: ${{ github.ref == 'refs/heads/main' && vars.GTAG_TRACKING_ID || '' }}
+ run: pnpm build
+ - name: Upload site
+ uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
+ with:
+ name: site
+ path: build/
+ retention-days: 7
+ # Deploys from here instead of the Pages git integration so a broken build fails CI.
+ # Fork PRs don't get secrets, so they build but skip the deploy.
+ deploy:
+ name: Deploy to Cloudflare Pages
+ needs: build
+ if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ # Queue deploys in order instead of racing them, otherwise the last to finish wins.
+ concurrency:
+ group: deploy-${{ github.ref }}
+ cancel-in-progress: false
+ steps:
+ - name: Comment deploy start
+ if: github.event_name != 'push'
+ uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2
+ with:
+ message-id: cloudflare-deploy
+ message: |
+ ### 🚧 Deploy Preview for *docs-nebula* building...
+
+ | Name | Link |
+ |---------------------------------|------------------------|
+ |🔨 Latest commit | ${{ github.sha }} |
+ |🔍 Latest deploy log | ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} |
+ ---
+ - name: Download site
+ uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4
+ with:
+ name: site
+ path: build/
+ # main goes to production, any other branch gets a preview
+ - name: Deploy
+ id: cloudflare
+ uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3
+ with:
+ apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ accountId: d79c0f33ec1480243a4c7fc3cd5a9ff3
+ command: pages deploy build --project-name=docs-nebula --branch=${{ github.head_ref || github.ref_name }}
+ wranglerVersion: '4.28.1'
+ - name: Link the deploy
+ env:
+ URL: ${{ steps.cloudflare.outputs.deployment-url }}
+ run: echo "Deployed to $URL" >> "$GITHUB_STEP_SUMMARY"
+ - name: Comment deploy url
+ if: github.event_name != 'push'
+ uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2
+ with:
+ message-id: cloudflare-deploy
+ message: |
+ ### ✅ Deploy Preview for *docs-nebula* ready!
+
+ | Name | Link |
+ |---------------------------------|------------------------|
+ |🔨 Latest commit | ${{ github.sha }} |
+ |🔍 Latest deploy log | ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} |
+ |😎 Deploy Preview Url | [${{ steps.cloudflare.outputs.deployment-url }}](${{ steps.cloudflare.outputs.deployment-url }}) |
+ |😎 Deploy Preview Alias | [${{ steps.cloudflare.outputs.pages-deployment-alias-url }}](${{ steps.cloudflare.outputs.pages-deployment-alias-url }}) |
+ ---
+
+ ci-pass-fail:
+ name: pass/fail check
+ if: always()
+ needs: [lint, format, test, build, deploy]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fail if any job failed or was cancelled
+ if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
+ run: exit 1