@@ -19,15 +19,52 @@ concurrency:
19
19
cancel-in-progress : true
20
20
21
21
jobs :
22
- Process-Deployment :
23
- # For issue comments, only run on /deploy-review-app command
24
- # For push events, run if it's master branch OR if PR exists and has a review app
22
+ # Job to handle staging deployments
23
+ Deploy-Staging :
24
+ if : github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
25
+ runs-on : ubuntu-latest
26
+ permissions :
27
+ contents : read
28
+ deployments : write
29
+ env :
30
+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
31
+ CPLN_TOKEN : ${{ secrets.CPLN_TOKEN_STAGING }}
32
+ CPLN_ORG : ${{ vars.CPLN_ORG_STAGING }}
33
+ STAGING_APP_NAME : ${{ vars.STAGING_APP_NAME }}
34
+
35
+ steps :
36
+ - uses : actions/checkout@v4
37
+ with :
38
+ fetch-depth : 0
39
+
40
+ - name : Verify Environment Variables
41
+ run : |
42
+ # Required actions secrets
43
+ : "${GITHUB_TOKEN:?Required secret GITHUB_TOKEN not set}"
44
+ : "${CPLN_TOKEN:?Required secret CPLN_TOKEN_STAGING not set}"
45
+
46
+ # Required actions variables
47
+ : "${CPLN_ORG:?Required variable CPLN_ORG_STAGING not set}"
48
+ : "${STAGING_APP_NAME:?Required variable STAGING_APP_NAME not set}"
49
+
50
+ - name : Setup Environment
51
+ uses : ./.github/actions/setup-environment
52
+
53
+ - name : Deploy to Control Plane
54
+ id : deploy
55
+ uses : ./.github/actions/deploy-to-control-plane
56
+ with :
57
+ app_name : ${{ env.STAGING_APP_NAME }}
58
+ org : ${{ env.CPLN_ORG }}
59
+ github_token : ${{ secrets.GITHUB_TOKEN }}
60
+
61
+ # Job to handle review app deployments
62
+ Deploy-Review-App :
25
63
if : |
26
64
(github.event_name == 'issue_comment' &&
27
65
github.event.issue.pull_request &&
28
66
github.event.comment.body == '/deploy-review-app') ||
29
- github.event_name == 'push' ||
30
- github.event_name == 'workflow_dispatch'
67
+ github.event_name == 'push'
31
68
runs-on : ubuntu-latest
32
69
permissions :
33
70
contents : read
38
75
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
39
76
CPLN_TOKEN : ${{ secrets.CPLN_TOKEN_STAGING }}
40
77
CPLN_ORG : ${{ vars.CPLN_ORG_STAGING }}
41
- STAGING_APP_NAME : ${{ vars.STAGING_APP_NAME }}
42
78
REVIEW_APP_PREFIX : ${{ vars.REVIEW_APP_PREFIX }}
43
-
79
+
44
80
steps :
45
81
- uses : actions/checkout@v4
46
82
with :
54
90
55
91
# Required actions variables
56
92
: "${CPLN_ORG:?Required variable CPLN_ORG_STAGING not set}"
57
- : "${STAGING_APP_NAME:?Required variable STAGING_APP_NAME not set}"
58
93
: "${REVIEW_APP_PREFIX:?Required variable REVIEW_APP_PREFIX not set}"
59
-
60
- echo "All required secrets and variables are set"
61
94
62
95
- name : Setup Environment
63
96
uses : ./.github/actions/setup-environment
@@ -69,10 +102,12 @@ jobs:
69
102
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
70
103
run : |
71
104
# Get PR number from branch
72
- PR_NUMBER=$(gh pr list --head ${{ github.ref_name }} --json number --jq '.[0].number')
105
+ PR_DATA=$(gh pr list --head ${{ github.ref_name }} --json number,headRefOid --jq '.[0]')
106
+ PR_NUMBER=$(echo "$PR_DATA" | jq -r '.number')
73
107
if [ -n "$PR_NUMBER" ]; then
74
108
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
75
109
echo "APP_NAME=${{ env.REVIEW_APP_PREFIX }}-pr-$PR_NUMBER" >> $GITHUB_ENV
110
+ echo "COMMIT_SHA=$(echo "$PR_DATA" | jq -r '.headRefOid')" >> $GITHUB_ENV
76
111
echo "has_pr=true" >> $GITHUB_OUTPUT
77
112
else
78
113
echo "No PR found for this branch"
@@ -82,209 +117,34 @@ jobs:
82
117
- name : Set PR Number for Comment Event
83
118
if : github.event_name == 'issue_comment'
84
119
run : |
120
+ # Get PR data including the commit SHA
121
+ PR_DATA=$(gh pr view ${{ github.event.issue.number }} --json headRefOid --jq '.')
85
122
echo "PR_NUMBER=${{ github.event.issue.number }}" >> $GITHUB_ENV
86
123
echo "APP_NAME=${{ env.REVIEW_APP_PREFIX }}-pr-${{ github.event.issue.number }}" >> $GITHUB_ENV
124
+ echo "COMMIT_SHA=$(echo "$PR_DATA" | jq -r '.headRefOid')" >> $GITHUB_ENV
87
125
88
- - name : Setup Deployment Configuration
89
- id : setup
126
+ - name : Check Review App Exists
127
+ id : check-app
90
128
run : |
91
- # Function to check if app exists
92
- check_app_exists() {
93
- local app_name=$1
94
- cpln workload get "$app_name" --org "${{ env.CPLN_ORG }}" > /dev/null 2>&1
95
- }
96
-
97
- # Function to exit with message when deployment is not needed
98
- no_deployment() {
99
- local message=$1
100
- echo "SHOULD_DEPLOY=false" >> $GITHUB_OUTPUT
101
- echo "$message"
129
+ if ! cpln workload get "${{ env.APP_NAME }}" --org "${{ env.CPLN_ORG }}" > /dev/null 2>&1; then
130
+ echo "Review app ${{ env.APP_NAME }} does not exist"
102
131
exit 0
103
- }
104
-
105
- # Get default branch
106
- DEFAULT_BRANCH="refs/heads/$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')"
107
- echo "DEFAULT_BRANCH=$DEFAULT_BRANCH" >> $GITHUB_OUTPUT
108
-
109
- # Set staging app name if this is the default branch
110
- if [[ "${{ github.ref }}" == "$DEFAULT_BRANCH" ]]; then
111
- echo "APP_NAME=${{ env.STAGING_APP_NAME }}" >> $GITHUB_ENV
112
- echo "IS_STAGING=true" >> $GITHUB_ENV
113
- fi
114
-
115
- # Check if we should deploy
116
- if [[ "${{ github.ref }}" == "$DEFAULT_BRANCH" ]]; then
117
- echo "SHOULD_DEPLOY=true" >> $GITHUB_OUTPUT
118
- elif [[ "${{ github.event_name }}" == "issue_comment" &&
119
- "${{ github.event.issue.pull_request }}" == "true" &&
120
- "${{ github.event.comment.body }}" == "/deploy-review-app" ]]; then
121
- echo "SHOULD_DEPLOY=true" >> $GITHUB_OUTPUT
122
- elif [[ "${{ github.event_name }}" == "push" && "${{ steps.get-pr.outputs.has_pr }}" == "true" ]]; then
123
- if check_app_exists "${{ env.APP_NAME }}"; then
124
- echo "SHOULD_DEPLOY=true" >> $GITHUB_OUTPUT
125
- else
126
- no_deployment "No existing review app found for PR ${{ env.PR_NUMBER }}"
127
- fi
128
- else
129
- no_deployment "No deployment needed for this event"
130
132
fi
131
-
132
- # Set console link after APP_NAME is set
133
- echo "CONSOLE_LINK=[View in Control Plane Console](https://console.cpln.io/org/${{ env.CPLN_ORG }}/workload/${{ env.APP_NAME }})" >> $GITHUB_ENV
134
-
135
- - name : Set Workflow URL
136
- id : workflow-url
137
- uses : actions/github-script@v7
138
- with :
139
- script : |
140
- try {
141
- const jobs = await github.rest.actions.listJobsForWorkflowRun({
142
- owner: context.repo.owner,
143
- repo: context.repo.repo,
144
- run_id: context.runId
145
- });
146
-
147
- const currentJob = jobs.data.jobs.find(job => job.name === 'Process-Deployment');
148
- if (!currentJob) {
149
- console.log('Could not find Process-Deployment job, jobs found:', jobs.data.jobs.map(j => j.name));
150
- }
151
- const jobId = currentJob?.id;
152
-
153
- const workflowUrl = jobId
154
- ? `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/job/${jobId}`
155
- : `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
156
-
157
- core.exportVariable('WORKFLOW_URL', workflowUrl);
158
- console.log('Set WORKFLOW_URL to:', workflowUrl);
159
- } catch (error) {
160
- console.log('Error getting job details:', error);
161
- // Fallback to run URL
162
- const workflowUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
163
- core.exportVariable('WORKFLOW_URL', workflowUrl);
164
- console.log('Fallback: Set WORKFLOW_URL to:', workflowUrl);
165
- }
166
-
167
- - name : Create Initial Comment
168
- id : create-comment
169
- uses : actions/github-script@v7
170
- with :
171
- script : |
172
- const initialMessage = [
173
- '🚀 Deploying...',
174
- '',
175
- '📝 [View Deploy Logs](' + process.env.WORKFLOW_URL + ')',
176
- '',
177
- process.env.CONSOLE_LINK
178
- ].join('\n');
179
-
180
- const comment = await github.rest.issues.createComment({
181
- owner: context.repo.owner,
182
- repo: context.repo.repo,
183
- issue_number: process.env.PR_NUMBER,
184
- body: initialMessage
185
- });
186
-
187
- core.exportVariable('COMMENT_ID', comment.data.id);
188
- console.log('Created comment:', comment.data.id);
189
-
190
- - name : Update Status - Building
191
- if : env.IS_STAGING != 'true'
192
- uses : actions/github-script@v7
193
- with :
194
- script : |
195
- const buildingMessage = [
196
- '🏗️ Building...',
197
- '',
198
- '📝 [View Build Logs](' + process.env.WORKFLOW_URL + ')',
199
- '',
200
- process.env.CONSOLE_LINK
201
- ].join('\n');
202
-
203
- await github.rest.issues.updateComment({
204
- owner: context.repo.owner,
205
- repo: context.repo.repo,
206
- comment_id: process.env.COMMENT_ID,
207
- body: buildingMessage
208
- });
209
-
210
- - name : Checkout PR Branch
211
- if : env.IS_STAGING != 'true'
212
- run : git checkout ${{ steps.setup.outputs.PR_REF }}
133
+ echo "exists=true" >> $GITHUB_OUTPUT
213
134
214
135
- name : Build Docker Image
136
+ if : steps.check-app.outputs.exists == 'true' || github.event_name == 'issue_comment'
215
137
uses : ./.github/actions/build-docker-image
216
138
with :
217
139
app_name : ${{ env.APP_NAME }}
218
140
org : ${{ env.CPLN_ORG }}
219
- commit : ${{ steps.setup.outputs.PR_SHA }}
220
-
221
- - name : Update Status - Deploying
222
- if : env.IS_STAGING != 'true'
223
- uses : actions/github-script@v7
224
- with :
225
- script : |
226
- const deployingMessage = [
227
- '🚀 Deploying...',
228
- '',
229
- '📝 [View Deploy Logs](' + process.env.WORKFLOW_URL + ')',
230
- '',
231
- process.env.CONSOLE_LINK
232
- ].join('\n');
233
-
234
- await github.rest.issues.updateComment({
235
- owner: context.repo.owner,
236
- repo: context.repo.repo,
237
- comment_id: process.env.COMMENT_ID,
238
- body: deployingMessage
239
- });
141
+ commit : ${{ env.COMMIT_SHA }}
240
142
241
143
- name : Deploy to Control Plane
144
+ if : steps.check-app.outputs.exists == 'true' || github.event_name == 'issue_comment'
242
145
id : deploy
243
146
uses : ./.github/actions/deploy-to-control-plane
244
147
with :
245
148
app_name : ${{ env.APP_NAME }}
246
149
org : ${{ env.CPLN_ORG }}
247
150
github_token : ${{ secrets.GITHUB_TOKEN }}
248
- wait_timeout : ${{ vars.WAIT_TIMEOUT || 900 }}
249
-
250
- - name : Update Status - Success
251
- if : success() && env.IS_STAGING != 'true'
252
- uses : actions/github-script@v7
253
- with :
254
- script : |
255
- const successMessage = [
256
- '✅ Deployment successful!',
257
- '',
258
- '🌐 Review app is ready at: ${{ steps.deploy.outputs.REVIEW_APP_URL }}',
259
- '',
260
- '📝 [View App Logs](' + process.env.WORKFLOW_URL + ')',
261
- '',
262
- process.env.CONSOLE_LINK
263
- ].join('\n');
264
-
265
- await github.rest.issues.updateComment({
266
- owner: context.repo.owner,
267
- repo: context.repo.repo,
268
- comment_id: process.env.COMMENT_ID,
269
- body: successMessage
270
- });
271
-
272
- - name : Update Status - Failure
273
- if : failure() && env.IS_STAGING != 'true'
274
- uses : actions/github-script@v7
275
- with :
276
- script : |
277
- const failureMessage = [
278
- '❌ Deployment failed!',
279
- '',
280
- '📝 [View Deploy Logs](' + process.env.WORKFLOW_URL + ')',
281
- '',
282
- process.env.CONSOLE_LINK
283
- ].join('\n');
284
-
285
- await github.rest.issues.updateComment({
286
- owner: context.repo.owner,
287
- repo: context.repo.repo,
288
- comment_id: process.env.COMMENT_ID,
289
- body: failureMessage
290
- });
0 commit comments