Skip to content
Open
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
146 changes: 75 additions & 71 deletions .github/actions/build-and-push-image/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,86 +21,90 @@ inputs:
CUSTOM_BUILD_SCRIPT:
description: "The custom build script to use"
required: false
DOCKERFILE:
description: "The Dockerfile to use"
required: false
default: "Dockerfile"

runs:
using: "composite"
steps:
- name: 🔐 Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ inputs.AWS_ROLE_ARN }}
role-session-name: GitHub-Action-Role
aws-region: ${{ inputs.AWS_REGION }}
- name: 🔐 Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ inputs.AWS_ROLE_ARN }}
role-session-name: GitHub-Action-Role
aws-region: ${{ inputs.AWS_REGION }}

- name: 🔓 Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: 🔓 Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: 🧩 Parse ECR repositories
id: parse
shell: bash
run: |
if [ -n "${{ inputs.ECR_REPOSITORIES }}" ]; then
repos=$(echo "${{ inputs.ECR_REPOSITORIES }}" | tr ',' '\n')
elif [ -n "${{ inputs.ECR_REPOSITORY }}" ]; then
repos="${{ inputs.ECR_REPOSITORY }}"
else
echo "Error: Either ECR_REPOSITORY or ECR_REPOSITORIES must be provided."
exit 1
fi

- name: 🧩 Parse ECR repositories
id: parse
shell: bash
run: |
if [ -n "${{ inputs.ECR_REPOSITORIES }}" ]; then
repos=$(echo "${{ inputs.ECR_REPOSITORIES }}" | tr ',' '\n')
elif [ -n "${{ inputs.ECR_REPOSITORY }}" ]; then
repos="${{ inputs.ECR_REPOSITORY }}"
else
echo "Error: Either ECR_REPOSITORY or ECR_REPOSITORIES must be provided."
exit 1
fi

echo "repos<<EOF" >> $GITHUB_OUTPUT
echo "$repos" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "repos<<EOF" >> $GITHUB_OUTPUT
echo "$repos" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

# Build a multiline string of full ECR paths
images=""
for repo in $repos; do
images="$images\n${{ steps.login-ecr.outputs.registry }}/${repo}"
done
# Build a multiline string of full ECR paths
images=""
for repo in $repos; do
images="$images\n${{ steps.login-ecr.outputs.registry }}/${repo}"
done

# Write images to this step's output
echo "images<<EOF" >> $GITHUB_OUTPUT
echo -e "$images" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Write images to this step's output
echo "images<<EOF" >> $GITHUB_OUTPUT
echo -e "$images" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: 🐳 Docker Metadata
uses: docker/metadata-action@v5
id: meta
with:
images: "${{ steps.parse.outputs.images }}"
tags: |
latest
type=sha,prefix=sha-,format=long
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
- name: 🐳 Docker Metadata
uses: docker/metadata-action@v5
id: meta
with:
images: "${{ steps.parse.outputs.images }}"
tags: |
latest
type=sha,prefix=sha-,format=long
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag

- name: 🏗️ Build and push
if: ${{ !inputs.CUSTOM_BUILD_SCRIPT }}
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
context: ${{ inputs.WORKING_DIRECTORY }}
- name: 🏗️ Build and push
if: ${{ !inputs.CUSTOM_BUILD_SCRIPT }}
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
context: ${{ inputs.WORKING_DIRECTORY }}
file: ${{ inputs.WORKING_DIRECTORY }}/${{ inputs.DOCKERFILE || 'Dockerfile' }}

- name: 🏗️ Build and push images with custom script
if: ${{ inputs.CUSTOM_BUILD_SCRIPT }}
shell: bash
working-directory: ${{ inputs.WORKING_DIRECTORY }}
run: |
${{ inputs.CUSTOM_BUILD_SCRIPT }}
repos="${{ steps.parse.outputs.repos }}"
tags="${{ steps.meta.outputs.tags }}"
for repo in $repos; do
echo "Processing repository: $repo"
for tag in $tags; do
if [[ $tag == *"$repo"* ]]; then
echo "Tagging and pushing: $tag for image $repo"
docker tag "$repo" "$tag"
docker push "$tag"
fi
- name: 🏗️ Build and push images with custom script
if: ${{ inputs.CUSTOM_BUILD_SCRIPT }}
shell: bash
working-directory: ${{ inputs.WORKING_DIRECTORY }}
run: |
${{ inputs.CUSTOM_BUILD_SCRIPT }}
repos="${{ steps.parse.outputs.repos }}"
tags="${{ steps.meta.outputs.tags }}"
for repo in $repos; do
echo "Processing repository: $repo"
for tag in $tags; do
if [[ $tag == *"$repo"* ]]; then
echo "Tagging and pushing: $tag for image $repo"
docker tag "$repo" "$tag"
docker push "$tag"
fi
done
done
done

49 changes: 35 additions & 14 deletions .github/actions/deploy-ecs-service/action.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
name: '🚀 Deploy ECS service'
description: 'Deploy service on ECS with terraform'
name: "🚀 Deploy ECS service"
description: "Deploy service on ECS with terraform"

inputs:
AWS_REGION:
description: 'The AWS region to use'
description: "The AWS region to use"
required: true
default: eu-west-1
ENVIRONMENT:
description: 'Enter the environment.'
description: "Enter the environment."
required: true
AWS_DEPLOYMENT_ROLE:
description: 'The ARN of the AWS github-ci role the role to use for deployment'
description: "The ARN of the AWS github-ci role the role to use for deployment"
required: true
IMAGE_TAG:
description: 'The version tag of the image to deploy. Can be any image tag e.g. latest, 1.0.0, git sha'
description: "The version tag of the image to deploy. Can be any image tag e.g. latest, 1.0.0, git sha"
required: true
FORCE_NEW_DEPLOYMENT:
description: 'Force a new deployment even if the image tag is the same as the current deployment. E.g. latest'
description: "Force a new deployment even if the image tag is the same as the current deployment. E.g. latest"
required: false
default: false
SERVICE_NAME:
description: 'The name of the service to deploy. Only required if force new deployment is true'
description: "The name of the service to deploy. Only required if force new deployment is true"
required: false
CLUSTER_NAME:
description: 'The name of the ECS cluster to deploy to. Only required if force new deployment is true'
description: "The name of the ECS cluster to deploy to. Only required if force new deployment is true"
required: false
TERRAFORM_VERSION:
description: 'The version of Terraform to use'
description: "The version of Terraform to use"
required: false
default: 1.9.8
PRE_APPLIED_RESOURCES:
description: 'Resources to apply before deploying'
description: "Resources to apply before deploying"
required: false
default: '[]'
default: "[]"
TERRAFORM_PATH:
description: "The path to the terraform files"
required: false
default: "terraform"
SERVICES:
descritpion: "Only for deployment of mono repo and terraform in root"
required: false
default: ""

runs:
using: 'composite'
using: "composite"
steps:
- name: Setup Terraform
uses: hashicorp/setup-Terraform@v3
Expand All @@ -50,7 +54,7 @@ runs:
shell: bash
run: terraform --version

- name: 'Configure AWS Credentials'
- name: "Configure AWS Credentials"
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ inputs.AWS_DEPLOYMENT_ROLE }}
Expand Down Expand Up @@ -83,3 +87,20 @@ runs:
aws ecs wait services-stable \
--cluster ${{ inputs.CLUSTER_NAME }} \
--services ${{ inputs.SERVICE_NAME }}

- name: service list
id: service_list
if: ${{ inputs.SERVICES }}
shell: bash
run: |
list=$(echo '${{ inputs.SERVICES }}' | jq -r ' . |map(.name) | join(" ")')
echo service_list=${list}
echo service_list=${list} >> $GITHUB_OUTPUT

- name: Wait for all stable
shell: bash
if: ${{ inputs.SERVICES }}
run: |
aws ecs wait services-stable \
--cluster ${{ inputs.CLUSTER_NAME }} \
--services ${{ steps.service_list.outputs.service_list }}
141 changes: 141 additions & 0 deletions .github/workflows/main-deploy-mono-tf-global.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: "🚀 Build and deploy to main"
on:
workflow_call:
inputs:
aws_dev_account_id:
required: true
type: string
aws_region:
default: eu-west-1
type: string
github_ci_role_arn:
required: true
type: string
github_ci_ecr_role_arn:
required: true
type: string
services:
required: false
type: string
description: 'Services names when deploying multiple services. Should be a list of objects with keys "directory" and "name" e.g. [{"directory": "core", "name": "apro-core-service"}]'
cluster_name:
required: true
type: string
ecr_repository:
required: false
type: string
ecr_repositories:
required: false
type: string
custom_build_script:
required: false
type: string
terraform_version:
description: "Terraform version"
type: string
default: "1.9.8"
working_directory:
description: "Working directory"
type: string
default: "."
build_checkout_with_lfs:
description: "Checkout with LFS"
type: boolean
default: false
pre_applied_resources:
description: "Resources to apply before main deploy"
type: string
default: "[]"

secrets:
token:
required: true

permissions:
id-token: write # Required f. IAM Token
contents: write

jobs:
terraform-quality-checks:
name: "✅ Terraform Quality checks"
uses: aproorg/github-workflows/.github/workflows/terraform-quality-checks.yml@main
with:
terraform_version: ${{ inputs.terraform_version }}

get-next-version:
name: 🏷️ Get next version
runs-on: ubuntu-latest
outputs:
new_release_published: ${{ steps.get-next-version.outputs.new_release_published }}
steps:
- name: 📁 Checkout
uses: actions/checkout@v4

- name: 🏷️ Get next version
id: get-next-version
uses: aproorg/github-workflows/.github/actions/get-next-version@main
with:
github_token: ${{ secrets.token }}

create-ecr-repo:
name: "🚀 Apply shared"
runs-on: ubuntu-latest
steps:
- name: 📁 Checkout
uses: actions/checkout@v4

- name: "🚀 Apply shared"
uses: aproorg/github-workflows/.github/actions/apply-shared@main
with:
AWS_REGION: ${{ inputs.aws_region }}
AWS_ECR_DEPLOYMENT_ROLE: ${{ inputs.github_ci_ecr_role_arn }}
TERRAFORM_VERSION: ${{ inputs.terraform_version }}

build-and-push-all-images:
name: "️️️🏗️ Build and push all images"
strategy:
matrix:
include: ${{ fromJSON(inputs.services) }}
needs:
- terraform-quality-checks
- get-next-version
if: ${{ needs.get-next-version.outputs.new_release_published == 'true' }}
runs-on: ubuntu-latest
steps:
- name: 📁 Checkout
uses: actions/checkout@v4
with:
lfs: ${{ inputs.build_checkout_with_lfs }}

- name: "️️️🏗️ Build and push image all images"
uses: aproorg/github-workflows/.github/actions/build-and-push-image@kistill
with:
AWS_REGION: ${{ inputs.aws_region }}
AWS_ROLE_ARN: ${{ inputs.github_ci_ecr_role_arn }}
WORKING_DIRECTORY: ${{ matrix.directory }}
ECR_REPOSITORY: ${{ matrix.ecr_repository }}
DOCKERFILE: ${{ matrix.dockerfile }}

deploy-to-dev:
name: "🚀 Deploy to dev"
environment: dev
needs:
- build-and-push-all-images
- get-next-version
if: ${{ needs.get-next-version.outputs.new_release_published == 'true' }}
runs-on: ubuntu-latest
steps:
- name: 📁 Checkout
uses: actions/checkout@v4

- name: "🚀 Deploy to dev"
uses: aproorg/github-workflows/.github/actions/deploy-ecs-service@kistill
with:
AWS_REGION: ${{ inputs.aws_region }}
ENVIRONMENT: dev
AWS_DEPLOYMENT_ROLE: ${{ inputs.github_ci_role_arn }}
IMAGE_TAG: ${{ format('sha-{0}', github.sha) }}
SERVICES: ${{ inputs.services }}
CLUSTER_NAME: ${{ inputs.cluster_name }}
TERRAFORM_VERSION: ${{ inputs.terraform_version }}
PRE_APPLIED_RESOURCES: ${{ inputs.pre_applied_resources }}
Loading