Skip to content

build-deploy

build-deploy #1967

Workflow file for this run

name: build-deploy
on:
push:
branches:
- master
schedule:
- cron: '0 */6 * * *' # Deploy the website every 6 hours
jobs:
build-base-image:
name: Build Base Image
uses: ./.github/workflows/build-docker-image.yml
with:
dockerfile: ./infrastructure/docker/build/Dockerfile
image: davidbyoung/aphiria.com-build
image-sha-artifact-name: build-image-sha
secrets:
DOCKER_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }}
build-runtime-images:
name: Build Runtime Images
needs: build-base-image
strategy:
fail-fast: true
matrix:
include:
- dockerfile: ./infrastructure/docker/runtime/api/Dockerfile
image: davidbyoung/aphiria.com-api
image-sha-artifact-name: api-image-sha
- dockerfile: ./infrastructure/docker/runtime/web/Dockerfile
image: davidbyoung/aphiria.com-web
image-sha-artifact-name: web-image-sha
uses: ./.github/workflows/build-docker-image.yml
with:
dockerfile: ${{ matrix.dockerfile }}
image: ${{ matrix.image }}
image-sha-artifact-name: ${{ matrix.image-sha-artifact-name }}
secrets:
DOCKER_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }}
deploy:
runs-on: ubuntu-latest
name: Deploy
needs: build-runtime-images
environment: production
steps:
- name: Check Out Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download SHA Artifact
uses: actions/download-artifact@v4
with:
# Technically, an artifact for each image will be uploaded. We just choose one here, but all should have the same content.
name: api-image-sha
- name: Install Dependencies
run: |
chmod +x ./install.sh
./install.sh --install-terraform --install-helm --install-helmfile --install-doctl
- name: Terraform Infrastructure
run: |
# Configure and validate Terraform
terraform -chdir=./infrastructure/terraform init -backend-config="access_key=${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}" -backend-config="secret_key=${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}"
terraform -chdir=./infrastructure/terraform validate
# Plan and apply
terraform -chdir=./infrastructure/terraform plan -var="do_access_token=${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}" -var="do_spaces_access_key=${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}" -var="do_spaces_secret_key=${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}" -no-color -input=false
terraform -chdir=./infrastructure/terraform apply -var="do_access_token=${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}" -var="do_spaces_access_key=${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}" -var="do_spaces_secret_key=${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}" -no-color -input=false -auto-approve
- name: Configure Kubernetes Cluster
run: |
# Save the kubeconfig so that kubectl commands apply to the DigitalOcean cluster
doctl auth init --access-token ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
doctl kubernetes cluster kubeconfig save $(terraform -chdir=./infrastructure/terraform output -raw cluster_id)
# Install Helmfiles
helmfile -f ./infrastructure/kubernetes/base/helmfile.yml repos
helmfile -f ./infrastructure/kubernetes/base/helmfile.yml sync
# Write secrets to files so we can apply them
echo "${{ secrets.KUBERNETES_SECRETS }}" > ./infrastructure/kubernetes/environments/prod/core/secrets.yml
echo "${{ secrets.DIGITALOCEAN_SECRETS }}" > ./infrastructure/kubernetes/environments/prod/gateway-api/secrets.yml
# Update the DB migration job to use the latest Docker image
image_sha=$(cat image_sha.txt)
echo "Image SHA: $image_sha"
sed -i "s|davidbyoung/aphiria.com-api:latest|davidbyoung/aphiria.com-api:${image_sha}|g" ./infrastructure/kubernetes/base/database/jobs.yml
kubectl delete job db-migration --ignore-not-found
# Apply prod kustomization
kubectl apply -k ./infrastructure/kubernetes/environments/prod
# Use the latest Docker images in our pods
kubectl set image deployment/api php=davidbyoung/aphiria.com-api:${image_sha}
kubectl set image deployment/api copy-api-code=davidbyoung/aphiria.com-api:${image_sha}
kubectl set image deployment/web web=davidbyoung/aphiria.com-web:${image_sha}