|
1 |
| -# Control Plane GitHub Action |
2 |
| - |
3 | 1 | name: Deploy Review App to Control Plane
|
4 | 2 |
|
5 |
| -# Controls when the workflow will run |
6 | 3 | on:
|
7 |
| - # Allows you to run this workflow manually from the Actions tab |
8 | 4 | workflow_dispatch:
|
9 |
| - |
10 |
| - # Uncomment these lines to trigger the workflow on pull request events |
11 |
| - # pull_request: |
12 |
| - # branches: |
13 |
| - # - master |
14 |
| - |
15 |
| - # deploy on comment "/deploy-review-app" |
| 5 | + pull_request: |
| 6 | + types: [opened, synchronize, reopened] |
| 7 | + branches: [master] |
16 | 8 | issue_comment:
|
17 |
| - types: [created, edited] |
| 9 | + types: [created] |
| 10 | + |
| 11 | +concurrency: |
| 12 | + group: review-app-${{ github.event.pull_request.number || github.event.issue.number }} |
| 13 | + cancel-in-progress: true |
18 | 14 |
|
19 |
| -# Convert the GitHub secret variables to environment variables for use by the Control Plane CLI |
20 | 15 | env:
|
21 | 16 | CPLN_ORG: ${{secrets.CPLN_ORG_STAGING}}
|
22 | 17 | CPLN_TOKEN: ${{secrets.CPLN_TOKEN_STAGING}}
|
23 |
| - # Uncomment this line to use the PR number from the pull requests trigger event (that trigger is commented) |
24 |
| - # PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} |
25 |
| - PR_NUMBER: ${{ github.event.issue.number }} |
| 18 | + PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} |
26 | 19 |
|
27 | 20 | jobs:
|
| 21 | + check-concurrent: |
| 22 | + runs-on: ubuntu-latest |
| 23 | + outputs: |
| 24 | + cancelled: ${{ steps.check.outputs.cancelled }} |
| 25 | + steps: |
| 26 | + - name: Check for concurrent deployment |
| 27 | + id: check |
| 28 | + run: | |
| 29 | + if [ "${{ github.run_attempt }}" != "1" ]; then |
| 30 | + echo "⚠️ Cancelling previous deployment due to new code push..." |
| 31 | + echo "cancelled=true" >> $GITHUB_OUTPUT |
| 32 | + else |
| 33 | + echo "cancelled=false" >> $GITHUB_OUTPUT |
| 34 | + fi |
| 35 | +
|
28 | 36 | deploy-to-control-plane-review:
|
29 |
| - if: ${{ github.event_name != 'issue_comment' || (github.event.comment.body == '/deploy-review-app' && github.event.issue.pull_request) }} |
| 37 | + needs: check-concurrent |
| 38 | + if: | |
| 39 | + needs.check-concurrent.outputs.cancelled != 'true' && |
| 40 | + (github.event_name == 'workflow_dispatch' || |
| 41 | + github.event_name == 'pull_request' || |
| 42 | + (github.event_name == 'issue_comment' && |
| 43 | + github.event.comment.body == '/deploy-review-app' && |
| 44 | + github.event.issue.pull_request)) |
30 | 45 | runs-on: ubuntu-latest
|
31 | 46 |
|
| 47 | + permissions: |
| 48 | + contents: read |
| 49 | + deployments: write |
| 50 | + pull-requests: write |
| 51 | + |
| 52 | + outputs: |
| 53 | + app_url: ${{ steps.deploy.outputs.app_url }} |
| 54 | + deployment_id: ${{ steps.create-deployment.outputs.result.deployment_id }} |
| 55 | + |
32 | 56 | steps:
|
| 57 | + - name: Notify deployment start |
| 58 | + uses: actions/github-script@v7 |
| 59 | + with: |
| 60 | + script: | |
| 61 | + const message = `🚀 Starting new deployment for commit: ${context.sha.substring(0, 7)} |
| 62 | + ${context.payload.commits ? `\nChanges: ${context.payload.commits[0].message}` : ''}`; |
| 63 | + |
| 64 | + await github.rest.issues.createComment({ |
| 65 | + issue_number: context.issue.number || context.payload.pull_request.number, |
| 66 | + owner: context.repo.owner, |
| 67 | + repo: context.repo.repo, |
| 68 | + body: message |
| 69 | + }); |
| 70 | +
|
| 71 | + - name: Create GitHub Deployment |
| 72 | + id: create-deployment |
| 73 | + uses: actions/github-script@v7 |
| 74 | + with: |
| 75 | + script: | |
| 76 | + const deployment = await github.rest.repos.createDeployment({ |
| 77 | + owner: context.repo.owner, |
| 78 | + repo: context.repo.repo, |
| 79 | + ref: context.sha, |
| 80 | + environment: 'review-app', |
| 81 | + auto_merge: false, |
| 82 | + required_contexts: [] |
| 83 | + }); |
| 84 | + return { deployment_id: deployment.data.id }; |
| 85 | +
|
33 | 86 | - name: Get PR HEAD Ref
|
34 | 87 | if: ${{ github.event_name == 'issue_comment' }}
|
35 | 88 | id: getRef
|
36 |
| - run: echo "PR_REF=$(gh pr view $PR_NUMBER --repo ${{ github.repository }} --json headRefName | jq -r '.headRefName')" >> $GITHUB_OUTPUT |
| 89 | + run: | |
| 90 | + echo "PR_REF=$(gh pr view $PR_NUMBER --repo ${{ github.repository }} --json headRefName | jq -r '.headRefName')" >> $GITHUB_OUTPUT |
37 | 91 | env:
|
38 | 92 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
39 | 93 |
|
40 |
| - - name: Checkout source code from Github |
| 94 | + - name: Checkout source code |
41 | 95 | uses: actions/checkout@v4
|
42 | 96 | with:
|
43 | 97 | fetch-depth: 0
|
44 | 98 | ref: ${{ steps.getRef.outputs.PR_REF || github.ref }}
|
45 | 99 |
|
46 |
| - - name: Add GitHub Comment |
47 |
| - if: ${{ github.event_name == 'issue_comment' }} |
| 100 | + - name: Update deployment status (in_progress) |
48 | 101 | uses: actions/github-script@v7
|
49 | 102 | with:
|
50 | 103 | script: |
|
51 |
| - github.rest.issues.createComment({ |
52 |
| - issue_number: context.issue.number, |
| 104 | + await github.rest.repos.createDeploymentStatus({ |
53 | 105 | owner: context.repo.owner,
|
54 | 106 | repo: context.repo.repo,
|
55 |
| - body: "We started working on your review-app deployment. You can track progress in the `Actions` Tab [here](https://github.com/shakacode/react-webpack-rails-tutorial/actions/workflows/deploy-to-control-plane-review.yml) on Github." |
56 |
| - }) |
| 107 | + deployment_id: ${{ steps.create-deployment.outputs.result.deployment_id }}, |
| 108 | + state: 'in_progress', |
| 109 | + description: 'Deployment is in progress' |
| 110 | + }); |
57 | 111 |
|
58 |
| - - name: Get PR number |
59 |
| - if: ${{ github.event_name != 'issue_comment' }} |
60 |
| - run: | |
61 |
| - echo "GITHUB_REPOSITORY: \"$GITHUB_REPOSITORY\"" |
62 |
| - if [ -z "$PR_NUMBER" ]; then |
63 |
| - echo "PR_NUMBER is not in the trigger event. Fetching PR number from open PRs." |
64 |
| - REF="${{ github.ref }}" |
65 |
| - REF=${REF#refs/heads/} # Remove 'refs/heads/' prefix |
66 |
| - echo "REF: \"$REF\"" |
67 |
| - API_RESPONSE=$(curl --location --request GET "https://github.com/api/repos/${GITHUB_REPOSITORY}/pulls?state=open" \ |
68 |
| - --header 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}') |
69 |
| - PR_NUMBER=$(echo "$API_RESPONSE" | jq '.[] | select(.head.ref=="'$REF'") | .number') |
70 |
| - fi |
71 |
| - echo "PR_NUMBER: $PR_NUMBER" |
72 |
| - if [ -z "$PR_NUMBER" ]; then |
73 |
| - echo "PR_NUMBER is not set. Aborting." |
74 |
| - exit 1 |
75 |
| - fi |
76 |
| - echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV |
77 |
| - - name: Get App Name |
| 112 | + - name: Configure app name |
| 113 | + id: app-config |
78 | 114 | run: |
|
79 |
| - echo "PR_NUMBER: ${{ env.PR_NUMBER }}" |
80 |
| - echo "APP_NAME=qa-react-webpack-rails-tutorial-pr-${{ env.PR_NUMBER }}" >> "$GITHUB_ENV" |
81 |
| - echo "App Name: ${{ env.APP_NAME }}" |
82 |
| - - uses: ./.github/actions/deploy-to-control-plane |
| 115 | + APP_NAME="qa-react-webpack-rails-tutorial-pr-${{ env.PR_NUMBER }}" |
| 116 | + echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV |
| 117 | + echo "app_name=$APP_NAME" >> $GITHUB_OUTPUT |
| 118 | +
|
| 119 | + - name: Deploy to Control Plane |
| 120 | + id: deploy |
| 121 | + uses: ./.github/actions/deploy-to-control-plane |
83 | 122 | with:
|
84 | 123 | app_name: ${{ env.APP_NAME }}
|
85 | 124 | org: ${{ env.CPLN_ORG }}
|
| 125 | + |
| 126 | + - name: Update deployment status (success) |
| 127 | + if: success() |
| 128 | + uses: actions/github-script@v7 |
| 129 | + with: |
| 130 | + script: | |
| 131 | + const message = `✅ Deployment successful! |
| 132 | + Environment: review-app |
| 133 | + Commit: ${context.sha.substring(0, 7)} |
| 134 | + URL: ${{ steps.deploy.outputs.app_url }}`; |
| 135 | + |
| 136 | + await github.rest.issues.createComment({ |
| 137 | + issue_number: context.issue.number || context.payload.pull_request.number, |
| 138 | + owner: context.repo.owner, |
| 139 | + repo: context.repo.repo, |
| 140 | + body: message |
| 141 | + }); |
| 142 | + |
| 143 | + await github.rest.repos.createDeploymentStatus({ |
| 144 | + owner: context.repo.owner, |
| 145 | + repo: context.repo.repo, |
| 146 | + deployment_id: ${{ steps.create-deployment.outputs.result.deployment_id }}, |
| 147 | + state: 'success', |
| 148 | + environment_url: '${{ steps.deploy.outputs.app_url }}', |
| 149 | + description: 'Deployment successful' |
| 150 | + }); |
| 151 | +
|
| 152 | + - name: Update deployment status (failure) |
| 153 | + if: failure() |
| 154 | + uses: actions/github-script@v7 |
| 155 | + with: |
| 156 | + script: | |
| 157 | + const message = `❌ Deployment failed |
| 158 | + Commit: ${context.sha.substring(0, 7)} |
| 159 | + Please check the [workflow logs](${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}) for details.`; |
| 160 | + |
| 161 | + await github.rest.issues.createComment({ |
| 162 | + issue_number: context.issue.number || context.payload.pull_request.number, |
| 163 | + owner: context.repo.owner, |
| 164 | + repo: context.repo.repo, |
| 165 | + body: message |
| 166 | + }); |
| 167 | + |
| 168 | + await github.rest.repos.createDeploymentStatus({ |
| 169 | + owner: context.repo.owner, |
| 170 | + repo: context.repo.repo, |
| 171 | + deployment_id: ${{ steps.create-deployment.outputs.result.deployment_id }}, |
| 172 | + state: 'failure', |
| 173 | + description: 'Deployment failed' |
| 174 | + }); |
0 commit comments