Skip to content

Commit 94cbdd7

Browse files
committed
ci: create reusable deploy-website action and separate deployment workflow (#489)
# Refactor website deployment workflow with dedicated GitHub Action This PR improves the website deployment process by: 1. Creating a reusable `deploy-website` GitHub Action that: - Validates Supabase environment variables - Handles both preview and production deployments - Posts deployment comments 2. Separating deployment workflows: - Modified `ci.yml` to only handle PR preview deployments - Added new `deploy.yml` workflow for production deployments on main branch This approach provides better separation of concerns, reduces duplication, and makes the deployment process more maintainable. The reusable action ensures consistent deployment behavior across both preview and production environments.
1 parent 05b6836 commit 94cbdd7

3 files changed

Lines changed: 135 additions & 56 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: 'Deploy Website'
2+
description: 'Deploy website to Cloudflare Pages (preview or production)'
3+
4+
inputs:
5+
environment:
6+
description: 'Deployment environment (preview or production)'
7+
required: true
8+
supabase-url:
9+
description: 'Supabase URL for the website'
10+
required: true
11+
supabase-anon-key:
12+
description: 'Supabase anonymous key'
13+
required: true
14+
cloudflare-api-token:
15+
description: 'Cloudflare API token'
16+
required: true
17+
cloudflare-account-id:
18+
description: 'Cloudflare account ID'
19+
required: true
20+
plausible-proxy-url:
21+
description: 'Plausible proxy URL (optional, typically production only)'
22+
required: false
23+
default: ''
24+
preview-name:
25+
description: 'Preview name for PR deployments (e.g., pr-123)'
26+
required: false
27+
default: ''
28+
preview-url:
29+
description: 'Preview URL for deployment comments'
30+
required: false
31+
default: ''
32+
production-url:
33+
description: 'Production URL for deployment comments'
34+
required: true
35+
default: 'https://pgflow.dev'
36+
37+
runs:
38+
using: 'composite'
39+
steps:
40+
- name: Validate Supabase environment variables
41+
shell: bash
42+
env:
43+
VITE_SUPABASE_URL: ${{ inputs.supabase-url }}
44+
VITE_SUPABASE_ANON_KEY: ${{ inputs.supabase-anon-key }}
45+
run: |
46+
if [ -z "$VITE_SUPABASE_URL" ]; then
47+
echo "::error::VITE_SUPABASE_URL is not set"
48+
exit 1
49+
fi
50+
if [ -z "$VITE_SUPABASE_ANON_KEY" ]; then
51+
echo "::error::VITE_SUPABASE_ANON_KEY is not set"
52+
exit 1
53+
fi
54+
if [[ ! "$VITE_SUPABASE_URL" =~ ^https:// ]]; then
55+
echo "::error::VITE_SUPABASE_URL must use https:// (not http://)"
56+
exit 1
57+
fi
58+
echo "Supabase environment variables validated"
59+
60+
- name: Deploy website
61+
shell: bash
62+
env:
63+
CLOUDFLARE_API_TOKEN: ${{ inputs.cloudflare-api-token }}
64+
CLOUDFLARE_ACCOUNT_ID: ${{ inputs.cloudflare-account-id }}
65+
VITE_SUPABASE_URL: ${{ inputs.supabase-url }}
66+
VITE_SUPABASE_ANON_KEY: ${{ inputs.supabase-anon-key }}
67+
PLAUSIBLE_PROXY_URL: ${{ inputs.plausible-proxy-url }}
68+
CLOUDFLARE_BRANCH: ${{ inputs.preview-name }}
69+
run: |
70+
if [ "${{ inputs.environment }}" = "preview" ]; then
71+
pnpm nx run website:deploy:preview --skip-nx-cache
72+
else
73+
pnpm nx run website:deploy --skip-nx-cache
74+
fi
75+
76+
- name: Post deployment comment
77+
if: always()
78+
uses: ./.github/actions/deployment-comment
79+
with:
80+
project-name: Website
81+
preview-url: ${{ inputs.preview-url }}
82+
production-url: ${{ inputs.production-url }}

.github/workflows/ci.yml

Lines changed: 12 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ name: CI
22
on:
33
workflow_dispatch:
44
pull_request:
5-
push:
6-
branches: [main]
7-
# TODO: Optimize - separate deployment workflow to avoid re-running tests on main
85

96
concurrency:
107
group: ${{ github.workflow }}-${{ github.ref }}
@@ -146,19 +143,14 @@ jobs:
146143
if: steps.check.outputs.affected == 'true'
147144
run: pnpm nx run cli:e2e
148145

149-
# ────────────────────────────────── 3. DEPLOY WEBSITE ───────────────────────────
146+
# ────────────────────────────────── 3. DEPLOY WEBSITE (PREVIEW) ───────────────────────────
150147
deploy-website:
148+
if: github.event_name == 'pull_request'
151149
needs: [build-and-test, edge-worker-e2e, cli-e2e]
152150
runs-on: ubuntu-latest
153-
environment: ${{ github.event_name == 'pull_request' && 'preview' || 'production' }}
151+
environment: preview
154152
env:
155153
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
156-
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
157-
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
158-
DEPLOYMENT_ENV: ${{ github.event_name == 'pull_request' && 'preview' || 'production' }}
159-
VITE_SUPABASE_URL: ${{ github.event_name == 'pull_request' && secrets.WEBSITE_PREVIEW_SUPABASE_URL || secrets.WEBSITE_PRODUCTION_SUPABASE_URL }}
160-
VITE_SUPABASE_ANON_KEY: ${{ github.event_name == 'pull_request' && secrets.WEBSITE_PREVIEW_SUPABASE_ANON_KEY || secrets.WEBSITE_PRODUCTION_SUPABASE_ANON_KEY }}
161-
PLAUSIBLE_PROXY_URL: ${{ secrets.WEBSITE_PLAUSIBLE_PROXY_URL }}
162154
steps:
163155
- uses: actions/checkout@v4
164156
with:
@@ -169,63 +161,27 @@ jobs:
169161
github-token: ${{ secrets.GITHUB_TOKEN }}
170162
atlas-cloud-token: ${{ secrets.ATLAS_CLOUD_TOKEN }}
171163

172-
- name: Set Nx base for affected commands
173-
run: |
174-
echo "NX_BASE=origin/main" >> $GITHUB_ENV
175-
echo "NX_HEAD=HEAD" >> $GITHUB_ENV
176-
177164
- name: Check if website is affected
178165
id: check-affected
179166
run: |
180-
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/main" ]]; then
181-
# Always deploy website on main branch
182-
echo "affected=true" >> $GITHUB_OUTPUT
183-
echo "Main branch push - deploying website to production"
184-
elif pnpm nx show projects --affected -t build --base="$NX_BASE" --head="$NX_HEAD" | grep -q "^website$"; then
167+
if pnpm nx show projects --affected -t build --base=origin/main --head=HEAD | grep -q "^website$"; then
185168
echo "affected=true" >> $GITHUB_OUTPUT
186169
echo "Website is affected by changes"
187170
else
188171
echo "affected=false" >> $GITHUB_OUTPUT
189172
echo "Website is not affected by changes - skipping deployment"
190173
fi
191174
192-
- name: Validate Supabase environment variables
175+
- name: Deploy website preview
193176
if: steps.check-affected.outputs.affected == 'true'
194-
run: |
195-
if [ -z "$VITE_SUPABASE_URL" ]; then
196-
echo "❌ Error: VITE_SUPABASE_URL is not set"
197-
echo "Required GitHub secret missing: WEBSITE_${{ github.event_name == 'pull_request' && 'PREVIEW' || 'PRODUCTION' }}_SUPABASE_URL"
198-
exit 1
199-
fi
200-
if [ -z "$VITE_SUPABASE_ANON_KEY" ]; then
201-
echo "❌ Error: VITE_SUPABASE_ANON_KEY is not set"
202-
echo "Required GitHub secret missing: WEBSITE_${{ github.event_name == 'pull_request' && 'PREVIEW' || 'PRODUCTION' }}_SUPABASE_ANON_KEY"
203-
exit 1
204-
fi
205-
if [[ ! "$VITE_SUPABASE_URL" =~ ^https:// ]]; then
206-
echo "❌ Error: VITE_SUPABASE_URL must use https:// (not http://)"
207-
echo "Current value: $VITE_SUPABASE_URL"
208-
exit 1
209-
fi
210-
echo "✅ Supabase environment variables are valid"
211-
212-
- name: Deploy website
213-
id: deploy-website
214-
if: steps.check-affected.outputs.affected == 'true'
215-
env:
216-
CLOUDFLARE_BRANCH: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'main' }}
217-
run: |
218-
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
219-
pnpm nx run website:deploy:preview --skip-nx-cache
220-
else
221-
pnpm nx run website:deploy --skip-nx-cache
222-
fi
223-
224-
- name: Post deployment comment
225-
if: always()
226-
uses: ./.github/actions/deployment-comment
177+
uses: ./.github/actions/deploy-website
227178
with:
228-
project-name: Website
179+
environment: preview
180+
supabase-url: ${{ secrets.WEBSITE_PREVIEW_SUPABASE_URL }}
181+
supabase-anon-key: ${{ secrets.WEBSITE_PREVIEW_SUPABASE_ANON_KEY }}
182+
cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
183+
cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
184+
preview-name: pr-${{ github.event.pull_request.number }}
229185
preview-url: https://pr-${{ github.event.pull_request.number }}.pgflow.pages.dev
230186
production-url: https://pgflow.dev
231187

.github/workflows/deploy.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: deploy-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
permissions:
13+
contents: read
14+
pull-requests: write # for deployment comments
15+
16+
jobs:
17+
deploy-website:
18+
runs-on: ubuntu-latest
19+
environment: production
20+
env:
21+
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
27+
- uses: ./.github/actions/setup
28+
with:
29+
github-token: ${{ secrets.GITHUB_TOKEN }}
30+
atlas-cloud-token: ${{ secrets.ATLAS_CLOUD_TOKEN }}
31+
32+
- name: Deploy website to production
33+
uses: ./.github/actions/deploy-website
34+
with:
35+
environment: production
36+
supabase-url: ${{ secrets.WEBSITE_PRODUCTION_SUPABASE_URL }}
37+
supabase-anon-key: ${{ secrets.WEBSITE_PRODUCTION_SUPABASE_ANON_KEY }}
38+
cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
39+
cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
40+
plausible-proxy-url: ${{ secrets.WEBSITE_PLAUSIBLE_PROXY_URL }}
41+
production-url: https://pgflow.dev

0 commit comments

Comments
 (0)