@@ -44,59 +44,205 @@ runs:
4444 - name : Setup Environment
4545 uses : ./.github/actions/setup-environment
4646
47- - name : Get Commit SHA
48- id : get_sha
47+ - name : Set shared functions
48+ id : shared-functions
49+ uses : actions/github-script@v7
50+ with :
51+ script : |
52+ core.exportVariable('GET_CONSOLE_LINK', `
53+ function getConsoleLink(prNumber) {
54+ return ' [Control Plane Console for Review App with PR #' + prNumber + '](' +
55+ 'https://console.cpln.io/org/' + process.env.CPLN_ORG + '/workloads/' + process.env.APP_NAME + ')';
56+ }
57+ `);
58+
59+ - name : Initialize Deployment
60+ id : init-deployment
61+ uses : actions/github-script@v7
62+ with :
63+ script : |
64+ eval(process.env.GET_CONSOLE_LINK);
65+
66+ async function getWorkflowUrl(runId) {
67+ // Get the current job ID
68+ const jobs = await github.rest.actions.listJobsForWorkflowRun({
69+ owner: context.repo.owner,
70+ repo: context.repo.repo,
71+ run_id: runId
72+ });
73+
74+ const currentJob = jobs.data.jobs.find(job => job.status === 'in_progress');
75+ const jobId = currentJob?.id;
76+
77+ if (!jobId) {
78+ console.log('Warning: Could not find current job ID');
79+ return `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;
80+ }
81+
82+ return `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}/job/${jobId}`;
83+ }
84+
85+ // Create initial deployment comment
86+ const comment = await github.rest.issues.createComment({
87+ owner: context.repo.owner,
88+ repo: context.repo.repo,
89+ issue_number: process.env.PR_NUMBER,
90+ body: ' Initializing deployment...'
91+ });
92+
93+ // Create GitHub deployment
94+ const deployment = await github.rest.repos.createDeployment({
95+ owner: context.repo.owner,
96+ repo: context.repo.repo,
97+ ref: context.sha,
98+ environment: 'review',
99+ auto_merge: false,
100+ required_contexts: []
101+ });
102+
103+ const workflowUrl = await getWorkflowUrl(context.runId);
104+
105+ core.exportVariable('WORKFLOW_URL', workflowUrl);
106+ core.exportVariable('COMMENT_ID', comment.data.id);
107+ core.exportVariable('DEPLOYMENT_ID', deployment.data.id);
108+
109+ - name : Set commit hash
49110 shell : bash
50- run : ${{ github.action_path }}/scripts/get-commit-sha.sh
51- env :
52- GITHUB_TOKEN : ${{ inputs.github_token }}
53- PR_NUMBER : ${{ env.PR_NUMBER }}
111+ run : |
112+ FULL_COMMIT=$(git rev-parse HEAD)
113+ echo "COMMIT_HASH=${FULL_COMMIT:0:7}" >> $GITHUB_ENV
54114
55- - name : Deploy to Control Plane
56- id : deploy
115+ - name : Update Status - Setting Up
116+ uses : actions/github-script@v7
117+ with :
118+ script : |
119+ eval(process.env.GET_CONSOLE_LINK);
120+
121+ const setupMessage = [
122+ '🔧 Setting up Control Plane app...',
123+ '',
124+ ' [View Setup Logs](' + process.env.WORKFLOW_URL + ')',
125+ '',
126+ getConsoleLink(process.env.PR_NUMBER)
127+ ].join('\n');
128+
129+ await github.rest.issues.updateComment({
130+ owner: context.repo.owner,
131+ repo: context.repo.repo,
132+ comment_id: process.env.COMMENT_ID,
133+ body: setupMessage
134+ });
135+
136+ - name : Setup Control Plane App
57137 shell : bash
58138 run : |
59- echo "🚀 Deploying app for PR #${PR_NUMBER}..."
60-
61- # Create temp file for output
62- TEMP_OUTPUT=$(mktemp)
63- trap 'rm -f "${TEMP_OUTPUT}"' EXIT
64-
65- # Deploy the application and show output in real-time while capturing it
66- if ! cpflow deploy-image -a "${{ inputs.app_name }}" --run-release-phase --org "${{ inputs.org }}" 2>&1 | tee "${TEMP_OUTPUT}"; then
67- echo "❌ Deployment failed for PR #${PR_NUMBER}"
68- echo "Error output:"
69- cat "${TEMP_OUTPUT}"
70- exit 1
139+ echo "🔧 Checking if app exists..."
140+ if ! cpflow exists -a ${{ inputs.app_name }} ; then
141+ echo "📦 Setting up new Control Plane app..."
142+ cpflow setup-app -a ${{ inputs.app_name }}
71143 fi
72-
73- # Extract app URL from captured output
74- REVIEW_APP_URL=$(grep -oP 'https://rails-[^[:space:]]*\.cpln\.app(?=\s|$)' "${TEMP_OUTPUT}" | head -n1)
75- if [ -z "${REVIEW_APP_URL}" ]; then
76- echo "❌ Failed to get app URL from deployment output"
77- echo "Deployment output:"
78- cat "${TEMP_OUTPUT}"
79- exit 1
80- fi
81-
82- # Wait for all workloads to be ready
83- WAIT_TIMEOUT=${WAIT_TIMEOUT:-${{ inputs.wait_timeout }}}
84- echo "⏳ Waiting for all workloads to be ready (timeout: ${WAIT_TIMEOUT}s)..."
85-
86- # Use timeout command with ps:wait and show output in real-time
87- if ! timeout "${WAIT_TIMEOUT}" bash -c "cpflow ps:wait -a \"${{ inputs.app_name }}\"" 2>&1 | tee -a "${TEMP_OUTPUT}"; then
88- TIMEOUT_EXIT=$?
89- if [ ${TIMEOUT_EXIT} -eq 124 ]; then
90- echo "❌ Timed out waiting for workloads after ${WAIT_TIMEOUT} seconds"
91- else
92- echo "❌ Workloads did not become ready for PR #${PR_NUMBER} (exit code: ${TIMEOUT_EXIT})"
93- fi
94- echo "Full output:"
95- cat "${TEMP_OUTPUT}"
96- exit 1
97- fi
98-
99- echo "✅ Deployment successful for PR #${PR_NUMBER}"
100- echo "🌐 App URL: ${REVIEW_APP_URL}"
101- echo "review_app_url=${REVIEW_APP_URL}" >> $GITHUB_OUTPUT
102- echo "REVIEW_APP_URL=${REVIEW_APP_URL}" >> $GITHUB_ENV
144+
145+ - name : Update Status - Building
146+ uses : actions/github-script@v7
147+ with :
148+ script : |
149+ eval(process.env.GET_CONSOLE_LINK);
150+
151+ const buildingMessage = [
152+ '🏗️ Building Docker image for PR #' + process.env.PR_NUMBER + ', commit ' + process.env.COMMIT_HASH,
153+ '',
154+ ' [View Build Logs](' + process.env.WORKFLOW_URL + ')',
155+ '',
156+ getConsoleLink(process.env.PR_NUMBER)
157+ ].join('\n');
158+
159+ await github.rest.issues.updateComment({
160+ owner: context.repo.owner,
161+ repo: context.repo.repo,
162+ comment_id: process.env.COMMENT_ID,
163+ body: buildingMessage
164+ });
165+
166+ - name : Update Status - Deploying
167+ uses : actions/github-script@v7
168+ with :
169+ script : |
170+ eval(process.env.GET_CONSOLE_LINK);
171+
172+ const deployingMessage = [
173+ '🚀 Deploying to Control Plane...',
174+ '',
175+ '⏳ Waiting for deployment to be ready...',
176+ '',
177+ ' [View Deploy Logs](' + process.env.WORKFLOW_URL + ')',
178+ '',
179+ getConsoleLink(process.env.PR_NUMBER)
180+ ].join('\n');
181+
182+ await github.rest.issues.updateComment({
183+ owner: context.repo.owner,
184+ repo: context.repo.repo,
185+ comment_id: process.env.COMMENT_ID,
186+ body: deployingMessage
187+ });
188+
189+ - name : Deploy to Control Plane
190+ id : deploy
191+ shell : bash
192+ run : ${{ github.action_path }}/scripts/deploy.sh
193+ env :
194+ APP_NAME : ${{ inputs.app_name }}
195+ CPLN_ORG : ${{ inputs.org }}
196+ WAIT_TIMEOUT : ${{ inputs.wait_timeout }}
197+ 198+ - name : Update Status - Deployment Complete
199+ if : always()
200+ uses : actions/github-script@v7
201+ with :
202+ script : |
203+ eval(process.env.GET_CONSOLE_LINK);
204+
205+ const prNumber = process.env.PR_NUMBER;
206+ const appUrl = process.env.REVIEW_APP_URL;
207+ const workflowUrl = process.env.WORKFLOW_URL;
208+ const isSuccess = '${{ job.status }}' === 'success';
209+
210+ // Create GitHub deployment status
211+ const deploymentStatus = {
212+ owner: context.repo.owner,
213+ repo: context.repo.repo,
214+ deployment_id: process.env.DEPLOYMENT_ID,
215+ state: isSuccess ? 'success' : 'failure',
216+ environment_url: isSuccess ? appUrl : undefined,
217+ log_url: workflowUrl,
218+ environment: 'review'
219+ };
220+
221+ await github.rest.repos.createDeploymentStatus(deploymentStatus);
222+
223+ // Define messages based on deployment status
224+ const successMessage = [
225+ '✅ Deployment complete for PR #' + prNumber + ', commit ' + process.env.COMMIT_HASH,
226+ '',
227+ '🌐 [Review App for PR #' + prNumber + '](' + appUrl + ')',
228+ '',
229+ ' [View Completed Action Build and Deploy Logs](' + workflowUrl + ')',
230+ '',
231+ getConsoleLink(prNumber)
232+ ].join('\n');
233+
234+ const failureMessage = [
235+ '❌ Deployment failed for PR #' + prNumber + ', commit ' + process.env.COMMIT_HASH,
236+ '',
237+ ' [View Deployment Logs with Errors](' + workflowUrl + ')',
238+ '',
239+ getConsoleLink(prNumber)
240+ ].join('\n');
241+
242+ // Update the existing comment
243+ await github.rest.issues.updateComment({
244+ owner: context.repo.owner,
245+ repo: context.repo.repo,
246+ comment_id: process.env.COMMENT_ID,
247+ body: isSuccess ? successMessage : failureMessage
248+ });
0 commit comments