diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad912e52dc2cdf..d89816f03b1577 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -157,6 +157,7 @@ jobs: name: dist path: dist + post-build: name: Post Build needs: build diff --git a/.github/workflows/incremental-build-preview.yml b/.github/workflows/incremental-build-preview.yml new file mode 100644 index 00000000000000..78fdb506650586 --- /dev/null +++ b/.github/workflows/incremental-build-preview.yml @@ -0,0 +1,131 @@ +name: Incremental Build Preview + +on: + pull_request: + branches: + - production + +concurrency: + group: incremental-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + incremental-build: + name: Incremental Build + # Only run for PRs from the same repo (not forks), same as the regular preview + if: github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - uses: actions/setup-node@v6 + with: + node-version: 24.x + cache: npm + + # -- Install docs dependencies (gets regular astro from npm) -- + - name: Restore node_modules (cache hit) + id: node-modules-cache + uses: actions/cache@v5 + with: + path: node_modules + key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ hashFiles('package.json') }} + + - name: Install node_modules (cache miss) + run: npm ci + if: steps.node-modules-cache.outputs.cache-hit != 'true' + + # -- Download pre-built ced-astro fork from R2 -- + - name: Download ced-astro tarball from R2 + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CED_ASTRO_R2_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: 2f3dc21d188ba781322b520bbde5fb5a + run: | + npx wrangler r2 object get ced-astro/builds/latest.tgz --file /tmp/astro.tgz --remote --config /dev/null \ + || { echo "::error::Failed to download ced-astro tarball from R2. Has the GitLab CI pipeline run?"; exit 1; } + + # -- Override astro with the fork -- + - name: Install ced-astro over regular astro + run: npm install /tmp/astro.tgz --no-save + + # -- Restore previous build from R2 -- + - name: Download previous build from R2 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.BUILD_CACHE_R2_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.BUILD_CACHE_R2_SECRET_KEY }} + AWS_DEFAULT_REGION: auto + run: | + mkdir -p .previous-build + aws s3 cp "s3://cloudflare-docs-production-build-cache/latest.tar.gz" /tmp/previous-build.tar.gz \ + --endpoint-url https://b54f07a6c269ecca2fa60f1ae4920c99.r2.cloudflarestorage.com || true + if [ -f /tmp/previous-build.tar.gz ]; then + tar -xzf /tmp/previous-build.tar.gz -C .previous-build + fi + + # -- Run the build -- + - name: Restore Astro assets from cache + uses: actions/cache@v5 + with: + path: | + node_modules/.astro/assets + key: static + + - name: Build + run: | + export NODE_OPTIONS='--max-old-space-size=8192' + npx astro build --previous-dist .previous-build/dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # -- Upload build to R2 for future incremental runs -- + - name: Upload build cache to R2 + if: always() && hashFiles('dist/index.html') != '' + env: + AWS_ACCESS_KEY_ID: ${{ secrets.BUILD_CACHE_R2_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.BUILD_CACHE_R2_SECRET_KEY }} + AWS_DEFAULT_REGION: auto + run: | + tar -czf /tmp/build-cache.tar.gz dist/ $([ -d dist-meta ] && echo "dist-meta/") + aws s3 cp /tmp/build-cache.tar.gz "s3://cloudflare-docs-production-build-cache/latest.tar.gz" --endpoint-url https://b54f07a6c269ecca2fa60f1ae4920c99.r2.cloudflarestorage.com + + # -- Deploy preview -- + - name: Deploy to Cloudflare Workers + id: deploy + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + run: | + SHORT_SHA="${{ github.event.pull_request.head.sha }}" + SHORT_SHA="${SHORT_SHA:0:8}" + echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT" + npx wrangler deploy --dispatch-namespace preview-deployments --name "incr-${SHORT_SHA}" + + - name: Post preview URL on PR + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + SHORT_SHA="${{ steps.deploy.outputs.short_sha }}" + PREVIEW_URL="https://incr-${SHORT_SHA}.preview.developers.cloudflare.com" + PR_NUMBER="${{ github.event.pull_request.number }}" + + # Check for existing incremental build comment + EXISTING=$(gh api \ + "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + --jq '.[] | select(.user.login == "github-actions[bot]" and (.body | contains("Incremental Build Preview"))) | .id' \ + | head -1) + + BODY="**Incremental Build Preview:** ${PREVIEW_URL}" + + if [ -n "$EXISTING" ]; then + gh api \ + "repos/${{ github.repository }}/issues/comments/${EXISTING}" \ + -X PATCH -f body="$BODY" + else + gh api \ + "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + -f body="$BODY" + fi diff --git a/.gitignore b/.gitignore index 5f310e5baed4b6..f0d5178de94ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ # build output dist/ +dist-meta/ distmd/ distllms/ + # generated types .astro/ diff --git a/astro.config.ts b/astro.config.ts index 7927b24ae3c5cd..e754d2cf23b4a9 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -90,6 +90,16 @@ export default defineConfig({ experimental: { contentIntellisense: true, }, + incrementalBuild: { + pageCollections: ["docs"], + partialCollections: ["partials"], + partialResolver: (name: string, props: any) => { + if (name === "Render" && props.file && props.product) { + return `src/content/partials/${props.product}/${props.file}.mdx`; + } + return null; + }, + }, server: { port: 1111, }, diff --git a/package.json b/package.json index a99ac778818344..be1ea0acaa222f 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "astro": "npx astro", "prebuild": "npx tsx bin/fetch-skills.ts", "build": "export NODE_OPTIONS='--max-old-space-size=8192' || set NODE_OPTIONS=\"--max-old-space-size=8192\" && npx astro build", + "build:incremental": "export NODE_OPTIONS='--max-old-space-size=8192' || set NODE_OPTIONS=\"--max-old-space-size=8192\" && npx astro build --previous-dist ./build/cache/dist", "typegen:worker": "npx wrangler types ./worker/worker-configuration.d.ts", "check": "npm run check:astro && npm run check:worker", "check:astro": "npx astro check",