From 8b7e5f2ec94109e768f9e37406e1d3428787233c Mon Sep 17 00:00:00 2001 From: Drew Butler Date: Wed, 17 Jun 2026 13:31:58 -0400 Subject: [PATCH] ci: ephemeral PR preview deploys; production-only on main Add preview.yml: each PR runs 'wrangler versions upload' (preview version, no production change) and comments the preview URL. Simplify deploy.yml to deploy the production Worker on push to main only (v2 staging path removed). --- .github/workflows/deploy.yml | 10 +++--- .github/workflows/preview.yml | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3a4cae3..10fc054 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,14 +1,14 @@ name: Deploy -# Push to main -> production Worker `dbtlr-com` (serves dbtlr.com once the custom domain is attached). -# Push to v2 -> staging Worker `dbtlr-com-v2` on workers.dev. +# Push to main -> production Worker `dbtlr-com` (serves dbtlr.com). +# PR previews live in preview.yml. on: push: - branches: [main, v2] + branches: [main] workflow_dispatch: concurrency: - group: deploy-${{ github.ref_name }} + group: deploy-main cancel-in-progress: true jobs: @@ -28,4 +28,4 @@ jobs: with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: ${{ github.ref_name == 'main' && 'deploy' || 'deploy --name dbtlr-com-v2' }} + command: deploy diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 0000000..0250667 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,61 @@ +name: PR Preview + +# Every PR to main gets an ephemeral preview: `wrangler versions upload` uploads a +# new version of the `dbtlr-com` Worker WITHOUT deploying it to production, and we +# post its preview URL on the PR. Production is untouched until the PR merges. +on: + pull_request: + branches: [main] + +concurrency: + group: preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + +jobs: + preview: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v6 + - uses: actions/setup-node@v6 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm check + - run: pnpm build + - id: preview + uses: cloudflare/wrangler-action@v4 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: versions upload + - name: Comment preview URL + uses: actions/github-script@v9 + with: + script: | + const url = `${{ steps.preview.outputs.deployment-url }}`; + const marker = ''; + const body = [ + marker, + '### ๐Ÿ”Ž Preview deploy', + '', + url ? url : '_No preview URL produced โ€” check the workflow logs._', + '', + `Updated for ${context.sha.slice(0, 7)} ยท ephemeral version, not production.`, + ].join('\n'); + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const existing = comments.find((c) => c.body && c.body.includes(marker)); + if (existing) { + await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body }); + } else { + await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body }); + }