Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SAH-119]: Nest.js Server #238

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
166 changes: 166 additions & 0 deletions .github/workflows/sahil-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
name: Docker image build and publish for Server
on:
workflow_dispatch:
inputs:
path_to_dockerfile:
description: Path to the dockerfile (default = 'Dockerfile')
default: "infra/docker/Dockerfile.server"
type: string
docker_build_dir:
description: Docker build directory (default = '.')
default: "."
type: string
image_tag:
description: Tag to apply to images.
type: string
default: sahil-server
lifecycle_policy_file:
description: Path to the lifecycle policy JSON file (default = 'policy.json')
default: "policy.json"
type: string
backend_s3_bucket:
description: Name of the S3bucket for Terraform backend
default: "sahil-terraform-state-bucket"
type: string
backend_iam_role:
description: Name of the Terraform backend assumable IAM Role
default: "workload-assumable-role"
type: string
github_iam_role:
description: Name of the IAM Role for adding access to ECR repo
default: "github-actions-role"
type: string
aws_account_id:
description: AWS Account ID
default: "060795911441"
type: string
aws_region:
description: Target AWS Region
default: "eu-west-1"
type: string
backend_dynamodb_table:
description: DynamoDB table for State lock
default: "sahil-terraform-table-locks"
type: string

# concurrency required to avoid terraform lock contention during ECR provisioning
concurrency: ci-${{ github.repository }}-server-docker-pipeline

jobs:
docker:
runs-on: ubuntu-latest

permissions:
id-token: write
contents: read

outputs:
image_tag: ${{ steps.build-publish.outputs.image_tag }}
version_tag: ${{ steps.build-publish.outputs.version_tag }}
full_image: ${{ steps.build-publish.outputs.full_image }}

steps:
- uses: actions/checkout@v3

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/sahil-deployment-role
aws-region: ${{ inputs.aws_region }}

- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false

- name: prepare ECR repo name based on the Github repository
shell: bash
run: |
set -eux
# lowercase the name
repo="${GITHUB_REPOSITORY,,}"

# replace / with _
echo "ECR_REPO_NAME=${repo//\//_}" >> $GITHUB_ENV

- name: TF init
shell: bash
run: |
set -eux
terraform init -upgrade -reconfigure \
-backend-config='skip_metadata_api_check=true' \
-backend-config='skip_region_validation=true' \
-backend-config='skip_credentials_validation=true' \
-backend-config='region=${{ inputs.aws_region }}' \
-backend-config='bucket=${{ inputs.backend_s3_bucket }}' \
-backend-config='key=docker-ecr/terraform-${{ env.ECR_REPO_NAME }}.tfstate' \
-backend-config='dynamodb_table=${{ inputs.backend_dynamodb_table }}' \
-backend-config='assume_role={ role_arn = "arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.backend_iam_role }}" }'
working-directory: infra/terraform

- name: Create ECR repo [TF apply]
shell: bash
run: |
set -eux
terraform apply \
-var 'repository_name=${{ env.ECR_REPO_NAME }}' \
-var 'lifecycle_policy=${{ inputs.lifecycle_policy_file }}' \
-var 'iam_role=arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.github_iam_role }}' \
-var 'aws_account_id=${{ inputs.aws_account_id }}' \
-auto-approve
working-directory: infra/terraform

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
registries: ${{ inputs.aws_account_id }}

- name: Build, tag, and push image to Amazon ECR
id: build-publish
shell: bash
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPO_NAME }}
IMAGE_TAG: ${{ inputs.image_tag }}
run: |
# Get the current latest image digest (if it exists)
PREVIOUS_IMAGE_MANIFEST=$(aws ecr batch-get-image \
--repository-name $ECR_REPOSITORY \
--image-ids imageTag=$IMAGE_TAG \
--output text \
--query 'images[].imageManifest' || echo "")

# Build the new image
docker build "${{ inputs.docker_build_dir }}" -f "${{ inputs.path_to_dockerfile }}" -t "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

# Push the new image as latest
docker push "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

# If there was a previous image, tag it as v1, v2, etc.
if [ ! -z "$PREVIOUS_IMAGE_MANIFEST" ]; then
# Get the current highest version number
CURRENT_VERSION=$(aws ecr describe-images \
--repository-name $ECR_REPOSITORY \
--query 'imageDetails[].imageTags[?starts_with(@, `v`)]' \
--output text | grep -o 'v[0-9]*' | sed 's/v//' | sort -n | tail -1)

# Calculate next version number
if [ -z "$CURRENT_VERSION" ]; then
NEW_VERSION="v1"
else
NEW_VERSION="v$((CURRENT_VERSION + 1))"
fi

# Tag the previous image with the new version
aws ecr put-image \
--repository-name $ECR_REPOSITORY \
--image-tag $NEW_VERSION \
--image-manifest "$PREVIOUS_IMAGE_MANIFEST"

echo "Previous image tagged as $NEW_VERSION"
echo "version_tag=$NEW_VERSION" >> $GITHUB_OUTPUT
fi

echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "full_image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
Loading
Loading