Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 65 additions & 22 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@ jobs:
if: startsWith(github.ref, 'refs/heads/deploy/')
outputs:
skip_build: ${{ steps.retag.outputs.skip_build }}
permissions:
id-token: write
contents: read
container: docker:stable-git
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials for ECR
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.ECR_IAM_ROLE }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
uses: aws-actions/amazon-ecr-login@v2
- name: Retag images with Skopeo
id: retag
run: |
Expand All @@ -56,7 +61,6 @@ jobs:
echo "skip_build=false" >> $GITHUB_OUTPUT
fi


# This job heavily relies on Docker layer caching to make it as fast as possible
# It builds the app-test stage first, and tests it,
# and only after that builds the rest of the stuff and pushes it to ECR
Expand All @@ -65,32 +69,44 @@ jobs:
# builds the image if the previous job didn't fail and didn't indicate
# that this one should be skipped
if: ${{ !failure() && (needs.retag-images.outputs.skip_build!='true')}}
needs: [ retag-images ]
needs: [retag-images]
permissions:
id-token: write
contents: read
container: docker:stable-git
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
with:
version: v0.6.3
driver-opts: image=moby/buildkit:v0.11.5
driver-opts: image=moby/buildkit:v0.26.3
- name: configure AWS for s3 Docker cache
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.REGISTRY_IAM_ROLE }}
role-session-name: s3
aws-region: ${{ env.AWS_REGION }}
- name: Set dynamic env vars
run: |
docker version
SHORT_COMMIT=$(echo $GITHUB_SHA | cut -c -8)
echo "VERSION=${SHORT_COMMIT}" >> $GITHUB_ENV
echo "DATABASE_PASSWORD=$( head -c 24 /dev/urandom | xxd -p | tr -d '\n ')" >> $GITHUB_ENV
echo "ENVIRONMENT=$(basename $GITHUB_REF)" >> $GITHUB_ENV
echo "CACHE=type=s3,region=${{ env.AWS_REGION }},bucket=${{ secrets.REGISTRY_BUCKET_NAME }}" >> $GITHUB_ENV
- name: Build test containers
uses: docker/bake-action@v5.11.0
uses: docker/bake-action@v6
env:
CACHE: type=s3,region=${{ env.AWS_REGION }},bucket=${{ secrets.REGISTRY_BUCKET_NAME }},access_key_id=${{ secrets.REGISTRY_AWS_ACCESS_KEY_ID }},secret_access_key=${{ secrets.REGISTRY_AWS_SECRET_ACCESS_KEY }}
CACHE: ${{ env.CACHE }}
DOCKER_BUILD_RECORD_UPLOAD: "false"
with:
source: .
files: docker-bake.hcl
targets: app-test
load: true
provenance: false
- name: Test app
run: |
# there's some limitation on the hostname length
Expand Down Expand Up @@ -124,41 +140,68 @@ jobs:
${{ env.PROJECT }}/app-test:${{ env.VERSION }} \
./manage.py makemigrations --check --dry-run

# Configure ECR role and login (token stored in Docker config)
- name: Configure AWS credentials for ECR
if: startsWith(github.ref, 'refs/heads/deploy/')
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.ECR_IAM_ROLE }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
if: startsWith(github.ref, 'refs/heads/deploy/')
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
uses: aws-actions/amazon-ecr-login@v2
# Reconfigure S3 cache role for Docker build (ECR push uses token from login step)
- name: configure AWS for s3 Docker cache
if: startsWith(github.ref, 'refs/heads/deploy/')
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.REGISTRY_IAM_ROLE }}
role-session-name: s3
aws-region: ${{ env.AWS_REGION }}
- name: Update CACHE env var for deploy build
if: startsWith(github.ref, 'refs/heads/deploy/')
run: |
echo "CACHE=type=s3,region=${{ env.AWS_REGION }},bucket=${{ secrets.REGISTRY_BUCKET_NAME }}" >> $GITHUB_ENV
- name: Build all other app parts and push to ECR
if: startsWith(github.ref, 'refs/heads/deploy/')
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
CACHE: type=s3,region=${{ env.AWS_REGION }},bucket=${{ secrets.REGISTRY_BUCKET_NAME }},access_key_id=${{ secrets.REGISTRY_AWS_ACCESS_KEY_ID }},secret_access_key=${{ secrets.REGISTRY_AWS_SECRET_ACCESS_KEY }}
uses: docker/[email protected]
CACHE: ${{ env.CACHE }}
DOCKER_BUILD_RECORD_UPLOAD: "false"
uses: docker/bake-action@v6
with:
source: .
files: docker-bake.hcl
targets: default
# makes it push to the registry
push: true
provenance: false

deploy:
needs: [ build-and-test, retag-images ]
needs: [build-and-test, retag-images]
if: startsWith(github.ref, 'refs/heads/deploy/') && !failure()
permissions:
id-token: write
contents: read
container: docker:stable-git
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
# TODO: Update deploy-user module to support OIDC role creation
# For now, using access keys (created by deploy-user module)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Download ecs-tool
run: |
wget -O ecs-tool.tar.gz https://github.com/springload/ecs-tool/releases/download/v1.9.9-beta/ecs-tool_1.9.9-beta_linux_amd64.tar.gz && tar -C /usr/bin -xvf ecs-tool.tar.gz ecs-tool
wget -O ecs-tool.tar.gz https://github.com/springload/ecs-tool/releases/download/v1.9.9-beta/ecs-tool_1.9.9-beta_linux_amd64.tar.gz && tar -C /usr/bin -xvf ecs-tool.tar.gz ecs-tool

- name: Deploy app
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
EJSON_PRIVATE: ${{ secrets.EJSON_PRIVATE }}
run: |-
set -eu
Expand Down
22 changes: 12 additions & 10 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// this is registry used for caching purposes only
variable "CACHE_REGISTRY" { default = "" }
// this is cache definition used for caching purposes only
variable "CACHE" { default = "" }
// this is remote registry to push to
variable "REGISTRY" { default = "" }
variable "ENVIRONMENT" { default = "preview" }
Expand All @@ -14,15 +16,15 @@ group "default" {
target "base" {
dockerfile = "docker/application/Dockerfile"
target = "base"
cache-from = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/base:${VERSION}", "type=registry,ref=${CACHE_REGISTRY}/base:cache"] : []
cache-to = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/base:cache,mode=max"] : []
cache-from = notequal("", CACHE) ? ["${CACHE},name=base"] : []
cache-to = notequal("", CACHE) ? ["${CACHE},mode=max,name=base"] : []
}

target "app" {
dockerfile = "docker/application/Dockerfile"
target = "app"
cache-from = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/app:${VERSION}", "type=registry,ref=${CACHE_REGISTRY}/app:cache"] : []
cache-to = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/app:cache,mode=max"] : []
cache-from = notequal("", CACHE) ? ["${CACHE},name=app"] : []
cache-to = notequal("", CACHE) ? ["${CACHE},mode=max,name=app"] : []

args = {
VERSION : VERSION,
Expand All @@ -38,8 +40,8 @@ target "app" {
target "app-test" {
dockerfile = "docker/application/Dockerfile"
target = "app-test"
cache-from = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/app-test:${VERSION}", "type=registry,ref=${CACHE_REGISTRY}/app-test:cache"] : []
cache-to = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/app-test:cache,mode=max"] : []
cache-from = notequal("", CACHE) ? ["${CACHE},name=app-test", "${CACHE},name=base"] : []
cache-to = notequal("", CACHE) ? ["${CACHE},mode=max,name=app-test"] : []

args = {
VERSION : VERSION,
Expand All @@ -52,8 +54,8 @@ target "app-test" {
target "tasks" {
dockerfile = "docker/application/Dockerfile"
target = "tasks"
cache-from = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/tasks:${VERSION}", "type=registry,ref=${CACHE_REGISTRY}/tasks:cache"] : []
cache-to = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/tasks:cache,mode=max"] : []
cache-from = notequal("", CACHE) ? ["${CACHE},name=tasks"] : []
cache-to = notequal("", CACHE) ? ["${CACHE},mode=max,name=tasks"] : []

args = {
VERSION : VERSION,
Expand All @@ -69,8 +71,8 @@ target "tasks" {
target "httpd" {
context = "docker/httpd"

cache-from = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/httpd:${ENVIRONMENT}-${VERSION}", "type=registry,ref=${CACHE_REGISTRY}/httpd:cache"] : []
cache-to = notequal("", CACHE_REGISTRY) ? ["type=registry,ref=${CACHE_REGISTRY}/httpd:cache,mode=max"] : []
cache-from = notequal("", CACHE) ? ["${CACHE},name=httpd"] : []
cache-to = notequal("", CACHE) ? ["${CACHE},mode=max,name=httpd"] : []

args = {
VERSION : VERSION,
Expand Down
Loading