@@ -19,15 +19,52 @@ concurrency:
1919 cancel-in-progress : true
2020
2121jobs :
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 :
2563 if : |
2664 (github.event_name == 'issue_comment' &&
2765 github.event.issue.pull_request &&
2866 github.event.comment.body == '/deploy-review-app') ||
29- github.event_name == 'push' ||
30- github.event_name == 'workflow_dispatch'
67+ github.event_name == 'push'
3168 runs-on : ubuntu-latest
3269 permissions :
3370 contents : read
3875 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
3976 CPLN_TOKEN : ${{ secrets.CPLN_TOKEN_STAGING }}
4077 CPLN_ORG : ${{ vars.CPLN_ORG_STAGING }}
41- STAGING_APP_NAME : ${{ vars.STAGING_APP_NAME }}
4278 REVIEW_APP_PREFIX : ${{ vars.REVIEW_APP_PREFIX }}
43-
79+
4480 steps :
4581 - uses : actions/checkout@v4
4682 with :
5490
5591 # Required actions variables
5692 : "${CPLN_ORG:?Required variable CPLN_ORG_STAGING not set}"
57- : "${STAGING_APP_NAME:?Required variable STAGING_APP_NAME not set}"
5893 : "${REVIEW_APP_PREFIX:?Required variable REVIEW_APP_PREFIX not set}"
59-
60- echo "All required secrets and variables are set"
6194
6295 - name : Setup Environment
6396 uses : ./.github/actions/setup-environment
@@ -69,10 +102,12 @@ jobs:
69102 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
70103 run : |
71104 # 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')
73107 if [ -n "$PR_NUMBER" ]; then
74108 echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
75109 echo "APP_NAME=${{ env.REVIEW_APP_PREFIX }}-pr-$PR_NUMBER" >> $GITHUB_ENV
110+ echo "COMMIT_SHA=$(echo "$PR_DATA" | jq -r '.headRefOid')" >> $GITHUB_ENV
76111 echo "has_pr=true" >> $GITHUB_OUTPUT
77112 else
78113 echo "No PR found for this branch"
@@ -82,209 +117,34 @@ jobs:
82117 - name : Set PR Number for Comment Event
83118 if : github.event_name == 'issue_comment'
84119 run : |
120+ # Get PR data including the commit SHA
121+ PR_DATA=$(gh pr view ${{ github.event.issue.number }} --json headRefOid --jq '.')
85122 echo "PR_NUMBER=${{ github.event.issue.number }}" >> $GITHUB_ENV
86123 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
87125
88- - name : Setup Deployment Configuration
89- id : setup
126+ - name : Check Review App Exists
127+ id : check-app
90128 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"
102131 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"
130132 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
213134
214135 - name : Build Docker Image
136+ if : steps.check-app.outputs.exists == 'true' || github.event_name == 'issue_comment'
215137 uses : ./.github/actions/build-docker-image
216138 with :
217139 app_name : ${{ env.APP_NAME }}
218140 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 }}
240142
241143 - name : Deploy to Control Plane
144+ if : steps.check-app.outputs.exists == 'true' || github.event_name == 'issue_comment'
242145 id : deploy
243146 uses : ./.github/actions/deploy-to-control-plane
244147 with :
245148 app_name : ${{ env.APP_NAME }}
246149 org : ${{ env.CPLN_ORG }}
247150 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