Skip to content
Merged
48 changes: 48 additions & 0 deletions .github/workflows/cleanup-preview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# 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:
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'
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 }}
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
name: Deployment
# 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-<PR_NUMBER>" .

name: Deployment (Preview)
on:
push:
branches:
- main
pull_request:
branches:
- main
types:
- opened
- reopened
- synchronize
- closed
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:
if: ${{ github.event.action != 'closed' }}
runs-on: ubuntu-latest
environment:
name: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }}
name: preview
permissions:
contents: read
pull-requests: write
Expand Down Expand Up @@ -62,42 +61,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 }}
54 changes: 54 additions & 0 deletions .github/workflows/deployment-production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 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:
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 }}