diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml index 540825b..f3e5a06 100644 --- a/.github/workflows/pr-preview.yml +++ b/.github/workflows/pr-preview.yml @@ -14,163 +14,84 @@ concurrency: cancel-in-progress: true jobs: - build-preview: - runs-on: ubuntu-latest - outputs: - artifact_name: ${{ steps.meta.outputs.artifact_name }} - screenshot_name: ${{ steps.meta.outputs.screenshot_name }} - post_path: ${{ steps.changed_post.outputs.post_path }} - post_url: ${{ steps.changed_post.outputs.post_url }} - steps: - - name: Set artifact name - id: meta - run: | - echo "artifact_name=site-preview-pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT" - echo "screenshot_name=site-screenshots-pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT" - - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true - - - name: Build site - run: bundle exec jekyll build - - - name: Detect changed post - id: changed_post - env: - BASE_SHA: ${{ github.event.pull_request.base.sha }} - HEAD_SHA: ${{ github.sha }} - run: | - mapfile -t posts < <(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- '_posts/*.md') - if [[ ${#posts[@]} -eq 0 ]]; then - echo "post_path=" >> "$GITHUB_OUTPUT" - echo "post_url=/" >> "$GITHUB_OUTPUT" - exit 0 - fi - - post="${posts[0]}" - slug="$(basename "$post" .md)" - slug="${slug#????-??-??-}" - echo "post_path=$post" >> "$GITHUB_OUTPUT" - echo "post_url=/$slug/" >> "$GITHUB_OUTPUT" - - - name: Upload site artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.meta.outputs.artifact_name }} - path: _site - retention-days: 7 - - - name: Install Playwright Chromium - run: npx -y playwright@1.53.0 install --with-deps chromium - - - name: Capture preview screenshot - env: - POST_URL: ${{ steps.changed_post.outputs.post_url }} - run: | - python3 -m http.server --directory _site 4173 > /tmp/pr-preview-server.log 2>&1 & - server_pid=$! - trap 'kill "$server_pid"' EXIT - - for i in {1..20}; do - if curl -fsS "http://127.0.0.1:4173${POST_URL}" >/dev/null; then - break - fi - sleep 0.5 - done - - npx -y playwright@1.53.0 screenshot --browser=chromium --full-page "http://127.0.0.1:4173${POST_URL}" preview-long.png - - - name: Upload screenshot artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.meta.outputs.screenshot_name }} - path: preview-long.png - retention-days: 7 - deploy-cloudflare-preview: runs-on: ubuntu-latest - needs: build-preview - if: ${{ !github.event.pull_request.head.repo.fork && vars.CLOUDFLARE_PAGES_PROJECT != '' && vars.CLOUDFLARE_ACCOUNT_ID != '' && secrets.CLOUDFLARE_API_TOKEN != '' }} + if: ${{ !github.event.pull_request.head.repo.fork && vars.CLOUDFLARE_PAGES_PROJECT != '' && vars.CLOUDFLARE_ACCOUNT_ID != '' }} permissions: contents: read deployments: write outputs: - preview_url: ${{ steps.cf.outputs.alias }} + preview_url: ${{ steps.cf.outputs.pages-deployment-alias-url }} + deployment_url: ${{ steps.cf.outputs.deployment-url }} + has_token: ${{ steps.token_check.outputs.has_token }} steps: + - name: Check Cloudflare token + id: token_check + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + run: | + if [ -n "$CLOUDFLARE_API_TOKEN" ]; then + echo "has_token=true" >> "$GITHUB_OUTPUT" + else + echo "has_token=false" >> "$GITHUB_OUTPUT" + fi + - name: Checkout - uses: actions/checkout@v4 + if: ${{ steps.token_check.outputs.has_token == 'true' }} + uses: actions/checkout@v6 - name: Set up Ruby + if: ${{ steps.token_check.outputs.has_token == 'true' }} uses: ruby/setup-ruby@v1 with: + ruby-version: "3.1" bundler-cache: true - name: Build site + if: ${{ steps.token_check.outputs.has_token == 'true' }} run: bundle exec jekyll build - name: Publish to Cloudflare Pages id: cf - uses: cloudflare/pages-action@v1 + if: ${{ steps.token_check.outputs.has_token == 'true' }} + uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} - projectName: ${{ vars.CLOUDFLARE_PAGES_PROJECT }} - directory: _site + command: pages deploy _site --project-name=${{ vars.CLOUDFLARE_PAGES_PROJECT }} --branch=pr-${{ github.event.number }} gitHubToken: ${{ secrets.GITHUB_TOKEN }} - branch: pr-${{ github.event.number }} - wranglerVersion: '3' + wranglerVersion: "3" comment-preview: runs-on: ubuntu-latest - needs: [build-preview, deploy-cloudflare-preview] - if: ${{ always() && !github.event.pull_request.head.repo.fork && needs.build-preview.result == 'success' && (needs.deploy-cloudflare-preview.result == 'success' || needs.deploy-cloudflare-preview.result == 'skipped') }} + needs: deploy-cloudflare-preview + if: ${{ always() && !github.event.pull_request.head.repo.fork && (needs.deploy-cloudflare-preview.result == 'success' || needs.deploy-cloudflare-preview.result == 'skipped' || needs.deploy-cloudflare-preview.result == 'failure') }} steps: - name: Add or update PR preview comment uses: actions/github-script@v7 env: RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - ARTIFACT_NAME: ${{ needs.build-preview.outputs.artifact_name }} - SCREENSHOT_NAME: ${{ needs.build-preview.outputs.screenshot_name }} - POST_PATH: ${{ needs.build-preview.outputs.post_path }} - POST_URL: ${{ needs.build-preview.outputs.post_url }} CLOUDFLARE_URL: ${{ needs.deploy-cloudflare-preview.outputs.preview_url }} - CLOUDFLARE_ENABLED: ${{ vars.CLOUDFLARE_PAGES_PROJECT != '' && vars.CLOUDFLARE_ACCOUNT_ID != '' && secrets.CLOUDFLARE_API_TOKEN != '' }} + CLOUDFLARE_DEPLOYMENT_URL: ${{ needs.deploy-cloudflare-preview.outputs.deployment_url }} + CLOUDFLARE_ENABLED: ${{ vars.CLOUDFLARE_PAGES_PROJECT != '' && vars.CLOUDFLARE_ACCOUNT_ID != '' && needs.deploy-cloudflare-preview.outputs.has_token == 'true' }} CLOUDFLARE_RESULT: ${{ needs.deploy-cloudflare-preview.result }} with: script: | const marker = ""; - const postLine = process.env.POST_PATH - ? `- Changed post detected: \`${process.env.POST_PATH}\`\n- Suggested file to open after extracting: \`_site${process.env.POST_URL}index.html\`` - : "- No post markdown file changed in this PR; preview starts at `_site/index.html`."; + const previewUrl = process.env.CLOUDFLARE_URL || process.env.CLOUDFLARE_DEPLOYMENT_URL; const cloudflareLine = process.env.CLOUDFLARE_ENABLED === "true" ? (process.env.CLOUDFLARE_RESULT === "success" - ? (process.env.CLOUDFLARE_URL - ? `- Hosted preview (Cloudflare Pages): [Open preview](${process.env.CLOUDFLARE_URL})` + ? (previewUrl + ? `- Hosted preview (Cloudflare Pages): [Open preview](${previewUrl})` : "- Hosted preview (Cloudflare Pages): deployed, but URL output was empty. Check deployment details.") - : "- Hosted preview (Cloudflare Pages): deployment did not succeed; check workflow logs.") + : `- Hosted preview (Cloudflare Pages): deployment did not succeed; check [workflow logs](${process.env.RUN_URL}).`) : "- Hosted preview (Cloudflare Pages): not configured (set repository vars/secrets; see README)."; const body = `${marker} ## PR Preview Ready - A static preview was built for this PR. - - - Download artifact: **${process.env.ARTIFACT_NAME}** from [this workflow run](${process.env.RUN_URL}) - - Download long screenshot artifact: **${process.env.SCREENSHOT_NAME}** from [this workflow run](${process.env.RUN_URL}) - ${postLine} ${cloudflareLine} - - Quick local preview: - - Extract artifact zip - - Run: \`python3 -m http.server --directory _site 4173\` - - Open: \`http://localhost:4173${process.env.POST_URL}\` `; const { owner, repo } = context.repo; diff --git a/README.md b/README.md index 9ead0b6..3c14f50 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,8 @@ This repo now includes a PR preview workflow at `.github/workflows/pr-preview.ym For each pull request update, it: 1. Builds the site with Jekyll. -2. Uploads the full `_site` output as a workflow artifact. -3. Captures a full-page screenshot artifact for quick visual review. -4. Optionally deploys to Cloudflare Pages for a hosted preview URL. -5. Posts or updates a sticky PR comment with links and instructions. +2. Deploys to Cloudflare Pages for a hosted preview URL. +3. Posts or updates a sticky PR comment with the preview link. This gives reviewers a consistent way to preview rendered pages without running Jekyll locally. @@ -63,4 +61,4 @@ Notes: - Cloudflare deploy is skipped automatically if these vars/secrets are missing. - Cloudflare deploy is also skipped for forked PRs for security. -- Artifact and screenshot previews still run even when Cloudflare is skipped. +- No local artifact or screenshot is generated by this workflow.