Skip to content

Deploying to staging triggered by naanci #29

Deploying to staging triggered by naanci

Deploying to staging triggered by naanci #29

Workflow file for this run

name: Deploying to staging
run-name: Deploying to staging triggered by ${{ inputs.author }}
concurrency:
group: deploy-staging-pr-${{ inputs.prId }}
cancel-in-progress: true
on:
workflow_dispatch:
inputs:
prId:
description: "PR to deploy"
required: true
repository:
description: "The repository from which the slash command was dispatched"
required: true
comment-id:
description: "The comment-id of the slash command"
required: true
author:
description: "The author that triggered this actions"
required: true
permissions:
contents: write
issues: write
pull-requests: write
statuses: write
jobs:
getPRHead:
name: Get PR head SHA
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.pr-head.outputs.result }}
steps:
- name: Get PR head SHA
id: pr-head
uses: actions/github-script@v7
with:
result-encoding: string
script: |
const prId = ${{ inputs.prId }};
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: parseInt(prId, 10)
});
return pr.head.sha;
sendMessage:
name: Send deploying to staging message
runs-on: ubuntu-latest
needs: getPRHead
steps:
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const prId = ${{ inputs.prId }};
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const commitHash = '${{ needs.getPRHead.outputs.sha }}';
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: commitHash,
state: 'pending',
target_url: runUrl,
context: 'Deploy to staging',
description: 'Deployment to staging in progress...',
});
checkExistingImage:
name: Check if image already exists
runs-on: ubuntu-latest
needs: [getPRHead, sendMessage]
outputs:
image-exists: ${{ steps.check-image.outputs.exists }}
git-sha: ${{ steps.set-sha.outputs.sha }}
steps:
- name: Set SHA
id: set-sha
run: echo "sha=$(echo "${{ needs.getPRHead.outputs.sha }}" | cut -c1-7)" >> $GITHUB_OUTPUT
- name: Check if Docker image exists
id: check-image
run: |
SHA7=$(echo "${{ needs.getPRHead.outputs.sha }}" | cut -c1-7)
if docker manifest inspect tahminator/codebloom:staging-$SHA7 > /dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "Image staging-$SHA7 already exists"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "Image staging-$SHA7 does not exist"
fi
promoteExisting:
name: Promote existing image to staging-latest
runs-on: ubuntu-latest
needs: [getPRHead, checkExistingImage]
if: needs.checkExistingImage.outputs.image-exists == 'true'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ needs.getPRHead.outputs.sha }}
- name: Setup CI
uses: ./.github/composite/setup-ci
with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- name: Load secrets
uses: ./.github/composite/load-secrets
with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
UNLOAD_ENVIRONMENTS: ci
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: tahminator
password: ${{ env.DOCKER_HUB_PAT }}
- name: Promote existing image
run: |
SHA7=${{ needs.checkExistingImage.outputs.git-sha }}
docker pull tahminator/codebloom:staging-$SHA7
docker tag tahminator/codebloom:staging-$SHA7 tahminator/codebloom:staging-latest
docker push tahminator/codebloom:staging-latest
echo "Promoted staging-$SHA7 to staging-latest"
frontendPreTest:
name: Frontend Pre Test
runs-on: ubuntu-latest
needs: [getPRHead, checkExistingImage]
if: needs.checkExistingImage.outputs.image-exists == 'false'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ needs.getPRHead.outputs.sha }}
- name: Run workflow
uses: ./.github/composite/test/frontend-pre-test
with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
backendPreTest:
name: Backend Compile Test
runs-on: ubuntu-latest
needs: [getPRHead, checkExistingImage]
if: needs.checkExistingImage.outputs.image-exists == 'false'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ needs.getPRHead.outputs.sha }}
- name: Run workflow
uses: ./.github/composite/test/backend-pre-test
validateDBSchema:
name: Validate DB Schema on Staging DB
runs-on: ubuntu-latest
needs: [getPRHead, checkExistingImage, backendPreTest]
if: needs.checkExistingImage.outputs.image-exists == 'false'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ needs.getPRHead.outputs.sha }}
fetch-depth: 0
- name: Run workflow
uses: ./.github/composite/validate-db
with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
ENVIRONMENT: staging
SHA: ${{ needs.getPRHead.outputs.sha }}
buildImage:
name: Build Docker Image & Upload to Registry
runs-on: ubuntu-latest
needs:
[
getPRHead,
checkExistingImage,
validateDBSchema,
backendPreTest,
frontendPreTest,
]
if: needs.checkExistingImage.outputs.image-exists == 'false'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ needs.getPRHead.outputs.sha }}
- name: Run workflow
uses: ./.github/composite/build-image
with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
TAG_PREFIX: staging-
SERVER_PROFILES: stg
redeploy:
name: Redeploy on DigitalOcean
runs-on: ubuntu-latest
needs: [buildImage, promoteExisting, getPRHead]
if: always() && (needs.buildImage.result == 'success' || needs.promoteExisting.result == 'success')
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ needs.getPRHead.outputs.sha }}
fetch-depth: 0
- name: Run workflow
uses: ./.github/composite/redeploy
with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
ENVIRONMENT: staging
SHA: ${{ needs.getPRHead.outputs.sha }}
notifyStatus:
name: Notify on deployment status
runs-on: ubuntu-latest
needs:
[
getPRHead,
checkExistingImage,
sendMessage,
backendPreTest,
frontendPreTest,
validateDBSchema,
buildImage,
promoteExisting,
redeploy,
]
if: always()
steps:
- name: Comment on PR about deployment status
uses: actions/github-script@v7
with:
script: |
const prId = ${{ inputs.prId }};
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const commitHash = '${{ needs.getPRHead.outputs.sha }}';
const needsObj = ${{ toJSON(needs) }};
const jobNames = Object.keys(needsObj);
const failedJobs = jobNames.filter((name) => needsObj[name].result === 'failure');
const cancelledJobs = jobNames.filter((name) => needsObj[name].result === 'cancelled');
const successJobs = jobNames.filter((name) => needsObj[name].result === 'success');
let statusMessage;
let status = false;
if (failedJobs.length > 0 && cancelledJobs.length > 0) {
statusMessage = `**Staging deployment failed and was cancelled** for commit ${commitHash}`;
status = false;
} else if (failedJobs.length > 0) {
statusMessage = `**Staging deployment failed** for commit ${commitHash}`;
status = false;
} else if (cancelledJobs.length > 0) {
statusMessage = `**Staging deployment was cancelled** for commit ${commitHash}`;
status = false;
} else {
statusMessage = `**Staging deployment succeeded** for commit ${commitHash}`;
status = true;
}
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: commitHash,
state: status ? 'success' : 'failure',
target_url: runUrl,
context: "Deploy to staging",
description: status ? "Staging deployment succeeded" : "Staging deployment failed",
});