-
Notifications
You must be signed in to change notification settings - Fork 53
241 lines (208 loc) · 8.84 KB
/
preview-deploy.yml
File metadata and controls
241 lines (208 loc) · 8.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
name: Preview Deploy (External Contributors)
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
statuses: write
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
jobs:
deploy-preview:
name: Deploy Preview
if: github.event.pull_request.head.repo.fork == true
runs-on: ubuntu-latest
environment: preview-deploy-approval
steps:
- name: Set PR info
id: pr
run: |
echo "head_sha=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
- name: Set pending status
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: '${{ steps.pr.outputs.head_sha }}',
state: 'pending',
context: 'Preview Deploy',
description: 'Detecting changes and deploying...'
});
- name: Checkout PR head
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Fetch base commit
run: |
git fetch origin ${{ github.event.pull_request.base.sha }}
git branch base-sha FETCH_HEAD
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.12.3
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.17.0
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Detect changed apps with Turbo
id: changes
run: |
# Get affected packages using turbo's change detection
# Use immutable base SHA reference instead of mutable branch name
BASE_REF="base-sha"
echo "Detecting changes between $BASE_REF and HEAD..."
# Use turbo to find affected packages with build task
affected=$(pnpm turbo build --filter="...[$BASE_REF]" --dry-run=json 2>/dev/null || echo '{"packages":[]}')
echo "Turbo output:"
echo "$affected" | head -50
# Extract package names from turbo output
packages=$(echo "$affected" | jq -r '.packages[]' 2>/dev/null || echo "")
echo "Affected packages:"
echo "$packages"
# Filter to only deployable apps
apps_to_deploy=""
while IFS= read -r pkg; do
case "$pkg" in
"status.app"|"hub"|"portfolio"|"api"|"status.network")
apps_to_deploy="$apps_to_deploy $pkg"
;;
esac
done <<< "$packages"
apps_to_deploy=$(echo "$apps_to_deploy" | xargs)
echo "Apps to deploy: $apps_to_deploy"
echo "apps=$apps_to_deploy" >> $GITHUB_OUTPUT
- name: Install Vercel CLI
run: npm install -g vercel@latest
- name: Deploy status.app
id: deploy-status-app
if: contains(steps.changes.outputs.apps, 'status.app')
run: |
vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
vercel build --token=${{ secrets.VERCEL_TOKEN }}
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> $GITHUB_OUTPUT
working-directory: apps/status.app
env:
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_STATUS_APP }}
- name: Deploy hub
id: deploy-hub
if: contains(steps.changes.outputs.apps, 'hub')
run: |
vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
vercel build --token=${{ secrets.VERCEL_TOKEN }}
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> $GITHUB_OUTPUT
working-directory: apps/hub
env:
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_HUB }}
- name: Deploy portfolio
id: deploy-portfolio
if: contains(steps.changes.outputs.apps, 'portfolio')
run: |
vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
vercel build --token=${{ secrets.VERCEL_TOKEN }}
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> $GITHUB_OUTPUT
working-directory: apps/portfolio
env:
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_PORTFOLIO }}
- name: Deploy api
id: deploy-api
if: contains(steps.changes.outputs.apps, 'api')
run: |
vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
vercel build --token=${{ secrets.VERCEL_TOKEN }}
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> $GITHUB_OUTPUT
working-directory: apps/api
env:
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_API }}
- name: Deploy status.network
id: deploy-status-network
if: contains(steps.changes.outputs.apps, 'status.network')
run: |
vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
vercel build --token=${{ secrets.VERCEL_TOKEN }}
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> $GITHUB_OUTPUT
working-directory: apps/status.network
env:
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_STATUS_NETWORK }}
- name: Set status and comment PR
uses: actions/github-script@v7
with:
script: |
const deployments = [];
if ('${{ steps.deploy-status-app.outputs.url }}'.trim()) {
deployments.push({ name: 'status.app', url: '${{ steps.deploy-status-app.outputs.url }}' });
}
if ('${{ steps.deploy-hub.outputs.url }}'.trim()) {
deployments.push({ name: 'hub', url: '${{ steps.deploy-hub.outputs.url }}' });
}
if ('${{ steps.deploy-portfolio.outputs.url }}'.trim()) {
deployments.push({ name: 'portfolio', url: '${{ steps.deploy-portfolio.outputs.url }}' });
}
if ('${{ steps.deploy-api.outputs.url }}'.trim()) {
deployments.push({ name: 'api', url: '${{ steps.deploy-api.outputs.url }}' });
}
if ('${{ steps.deploy-status-network.outputs.url }}'.trim()) {
deployments.push({ name: 'status.network', url: '${{ steps.deploy-status-network.outputs.url }}' });
}
if (deployments.length === 0) {
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: '${{ steps.pr.outputs.head_sha }}',
state: 'success',
context: 'Preview Deploy',
description: 'No deployable app changes detected'
});
await github.rest.issues.createComment({
issue_number: ${{ steps.pr.outputs.pr_number }},
owner: context.repo.owner,
repo: context.repo.repo,
body: `⚠️ **No apps to deploy**\n\nNo changes detected in deployable apps.`
});
return;
}
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: '${{ steps.pr.outputs.head_sha }}',
state: 'success',
context: 'Preview Deploy',
description: `Deployed ${deployments.length} app(s) successfully`
});
let table = '| Project | Deployment | Preview | Comments |\n';
table += '|---------|------------|---------|----------|\n';
for (const dep of deployments) {
table += `| ${dep.name} | ✅ Ready | [Preview](${dep.url}) | [Comment](${dep.url}) |\n`;
}
const body = `**Preview deployments are ready!**\n\n${table}\n\n---\n*Deployed via GitHub Actions*`;
await github.rest.issues.createComment({
issue_number: ${{ steps.pr.outputs.pr_number }},
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
- name: Set failure status
if: failure()
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: '${{ steps.pr.outputs.head_sha }}',
state: 'failure',
context: 'Preview Deploy',
description: 'Deployment failed - check Actions logs'
});