From b940ba88c9d4d59bd63766b1682c618236adb6f9 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:23:33 +0700 Subject: [PATCH 01/11] ci(workflow): split deployment and cleanup workflows --- .github/workflows/cleanup-preview.yaml | 47 +++++++++++++++++++ .../{deployment.yml => deployment.yaml} | 45 ++---------------- 2 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 .github/workflows/cleanup-preview.yaml rename .github/workflows/{deployment.yml => deployment.yaml} (59%) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml new file mode 100644 index 0000000..21ee163 --- /dev/null +++ b/.github/workflows/cleanup-preview.yaml @@ -0,0 +1,47 @@ +name: Cleanup Preview +on: + pull_request: + branches: + - main + types: + - closed + +concurrency: + group: cleanup-preview-${{ github.ref }} + cancel-in-progress: false +env: + NODE_VERSION: '24.11.1' + PNPM_VERSION: '10.23.0' + # For PR closed events this will resolve to preview- + STAGE: ${{ format('preview-{0}', github.event.number) }} +jobs: + cleanup: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + run_install: false + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: pnpm + - name: Install dependencies + run: pnpm install + - name: Destroy Preview Environment + run: pnpm alchemy destroy --stage ${{ env.STAGE }} + env: + # Alchemy + HOSTNAME: ${{ vars.HOSTNAME }} + ALCHEMY_SECRET: ${{ secrets.ALCHEMY_SECRET }} + ALCHEMY_STATE_TOKEN: ${{ secrets.ALCHEMY_STATE_TOKEN }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }} + PULL_REQUEST: ${{ github.event.number }} diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yaml similarity index 59% rename from .github/workflows/deployment.yml rename to .github/workflows/deployment.yaml index e082841..9640a7f 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yaml @@ -10,7 +10,6 @@ on: - opened - reopened - synchronize - - closed concurrency: group: deployment-${{ github.ref }} cancel-in-progress: false @@ -20,7 +19,6 @@ env: STAGE: ${{ github.event_name == 'pull_request' && format('preview-{0}', github.event.number) || (github.ref == 'refs/heads/main' && 'production' || github.ref_name) }} jobs: deploy: - if: ${{ github.event.action != 'closed' }} runs-on: ubuntu-latest environment: name: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }} @@ -29,18 +27,22 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v4 + - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} run_install: false + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm + - name: Install dependencies run: pnpm install + - name: Build and deploy run: pnpm alchemy deploy --stage ${{ env.STAGE }} env: @@ -62,42 +64,3 @@ jobs: POSTHOG_CLI_HOST: ${{ vars.POSTHOG_CLI_HOST }} POSTHOG_CLI_ENV_ID: ${{ secrets.POSTHOG_CLI_ENV_ID }} POSTHOG_CLI_TOKEN: ${{ secrets.POSTHOG_CLI_TOKEN }} - cleanup: - if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }} - runs-on: ubuntu-latest - environment: - name: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }} - permissions: - id-token: write - contents: read - pull-requests: write - steps: - - uses: actions/checkout@v4 - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ env.PNPM_VERSION }} - run_install: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: pnpm - - name: Install dependencies - run: pnpm install - - name: Safety Check - run: |- - if [ "${{ env.STAGE }}" = "production" ]; then - echo "ERROR: Cannot destroy production environment in cleanup job" - exit 1 - fi - - name: Destroy Preview Environment - run: pnpm alchemy destroy --stage ${{ env.STAGE }} - env: - # Alchemy - HOSTNAME: ${{ vars.HOSTNAME }} - ALCHEMY_SECRET: ${{ secrets.ALCHEMY_SECRET }} - ALCHEMY_STATE_TOKEN: ${{ secrets.ALCHEMY_STATE_TOKEN }} - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }} - PULL_REQUEST: ${{ github.event.number }} From c60e53b24976219fae19807f7f2b93660b702bb0 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:38:39 +0700 Subject: [PATCH 02/11] ci(workflow): split deployment into production and preview --- ...eployment.yaml => deployment-preview.yaml} | 15 ++---- .github/workflows/deployment-production.yaml | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 11 deletions(-) rename .github/workflows/{deployment.yaml => deployment-preview.yaml} (84%) create mode 100644 .github/workflows/deployment-production.yaml diff --git a/.github/workflows/deployment.yaml b/.github/workflows/deployment-preview.yaml similarity index 84% rename from .github/workflows/deployment.yaml rename to .github/workflows/deployment-preview.yaml index 9640a7f..89c09f8 100644 --- a/.github/workflows/deployment.yaml +++ b/.github/workflows/deployment-preview.yaml @@ -1,8 +1,5 @@ -name: Deployment +name: Deployment (Preview) on: - push: - branches: - - main pull_request: branches: - main @@ -11,38 +8,34 @@ on: - reopened - synchronize concurrency: - group: deployment-${{ github.ref }} + group: deployment-preview-${{ github.ref }} cancel-in-progress: false env: NODE_VERSION: '24.11.1' PNPM_VERSION: '10.23.0' - STAGE: ${{ github.event_name == 'pull_request' && format('preview-{0}', github.event.number) || (github.ref == 'refs/heads/main' && 'production' || github.ref_name) }} + STAGE: ${{ format('preview-{0}', github.event.number) }} jobs: deploy: runs-on: ubuntu-latest environment: - name: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }} + name: preview permissions: contents: read pull-requests: write steps: - uses: actions/checkout@v4 - - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} run_install: false - - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm - - name: Install dependencies run: pnpm install - - name: Build and deploy run: pnpm alchemy deploy --stage ${{ env.STAGE }} env: diff --git a/.github/workflows/deployment-production.yaml b/.github/workflows/deployment-production.yaml new file mode 100644 index 0000000..670443d --- /dev/null +++ b/.github/workflows/deployment-production.yaml @@ -0,0 +1,51 @@ +name: Deployment (Production) +on: + push: + branches: + - main +concurrency: + group: deployment-production-${{ github.ref }} + cancel-in-progress: false +env: + NODE_VERSION: '24.11.1' + PNPM_VERSION: '10.23.0' + STAGE: 'production' +jobs: + deploy: + runs-on: ubuntu-latest + environment: + name: production + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + run_install: false + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: pnpm + - name: Install dependencies + run: pnpm install + - name: Build and deploy + run: pnpm alchemy deploy --stage ${{ env.STAGE }} + env: + # Alchemy + HOSTNAME: ${{ vars.HOSTNAME }} + ALCHEMY_SECRET: ${{ secrets.ALCHEMY_SECRET }} + ALCHEMY_STATE_TOKEN: ${{ secrets.ALCHEMY_STATE_TOKEN }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }} + # Build + VITE_PUBLIC_POSTHOG_HOST: ${{ vars.VITE_PUBLIC_POSTHOG_HOST }} + VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.VITE_PUBLIC_POSTHOG_KEY }} + VITE_PUBLIC_POSTHOG_DEBUG: ${{ vars.VITE_PUBLIC_POSTHOG_DEBUG }} + VITE_PUBLIC_POSTHOG_ENABLED: ${{ vars.VITE_PUBLIC_POSTHOG_ENABLED }} + # Sourcemap inject and upload + POSTHOG_CLI_HOST: ${{ vars.POSTHOG_CLI_HOST }} + POSTHOG_CLI_ENV_ID: ${{ secrets.POSTHOG_CLI_ENV_ID }} + POSTHOG_CLI_TOKEN: ${{ secrets.POSTHOG_CLI_TOKEN }} From 956a826fcb3f13a0ba2c9068de4e21023bb91ae6 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:41:08 +0700 Subject: [PATCH 03/11] style: remove unused new line --- .github/workflows/cleanup-preview.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index 21ee163..1745346 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -5,7 +5,6 @@ on: - main types: - closed - concurrency: group: cleanup-preview-${{ github.ref }} cancel-in-progress: false From c402f6f5b13f4355c8157d666fce5341fc81f678 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:42:41 +0700 Subject: [PATCH 04/11] ci(test): add current branch to trigger workflows --- .github/workflows/deployment-preview.yaml | 1 + .github/workflows/deployment-production.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/deployment-preview.yaml b/.github/workflows/deployment-preview.yaml index 89c09f8..cb750bd 100644 --- a/.github/workflows/deployment-preview.yaml +++ b/.github/workflows/deployment-preview.yaml @@ -3,6 +3,7 @@ on: pull_request: branches: - main + - dev types: - opened - reopened diff --git a/.github/workflows/deployment-production.yaml b/.github/workflows/deployment-production.yaml index 670443d..071942a 100644 --- a/.github/workflows/deployment-production.yaml +++ b/.github/workflows/deployment-production.yaml @@ -3,6 +3,7 @@ on: push: branches: - main + - ci/split-workflow-into-multiple-files concurrency: group: deployment-production-${{ github.ref }} cancel-in-progress: false From 9d0eb8a3eb36e7f295889892902f8a0e8c2aff68 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:47:11 +0700 Subject: [PATCH 05/11] ci(test): add dev branch to cleanup preview workflow --- .github/workflows/cleanup-preview.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index 1745346..8567eb5 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -3,6 +3,7 @@ on: pull_request: branches: - main + - dev types: - closed concurrency: From 9b3b719fa75b52b37e7998c04eec175955141b29 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:51:24 +0700 Subject: [PATCH 06/11] fix(workflow): cleanup can't run for closed type only --- .github/workflows/cleanup-preview.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index 8567eb5..ed5ac0b 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -5,6 +5,9 @@ on: - main - dev types: + - opened + - reopened + - synchronize - closed concurrency: group: cleanup-preview-${{ github.ref }} @@ -17,6 +20,7 @@ env: jobs: cleanup: runs-on: ubuntu-latest + if: ${{ github.event.action == 'closed' }} permissions: id-token: write contents: read From fb7afedf43aa7139fa9d398a78d252c682facad4 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 15:58:01 +0700 Subject: [PATCH 07/11] fix(workflow): only run cleanup on closed with in preview env --- .github/workflows/cleanup-preview.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index ed5ac0b..c2f93e6 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -5,9 +5,6 @@ on: - main - dev types: - - opened - - reopened - - synchronize - closed concurrency: group: cleanup-preview-${{ github.ref }} @@ -20,7 +17,8 @@ env: jobs: cleanup: runs-on: ubuntu-latest - if: ${{ github.event.action == 'closed' }} + environment: + name: preview permissions: id-token: write contents: read From c274615a9cafc1ed2431e0e0b13ffd1ed67a1be9 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 16:00:52 +0700 Subject: [PATCH 08/11] ci: remove test branch --- .github/workflows/deployment-production.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deployment-production.yaml b/.github/workflows/deployment-production.yaml index 071942a..670443d 100644 --- a/.github/workflows/deployment-production.yaml +++ b/.github/workflows/deployment-production.yaml @@ -3,7 +3,6 @@ on: push: branches: - main - - ci/split-workflow-into-multiple-files concurrency: group: deployment-production-${{ github.ref }} cancel-in-progress: false From 9dbc29f31459c79efc5da65ffd8b88cf65629482 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 16:10:33 +0700 Subject: [PATCH 09/11] ci: remove environment --- .github/workflows/cleanup-preview.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index c2f93e6..8567eb5 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -17,8 +17,6 @@ env: jobs: cleanup: runs-on: ubuntu-latest - environment: - name: preview permissions: id-token: write contents: read From 235497681d3c8ca8c6e3a43eda73291ce9138ebe Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 16:14:42 +0700 Subject: [PATCH 10/11] ci: remove unused test branches --- .github/workflows/cleanup-preview.yaml | 1 - .github/workflows/deployment-preview.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index 8567eb5..1745346 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -3,7 +3,6 @@ on: pull_request: branches: - main - - dev types: - closed concurrency: diff --git a/.github/workflows/deployment-preview.yaml b/.github/workflows/deployment-preview.yaml index cb750bd..89c09f8 100644 --- a/.github/workflows/deployment-preview.yaml +++ b/.github/workflows/deployment-preview.yaml @@ -3,7 +3,6 @@ on: pull_request: branches: - main - - dev types: - opened - reopened From 54aa5834a654fb0f6624a8b9a5ef26b5600ac424 Mon Sep 17 00:00:00 2001 From: Edwin Tantawi Date: Tue, 13 Jan 2026 20:07:29 +0700 Subject: [PATCH 11/11] docs: add workflow description --- .github/workflows/cleanup-preview.yaml | 4 +++- .github/workflows/deployment-preview.yaml | 4 ++++ .github/workflows/deployment-production.yaml | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cleanup-preview.yaml b/.github/workflows/cleanup-preview.yaml index 1745346..e42d219 100644 --- a/.github/workflows/cleanup-preview.yaml +++ b/.github/workflows/cleanup-preview.yaml @@ -1,3 +1,6 @@ +# This workflow destroys the preview environment/deployment when a PR is closed. +# It prevents preview resources from leaking/stale after close. + name: Cleanup Preview on: pull_request: @@ -11,7 +14,6 @@ concurrency: env: NODE_VERSION: '24.11.1' PNPM_VERSION: '10.23.0' - # For PR closed events this will resolve to preview- STAGE: ${{ format('preview-{0}', github.event.number) }} jobs: cleanup: diff --git a/.github/workflows/deployment-preview.yaml b/.github/workflows/deployment-preview.yaml index 89c09f8..05be620 100644 --- a/.github/workflows/deployment-preview.yaml +++ b/.github/workflows/deployment-preview.yaml @@ -1,3 +1,7 @@ +# Deploys a per-PR preview environment for this repository. +# Triggered when a PR targeting main (commonly from release/* or hotfix/*) is opened, reopened, or updated (synchronize). +# Deploys to the "preview" environment with stage name "preview-" . + name: Deployment (Preview) on: pull_request: diff --git a/.github/workflows/deployment-production.yaml b/.github/workflows/deployment-production.yaml index 670443d..d0492ed 100644 --- a/.github/workflows/deployment-production.yaml +++ b/.github/workflows/deployment-production.yaml @@ -1,3 +1,6 @@ +# Deploys the main branch to the production environment on every push to main. +# Deploys to the GitHub environment "production" with stage name "production". + name: Deployment (Production) on: push: