-
Notifications
You must be signed in to change notification settings - Fork 7
Enable deploy previews via cloudflare #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
70e6b96
e6f6f97
a218994
0f39113
59c2191
939c1d4
fff39a1
e841560
18c0148
0966b6f
e680187
17b1a4f
b7d8fa1
941093b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // Minimizes previous deploy-preview comments so only the latest is visible. | ||
| // Called from preview-deploy.yml via actions/github-script. | ||
|
|
||
| export default async function run({ github, context, prNumber }) { | ||
| const comments = await github.paginate(github.rest.issues.listComments, { | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| }); | ||
|
|
||
| await Promise.all( | ||
| comments | ||
| .filter( | ||
| (c) => | ||
| c.user.login === "github-actions[bot]" && | ||
| c.body.includes("<!-- deploy-preview -->") | ||
| ) | ||
| .map((c) => | ||
| github.graphql( | ||
| ` | ||
| mutation($id: ID!) { | ||
| minimizeComment(input: { subjectId: $id, classifier: OUTDATED }) { | ||
| minimizedComment { isMinimized } | ||
| } | ||
| } | ||
| `, | ||
| { id: c.node_id } | ||
| ) | ||
| ) | ||
| ); | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| name: Build Preview | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [main] | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: preview-build-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Build site | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | ||
| with: | ||
| node-version: "24" | ||
| cache: "npm" | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Build GAP website | ||
| run: npm run build | ||
|
|
||
| - name: Upload build artifact | ||
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | ||
| with: | ||
| name: preview-build | ||
| path: _site | ||
| include-hidden-files: true | ||
| retention-days: 3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| name: Deploy Preview | ||
|
|
||
| on: | ||
| workflow_run: | ||
| workflows: ["Build Preview"] | ||
| types: [completed] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| actions: read | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| deploy: | ||
| name: Deploy preview to Cloudflare | ||
| runs-on: ubuntu-latest | ||
| if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }} | ||
|
|
||
| steps: | ||
| - name: Checkout wrangler config | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | ||
| with: | ||
| ref: main | ||
| sparse-checkout: | | ||
| wrangler.jsonc | ||
| .github/scripts | ||
|
|
||
| # Security: actions/download-artifact handles zip extraction safely | ||
| # (immune to zip-slip), and the artifact only contains static HTML/CSS/JS | ||
| # built by the unprivileged preview-build workflow. | ||
| - name: Download build artifact | ||
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | ||
| with: | ||
| name: preview-build | ||
| run-id: ${{ github.event.workflow_run.id }} | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| path: _site | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK, this downloads a tarball or similar and extracts it to that folder. There have been vulnerabilities in the past where a maliciously structured tarball has resulted in the extractor writing files outside of the target directory, are we certain we’re not at risk of this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like
Tested here:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Relies on this logic from the |
||
|
|
||
| - name: Get PR number | ||
| id: pr | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| PR_NUM=$(gh pr list --repo "${{ github.repository }}" \ | ||
| --head "${{ github.event.workflow_run.head_branch }}" \ | ||
| --json number --jq '.[0].number') | ||
| if ! [[ "$PR_NUM" =~ ^[0-9]+$ ]]; then | ||
| echo "::error::Could not determine PR number" | ||
| exit 1 | ||
| fi | ||
| echo "number=$PR_NUM" >> "$GITHUB_OUTPUT" | ||
|
|
||
| # Security: Wrangler is configured for static asset serving only (see | ||
| # wrangler.jsonc). The uploaded content is pre-built HTML/CSS/JS with no | ||
| # server-side execution capability. | ||
| - name: Deploy preview to Cloudflare Workers | ||
| id: deploy | ||
| uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4 | ||
| with: | ||
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | ||
| command: versions upload --no-bundle --preview-alias "pr-${{ steps.pr.outputs.number }}" --message "PR #${{ steps.pr.outputs.number }} preview (${{ github.event.workflow_run.head_sha }})" | ||
|
|
||
| - name: Hide old deploy preview comments | ||
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 | ||
| with: | ||
| script: | | ||
|
magicmark marked this conversation as resolved.
|
||
| const { default: run } = await import('${{ github.workspace }}/.github/scripts/hide-old-deploy-comments.mjs'); | ||
| await run({ github, context, prNumber: ${{ steps.pr.outputs.number }} }); | ||
|
|
||
| - name: Comment on PR (success) | ||
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 | ||
| with: | ||
| script: | | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: ${{ steps.pr.outputs.number }}, | ||
| body: [ | ||
| '<!-- deploy-preview -->', | ||
| '### 🚀 Deploy Preview', | ||
| '', | ||
| '- **This commit:** ${{ steps.deploy.outputs.deployment-url }}', | ||
| '- **This PR** <sub>(kept up to date)</sub>: https://pr-${{ steps.pr.outputs.number }}-gaps.graphql-foundation.workers.dev' | ||
| ].join('\n') | ||
| }); | ||
|
|
||
| - name: Comment on PR (failure) | ||
| if: failure() | ||
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 | ||
| with: | ||
| script: | | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: ${{ steps.pr.outputs.number }}, | ||
| body: 'Deploy preview failed.\n\n```\ngh run view ${{ github.run_id }} --repo ${{ github.repository }} --log-failed\n```' | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "$schema": "node_modules/wrangler/config-schema.json", | ||
| "name": "gaps", | ||
| "compatibility_date": "2026-05-23", | ||
| "assets": { | ||
| "directory": "./_site" | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.