cloudflare/vinext
Publicmirrored from https://github.com/cloudflare/vinextAvailable
.github/workflows/deploy-examples.yml
164lines · modecode
| 1 | name: Deploy Examples |
| 2 | |
| 3 | on: |
| 4 | push: |
| 5 | branches: [main] |
| 6 | pull_request: |
| 7 | branches: [main] |
| 8 | |
| 9 | jobs: |
| 10 | deploy: |
| 11 | name: Deploy ${{ matrix.example.name }} |
| 12 | runs-on: ubuntu-latest |
| 13 | permissions: |
| 14 | contents: read |
| 15 | deployments: write |
| 16 | strategy: |
| 17 | fail-fast: false |
| 18 | matrix: |
| 19 | example: |
| 20 | - name: app-router-cloudflare |
| 21 | project: app-router-cloudflare |
| 22 | wrangler_config: dist/server/wrangler.json |
| 23 | - name: pages-router-cloudflare |
| 24 | project: pages-router-cloudflare |
| 25 | wrangler_config: dist/pages_router_cloudflare/wrangler.json |
| 26 | - name: app-router-playground |
| 27 | project: app-router-playground |
| 28 | wrangler_config: dist/server/wrangler.json |
| 29 | - name: realworld-api-rest |
| 30 | project: realworld-api-rest |
| 31 | wrangler_config: dist/realworld_api_rest/wrangler.json |
| 32 | - name: nextra-docs-template |
| 33 | project: nextra-docs-template |
| 34 | wrangler_config: dist/server/wrangler.json |
| 35 | - name: benchmarks |
| 36 | project: benchmarks |
| 37 | wrangler_config: dist/server/wrangler.json |
| 38 | - name: hackernews |
| 39 | project: hackernews |
| 40 | wrangler_config: dist/server/wrangler.json |
| 41 | steps: |
| 42 | - uses: actions/checkout@v4 |
| 43 | |
| 44 | - uses: pnpm/action-setup@v4 |
| 45 | |
| 46 | - uses: actions/setup-node@v4 |
| 47 | with: |
| 48 | node-version: 24 |
| 49 | cache: pnpm |
| 50 | |
| 51 | - run: pnpm install |
| 52 | |
| 53 | - name: Build vinext plugin |
| 54 | run: pnpm run build |
| 55 | |
| 56 | - name: Build example |
| 57 | run: pnpm exec vite build |
| 58 | working-directory: examples/${{ matrix.example.name }} |
| 59 | |
| 60 | - name: Apply D1 migrations (benchmarks only) |
| 61 | if: matrix.example.name == 'benchmarks' && github.event_name == 'push' && github.ref == 'refs/heads/main' |
| 62 | uses: cloudflare/wrangler-action@v3 |
| 63 | with: |
| 64 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} |
| 65 | accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |
| 66 | workingDirectory: examples/benchmarks |
| 67 | command: d1 migrations apply vinext-benchmarks --remote |
| 68 | |
| 69 | - name: Deploy to Cloudflare Workers (Production) |
| 70 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' |
| 71 | uses: cloudflare/wrangler-action@v3 |
| 72 | with: |
| 73 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} |
| 74 | accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |
| 75 | workingDirectory: examples/${{ matrix.example.name }} |
| 76 | command: deploy --config ${{ matrix.example.wrangler_config }} |
| 77 | |
| 78 | - name: Deploy Preview Version |
| 79 | if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository |
| 80 | uses: cloudflare/wrangler-action@v3 |
| 81 | with: |
| 82 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} |
| 83 | accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |
| 84 | workingDirectory: examples/${{ matrix.example.name }} |
| 85 | command: versions upload --config ${{ matrix.example.wrangler_config }} --preview-alias pr-${{ github.event.pull_request.number }} |
| 86 | |
| 87 | smoke-test: |
| 88 | name: Smoke Test Deployments |
| 89 | runs-on: ubuntu-latest |
| 90 | needs: deploy |
| 91 | steps: |
| 92 | - uses: actions/checkout@v4 |
| 93 | |
| 94 | - name: Smoke test (production) |
| 95 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' |
| 96 | run: ./scripts/smoke-test.sh |
| 97 | |
| 98 | - name: Smoke test (preview) |
| 99 | if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository |
| 100 | run: ./scripts/smoke-test.sh --preview pr-${{ github.event.pull_request.number }} |
| 101 | |
| 102 | comment: |
| 103 | name: Comment Preview URLs |
| 104 | runs-on: ubuntu-latest |
| 105 | needs: deploy |
| 106 | if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository |
| 107 | permissions: |
| 108 | pull-requests: write |
| 109 | steps: |
| 110 | - name: Comment PR with preview URLs |
| 111 | uses: actions/github-script@v7 |
| 112 | with: |
| 113 | script: | |
| 114 | const prNumber = context.issue.number; |
| 115 | const alias = `pr-${prNumber}`; |
| 116 | |
| 117 | const examples = [ |
| 118 | { name: 'app-router-cloudflare', project: 'app-router-cloudflare' }, |
| 119 | { name: 'pages-router-cloudflare', project: 'pages-router-cloudflare' }, |
| 120 | { name: 'app-router-playground', project: 'app-router-playground', original: 'https://app-router.vercel.app' }, |
| 121 | { name: 'realworld-api-rest', project: 'realworld-api-rest' }, |
| 122 | { name: 'nextra-docs-template', project: 'nextra-docs-template' }, |
| 123 | { name: 'benchmarks', project: 'benchmarks' }, |
| 124 | { name: 'hackernews', project: 'hackernews', original: 'https://next-react-server-components.vercel.app' }, |
| 125 | ]; |
| 126 | |
| 127 | const { data: comments } = await github.rest.issues.listComments({ |
| 128 | owner: context.repo.owner, |
| 129 | repo: context.repo.repo, |
| 130 | issue_number: prNumber, |
| 131 | }); |
| 132 | |
| 133 | const marker = '<!-- vinext-deploy-previews -->'; |
| 134 | const existingComment = comments.find(c => c.body?.includes(marker)); |
| 135 | |
| 136 | const rows = examples |
| 137 | .map(e => { |
| 138 | const orig = e.original ? `[original](${e.original})` : ''; |
| 139 | return `| ${e.name} | [preview](https://${alias}-${e.project}.vinext.workers.dev) | [production](https://${e.project}.vinext.workers.dev) | ${orig} |`; |
| 140 | }) |
| 141 | .join('\n'); |
| 142 | |
| 143 | const body = [ |
| 144 | marker, |
| 145 | '| Example | Preview | Production | Original |', |
| 146 | '|---------|---------|------------|----------|', |
| 147 | rows, |
| 148 | ].join('\n'); |
| 149 | |
| 150 | if (existingComment) { |
| 151 | await github.rest.issues.updateComment({ |
| 152 | owner: context.repo.owner, |
| 153 | repo: context.repo.repo, |
| 154 | comment_id: existingComment.id, |
| 155 | body, |
| 156 | }); |
| 157 | } else { |
| 158 | await github.rest.issues.createComment({ |
| 159 | owner: context.repo.owner, |
| 160 | repo: context.repo.repo, |
| 161 | issue_number: prNumber, |
| 162 | body, |
| 163 | }); |
| 164 | } |
| 165 | |