|
1 | 1 | # Control Plane GitHub Action
|
2 | 2 |
|
3 |
| -name: Deploy-To-Control-Plane |
4 |
| -description: 'Deploys both to staging and to review apps' |
| 3 | +name: Deploy to Control Plane |
| 4 | +description: 'Deploys an application to Control Plane' |
5 | 5 |
|
6 | 6 | inputs:
|
7 | 7 | app_name:
|
8 |
| - description: 'The name of the app to deploy' |
| 8 | + description: 'Name of the application' |
9 | 9 | required: true
|
10 |
| - default: |
11 | 10 | org:
|
12 |
| - description: 'The org of the app to deploy' |
| 11 | + description: 'Organization name' |
13 | 12 | required: true
|
14 |
| - default: |
| 13 | + github_token: |
| 14 | + description: 'GitHub token' |
| 15 | + required: true |
| 16 | + wait_timeout: |
| 17 | + description: 'Timeout in seconds for waiting for workloads to be ready' |
| 18 | + required: false |
| 19 | + default: '900' |
| 20 | + |
| 21 | +outputs: |
| 22 | + review_app_url: |
| 23 | + description: 'URL of the deployed application' |
| 24 | + value: ${{ steps.deploy.outputs.review_app_url }} |
15 | 25 |
|
16 | 26 | runs:
|
17 |
| - using: 'composite' |
| 27 | + using: "composite" |
18 | 28 | steps:
|
19 | 29 | - name: Setup Environment
|
20 | 30 | uses: ./.github/actions/setup-environment
|
21 | 31 |
|
22 |
| - - name: Set Short SHA |
23 |
| - id: vars |
| 32 | + - name: Get Commit SHA |
| 33 | + id: get_sha |
24 | 34 | shell: bash
|
25 |
| - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" |
26 |
| - |
27 |
| - # Caching step |
28 |
| - - uses: actions/cache@v2 |
29 |
| - with: |
30 |
| - path: /tmp/.docker-cache |
31 |
| - key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile', '**/package.json', '**/yarn.lock') }}-${{ github.sha }} |
32 |
| - restore-keys: | |
33 |
| - ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile', '**/package.json', '**/yarn.lock') }} |
34 |
| - ${{ runner.os }}-docker- |
| 35 | + run: ${{ github.action_path }}/scripts/get-commit-sha.sh |
| 36 | + env: |
| 37 | + GITHUB_TOKEN: ${{ inputs.github_token }} |
| 38 | + PR_NUMBER: ${{ env.PR_NUMBER }} |
35 | 39 |
|
36 |
| - - name: cpflow setup-app |
37 |
| - shell: bash |
38 |
| - run: | |
39 |
| - if ! cpflow exists -a ${{ inputs.app_name }} ; then |
40 |
| - cpflow setup-app -a ${{ inputs.app_name }} |
41 |
| - fi |
42 |
| - # Provision all infrastructure on Control Plane. |
43 |
| - # app react-webpack-rails-tutorial will be created per definition in .controlplane/controlplane.yml |
44 |
| - - name: cpflow build-image |
45 |
| - shell: bash |
46 |
| - run: | |
47 |
| - cpln image docker-login |
48 |
| - # Use BUILDKIT_PROGRESS=plain to get more verbose logging of the build |
49 |
| - # BUILDKIT_PROGRESS=plain cpflow build-image -a ${{ inputs.app_name }} --commit ${{steps.vars.outputs.sha_short}} --org ${{inputs.org}} |
50 |
| - cpflow build-image -a ${{ inputs.app_name }} --commit ${{steps.vars.outputs.sha_short}} --org ${{inputs.org}} |
51 |
| - # --cache /tmp/.docker-cache |
52 | 40 | - name: Deploy to Control Plane
|
| 41 | + id: deploy |
53 | 42 | shell: bash
|
54 | 43 | run: |
|
55 |
| - echo "Deploying to Control Plane" |
56 |
| - cpflow deploy-image -a ${{ inputs.app_name }} --run-release-phase --org ${{inputs.org}} --verbose |
| 44 | + echo "🚀 Deploying app for PR #${PR_NUMBER}..." |
| 45 | + |
| 46 | + # Create temp file for output |
| 47 | + TEMP_OUTPUT=$(mktemp) |
| 48 | + trap 'rm -f "${TEMP_OUTPUT}"' EXIT |
| 49 | + |
| 50 | + # Deploy the application and show output in real-time while capturing it |
| 51 | + if ! cpflow deploy-image -a "${{ inputs.app_name }}" --run-release-phase --org "${{ inputs.org }}" 2>&1 | tee "${TEMP_OUTPUT}"; then |
| 52 | + echo "❌ Deployment failed for PR #${PR_NUMBER}" |
| 53 | + echo "Error output:" |
| 54 | + cat "${TEMP_OUTPUT}" |
| 55 | + exit 1 |
| 56 | + fi |
| 57 | + |
| 58 | + # Extract app URL from captured output |
| 59 | + REVIEW_APP_URL=$(grep -oP 'https://rails-[^[:space:]]*\.cpln\.app(?=\s|$)' "${TEMP_OUTPUT}" | head -n1) |
| 60 | + if [ -z "${REVIEW_APP_URL}" ]; then |
| 61 | + echo "❌ Failed to get app URL from deployment output" |
| 62 | + echo "Deployment output:" |
| 63 | + cat "${TEMP_OUTPUT}" |
| 64 | + exit 1 |
| 65 | + fi |
| 66 | + |
| 67 | + # Wait for all workloads to be ready |
| 68 | + WAIT_TIMEOUT=${WAIT_TIMEOUT:-${{ inputs.wait_timeout }}} |
| 69 | + if ! [[ "${WAIT_TIMEOUT}" =~ ^[0-9]+$ ]]; then |
| 70 | + echo "❌ Invalid timeout value: ${WAIT_TIMEOUT}" |
| 71 | + exit 1 |
| 72 | + fi |
| 73 | + echo "⏳ Waiting for all workloads to be ready (timeout: ${WAIT_TIMEOUT}s)" |
| 74 | + |
| 75 | + # Use timeout command with ps:wait and show output in real-time |
| 76 | + if ! timeout "${WAIT_TIMEOUT}" bash -c "cpflow ps:wait -a \"${{ inputs.app_name }}\"" 2>&1 | tee -a "${TEMP_OUTPUT}"; then |
| 77 | + TIMEOUT_EXIT=$? |
| 78 | + if [ ${TIMEOUT_EXIT} -eq 124 ]; then |
| 79 | + echo "❌ Timed out waiting for workloads after ${WAIT_TIMEOUT} seconds" |
| 80 | + else |
| 81 | + echo "❌ Workloads did not become ready for PR #${PR_NUMBER} (exit code: ${TIMEOUT_EXIT})" |
| 82 | + fi |
| 83 | + echo "Full output:" |
| 84 | + cat "${TEMP_OUTPUT}" |
| 85 | + exit 1 |
| 86 | + fi |
| 87 | + |
| 88 | + echo "✅ Deployment successful for PR #${PR_NUMBER}" |
| 89 | + echo "🌐 App URL: ${REVIEW_APP_URL}" |
| 90 | + echo "review_app_url=${REVIEW_APP_URL}" >> $GITHUB_OUTPUT |
| 91 | + echo "REVIEW_APP_URL=${REVIEW_APP_URL}" >> $GITHUB_ENV |
0 commit comments