Skip to content

Improvements to deployments #200

Improvements to deployments

Improvements to deployments #200

name: Deploy Review or Staging App
on:
pull_request:
types: [opened, synchronize, reopened]
issue_comment:
types: [created]
# Use concurrency to cancel in-progress runs
concurrency:
group: deploy-${{ github.event.pull_request.number || github.event.issue.number }}
cancel-in-progress: true
env:
APP_NAME: qa-react-webpack-rails-tutorial-pr-${{ github.event.pull_request.number || github.event.issue.number }}
CPLN_ORG: ${{ secrets.CPLN_ORG_STAGING }}
CPLN_TOKEN: ${{ secrets.CPLN_TOKEN_STAGING }}
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
jobs:
deploy:
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' &&
github.event.comment.body == '/deploy-review-app' &&
github.event.issue.pull_request)
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
pull-requests: write
issues: write
steps:
- name: Get PR HEAD Ref
if: ${{ github.event_name == 'issue_comment' }}
id: getRef
run: |
echo "PR_REF=$(gh pr view $PR_NUMBER --repo ${{ github.repository }} --json headRefName | jq -r '.headRefName')" >> $GITHUB_OUTPUT
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ steps.getRef.outputs.PR_REF || github.ref }}
- name: Setup Environment
uses: ./.github/actions/setup-environment
- name: Initialize Deployment
id: init-deployment
uses: actions/github-script@v7
with:
script: |
// Create GitHub deployment
const deployment = await github.rest.repos.createDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
environment: 'review-app',
auto_merge: false,
required_contexts: []
});
const runUrl = `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/job/${process.env.GITHUB_JOB}?pr=${context.issue.number || context.payload.pull_request.number}`;
// Create initial comment
const comment = await github.rest.issues.createComment({
issue_number: context.issue.number || context.payload.pull_request.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🚀 Starting deployment for ${context.sha.substring(0, 7)}\nDeployment ID: ${deployment.data.id}\nGitHub Actions Run: ${runUrl}`
});
// Set deployment status to in_progress
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.data.id,
state: 'in_progress',
description: 'Deployment is in progress'
});
return {
deploymentId: deployment.data.id,
commentId: comment.data.id
};
- name: Setup cpflow app
run: |
if ! cpflow exists -a ${{ env.APP_NAME }} ; then
cpflow setup-app -a ${{ env.APP_NAME }}
fi
- name: Deploy to Control Plane
id: deploy
uses: ./.github/actions/deploy-to-control-plane
env:
CPLN_TOKEN: ${{ secrets.CPLN_TOKEN_STAGING }}
CPLN_ORG: ${{ secrets.CPLN_ORG_STAGING }}
with:
app_name: ${{ env.APP_NAME }}
org: ${{ env.CPLN_ORG }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Update Status
if: always()
uses: actions/github-script@v7
with:
script: |
const isSuccess = '${{ job.status }}' === 'success';
const deploymentId = ${{ fromJSON(steps.init-deployment.outputs.result).deploymentId }};
const commentId = ${{ fromJSON(steps.init-deployment.outputs.result).commentId }};
const railsUrl = '${{ steps.deploy.outputs.rails_url }}';
// Update deployment status
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deploymentId,
state: isSuccess ? 'success' : 'failure',
...(isSuccess && { environment_url: railsUrl }),
description: isSuccess ? '✅ Deployment successful' : '❌ Deployment failed'
});
// Update comment
const message = isSuccess
? `✅ Deployment successful!\n\n🚀 Rails app: ${railsUrl}\n📊 Status: ${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`
: `❌ Deployment failed\n\nCommit: ${context.sha.substring(0, 7)}\nWorkflow Status: ${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: commentId,
body: message
});