.github/workflows/deploy-ci.yml
name: Build and deploy CI
on:
workflow_dispatch:
push:
branches:
- main
jobs:
prepare:
runs-on: ubuntu-latest
if: github.ref_name == 'main'
outputs:
target_branch: ${{ steps.target_branch.outputs.target_branch }}
api_image_tag: ${{ steps.prepare.outputs.api_image_tag }}
admin_image_tag: ${{ steps.prepare.outputs.admin_image_tag }}
app_image_tag: ${{ steps.prepare.outputs.app_image_tag }}
antivirus_image_tag: ${{ steps.prepare.outputs.antivirus_image_tag }}
steps:
- name: Get target_branch
id: target_branch
run: |
echo "target_branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4
with:
ref: ${{ steps.target_branch.outputs.target_branch }}
fetch-depth: 0
- name: Prepare
id: prepare
run: |
api_image_tag=$(git log --max-count=1 --oneline -- api packages package-lock.json | cut -d " " -f 1)
echo "api_image_tag: $api_image_tag"
echo "api_image_tag=$api_image_tag" >> $GITHUB_OUTPUT
admin_image_tag=$(git log --max-count=1 --oneline -- admin packages package-lock.json | cut -d " " -f 1)
echo "admin_image_tag: $admin_image_tag"
echo "admin_image_tag=$admin_image_tag" >> $GITHUB_OUTPUT
app_image_tag=$(git log --max-count=1 --oneline -- app packages package-lock.json | cut -d " " -f 1)
echo "app_image_tag: $app_image_tag"
echo "app_image_tag=$app_image_tag" >> $GITHUB_OUTPUT
antivirus_image_tag=$(git log --max-count=1 --oneline -- antivirus package-lock.json | cut -d " " -f 1)
echo "antivirus_image_tag: $antivirus_image_tag"
echo "antivirus_image_tag=$antivirus_image_tag" >> $GITHUB_OUTPUT
run_tests_api:
needs: prepare
uses: ./.github/workflows/run-tests-api.yml
with:
branch_name: ${{ needs.prepare.outputs.target_branch }}
secrets: inherit
run_tests_front:
needs: prepare
uses: ./.github/workflows/run-tests-front.yml
with:
branch_name: ${{ needs.prepare.outputs.branch_name }}
secrets: inherit
run_tests_lib:
needs: prepare
uses: ./.github/workflows/run-tests-lib.yml
with:
branch_name: ${{ needs.prepare.outputs.branch_name }}
secrets: inherit
build:
needs: [prepare, run_tests_api, run_tests_front, run_tests_lib]
runs-on: ubuntu-latest
strategy:
matrix:
app:
[
{
name: api,
path: api,
tag: "${{needs.prepare.outputs.api_image_tag}}",
},
{
name: app,
path: app,
tag: "${{needs.prepare.outputs.app_image_tag}}",
},
{
name: admin,
path: admin,
tag: "${{needs.prepare.outputs.admin_image_tag}}",
},
{
name: antivirus,
path: devops/antivirus,
tag: "${{needs.prepare.outputs.antivirus_image_tag}}",
},
]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.target_branch }}
- name: Check if image exists
id: check
uses: ./.github/actions/check_docker_image_tag
with:
registry: ${{ secrets.SCW_CI_IMAGE_REGISTRY }}
image_name: ${{ matrix.app.name }}
image_tag: ${{ matrix.app.tag }}
secret_key: ${{ secrets.SCW_CI_DEPLOY_SECRET_KEY }}
- name: Docker Build & Publish
uses: ./.github/actions/build_docker_image
if: steps.check.outputs.tag_exists == 0
with:
username: nologin
password: ${{ secrets.SCW_CI_DEPLOY_SECRET_KEY }}
registry: ${{ secrets.SCW_CI_IMAGE_REGISTRY }}
image_name: ${{ matrix.app.name }}
dockerfile_path: ${{ matrix.app.path }}/Dockerfile
image_tag: ${{ matrix.app.tag }}
sentry_auth_token: ${{ secrets.SENTRY_AUTH_TOKEN }}
deploy:
runs-on: ubuntu-latest
needs: [prepare, build]
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
env:
SCW_ACCESS_KEY: ${{ secrets.SCW_CI_DEPLOY_ACCESS_KEY }}
SCW_SECRET_KEY: ${{ secrets.SCW_CI_DEPLOY_SECRET_KEY }}
PG_CONN_STR: ${{ secrets.SCW_CI_BACKEND_CONN_STR }}
PGUSER: ${{ secrets.SCW_CI_BACKEND_USER }}
PGPASSWORD: ${{ secrets.SCW_CI_BACKEND_PASSWORD }}
ci_directory: ./devops/terraform/environments/ci
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.target_branch }}
- uses: hashicorp/setup-terraform@v3
- name: Init terraform
working-directory: ${{ env.ci_directory }}
run: terraform init
- name: Validate terraform
working-directory: ${{ env.ci_directory }}
run: terraform validate -no-color
- name: Terraform plan
working-directory: ${{ env.ci_directory }}
# add -lock-timeout option until https://github.com/hashicorp/terraform/issues/33217 is fixed
run: |
terraform plan -no-color -input=false -lock-timeout=15m \
-var="api_image_tag=${{ needs.prepare.outputs.api_image_tag }}" \
-var="admin_image_tag=${{ needs.prepare.outputs.admin_image_tag }}" \
-var="app_image_tag=${{ needs.prepare.outputs.app_image_tag }}"
- name: Terraform auto-apply
working-directory: ${{ env.ci_directory }}
run: |
terraform apply -no-color -input=false -auto-approve -lock-timeout=15m \
-var="api_image_tag=${{ needs.prepare.outputs.api_image_tag }}" \
-var="admin_image_tag=${{ needs.prepare.outputs.admin_image_tag }}" \
-var="app_image_tag=${{ needs.prepare.outputs.app_image_tag }}"
- name: Healthchecks
shell: bash
working-directory: ${{ env.ci_directory }}
run: |
# Sleep because status can still be an error if the previous deployement failed
sleep 10s
failure=false
while read name
do
status=$(terraform output -raw ${name}_container_status)
echo $name $status
if [[ $status != "ready" ]]
then
echo "Container ${name} is on '$status' state" 1>&2
failure=true
fi
done <<< 'app
admin
api'
if $failure
then
exit 1
fi