Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 098b886

Browse files
Building on working for review apps (#620)
WIP for updating github actions
1 parent 151c527 commit 098b886

File tree

9 files changed

+264
-311
lines changed

9 files changed

+264
-311
lines changed

‎.controlplane/controlplane.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ aliases:
3838
release_script: release_script.sh
3939

4040
apps:
41-
react-webpack-rails-tutorial:
41+
react-webpack-rails-tutorial-production:
4242
# Simulate Production Version
4343
<<: *common
4444
# Don't allow overriding the org and app by ENV vars b/c production is sensitive!

‎.github/actions/deploy-to-control-plane/action.yml

Lines changed: 51 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -44,205 +44,59 @@ runs:
4444
- name: Setup Environment
4545
uses: ./.github/actions/setup-environment
4646

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
110-
shell: bash
111-
run: |
112-
FULL_COMMIT=$(git rev-parse HEAD)
113-
echo "COMMIT_HASH=${FULL_COMMIT:0:7}" >> $GITHUB_ENV
114-
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
47+
- name: Get Commit SHA
48+
id: get_sha
13749
shell: bash
138-
run: |
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 }}
143-
fi
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-
});
50+
run: ${{ github.action_path }}/scripts/get-commit-sha.sh
51+
env:
52+
GITHUB_TOKEN: ${{ inputs.github_token }}
53+
PR_NUMBER: ${{ env.PR_NUMBER }}
18854

18955
- name: Deploy to Control Plane
19056
id: deploy
19157
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-
});
58+
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
71+
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

‎.github/actions/setup-environment/action.yml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
name: 'Setup Environment'
44
description: 'Sets up Ruby, installs Control Plane CLI, cpflow gem, and sets up the default profile'
55

6+
inputs:
7+
token:
8+
description: 'Control Plane token'
9+
required: true
10+
org:
11+
description: 'Control Plane organization'
12+
required: true
13+
614
runs:
715
using: 'composite'
816
steps:
@@ -22,19 +30,22 @@ runs:
2230
- name: Setup Control Plane Profile
2331
shell: bash
2432
run: |
25-
if [ -z "$CPLN_TOKEN" ]; then
26-
echo " Error: CPLN_TOKEN environment variable is not set"
33+
TOKEN="${{ inputs.token }}"
34+
ORG="${{ inputs.org }}"
35+
36+
if [ -z "$TOKEN" ]; then
37+
echo " Error: Control Plane token not provided"
2738
exit 1
2839
fi
2940
30-
if [ -z "$CPLN_ORG" ]; then
31-
echo " Error: CPLN_ORG environment variable is not set"
41+
if [ -z "$ORG" ]; then
42+
echo " Error: Control Plane organization not provided"
3243
exit 1
3344
fi
3445
3546
echo "Setting up Control Plane profile..."
36-
echo "Organization: $CPLN_ORG"
37-
cpln profile update default --org "$CPLN_ORG" --token "$CPLN_TOKEN"
47+
echo "Organization: $ORG"
48+
cpln profile update default --org "$ORG" --token "$TOKEN"
3849
3950
echo "Setting up Docker login for Control Plane registry..."
40-
cpln image docker-login --org "$CPLN_ORG"
51+
cpln image docker-login --org "$ORG"

‎.github/workflows/delete-review-app.yml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ permissions:
1313
issues: write
1414

1515
env:
16-
CPLN_ORG: ${{ secrets.CPLN_ORG }}
17-
CPLN_TOKEN: ${{ secrets.CPLN_TOKEN }}
16+
CPLN_ORG: ${{ vars.CPLN_ORG_STAGING }}
17+
CPLN_TOKEN: ${{ secrets.CPLN_TOKEN_STAGING }}
1818
APP_NAME: qa-react-webpack-rails-tutorial-pr-${{ github.event.pull_request.number || github.event.issue.number }}
1919
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
2020

@@ -29,6 +29,18 @@ jobs:
2929
runs-on: ubuntu-latest
3030

3131
steps:
32+
- name: Get PR number
33+
id: pr
34+
uses: actions/github-script@v7
35+
with:
36+
script: |
37+
const prNumber = context.payload.issue.number;
38+
core.setOutput('pr_number', prNumber);
39+
core.exportVariable('PR_NUMBER', prNumber);
40+
41+
- name: Set App Name
42+
run: echo "APP_NAME=qa-react-webpack-rails-tutorial-pr-${{ env.PR_NUMBER }}" >> $GITHUB_ENV
43+
3244
- uses: actions/checkout@v4
3345

3446
- name: Validate Required Secrets
@@ -46,7 +58,10 @@ jobs:
4658
fi
4759
4860
- name: Setup Environment
49-
uses: ./.github/actions/setup-environment
61+
uses: ./.github/actions/setup-environment@justin808-working-for-deploys
62+
with:
63+
org: ${{ env.CPLN_ORG }}
64+
token: ${{ env.CPLN_TOKEN }}
5065

5166
- name: Set shared functions
5267
id: shared-functions
@@ -105,23 +120,26 @@ jobs:
105120
issue_number: process.env.PR_NUMBER,
106121
owner: context.repo.owner,
107122
repo: context.repo.repo,
123+
body: '🗑️ Starting app deletion...'
108124
body: [
109125
message,
110126
'',
111-
' [View Delete Logs](' + process.env.WORKFLOW_URL + ')',
127+
' 🗑️ [View Delete Logs](' + process.env.WORKFLOW_URL + ')',
112128
'',
113129
getConsoleLink(process.env.PR_NUMBER)
114130
].join('\n')
115131
});
116132
return { commentId: comment.data.id };
117133
118134
- name: Delete Review App
119-
uses: ./.github/actions/delete-control-plane-app
135+
uses: ./.github/actions/delete-control-plane-app@justin808-working-for-deploys
120136
with:
121137
app_name: ${{ env.APP_NAME }}
122138
org: ${{ env.CPLN_ORG }}
123139
github_token: ${{ secrets.GITHUB_TOKEN }}
124140
env:
141+
APP_NAME: ${{ env.APP_NAME }}
142+
CPLN_ORG: ${{ secrets.CPLN_ORG }}
125143
CPLN_TOKEN: ${{ secrets.CPLN_TOKEN }}
126144

127145
- name: Update Delete Status
@@ -133,6 +151,7 @@ jobs:
133151
134152
const success = '${{ job.status }}' === 'success';
135153
const prNumber = process.env.PR_NUMBER;
154+
const cpConsoleUrl = `https://console.cpln.io/org/${process.env.CPLN_ORG}/workloads/${process.env.APP_NAME}`;
136155
137156
const successMessage = [
138157
'✅ Review app for PR #' + prNumber + ' was successfully deleted',

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /