Skip to content

CI/CD Pipeline

CI/CD Pipeline #22

Workflow file for this run

name: CI/CD Pipeline
on:
workflow_dispatch:
inputs:
dry_run:
description: 'Perform a dry run'
required: false
default: 'true'
jobs:
dry-run:
if: github.event.inputs.dry_run == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Log in to Amazon ECR
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_REPOSITORY }}
- name: Compare Docker image digests
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
set -e
IMAGE_URI="${{ secrets.AWS_ECR_REPOSITORY }}:latest"
echo "Fetching remote image digest..."
REMOTE_DIGEST=$(aws ecr describe-images --repository-name wxyc_backend_service --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageDigest' --output text)
if [ -z "$REMOTE_DIGEST" ]; then
echo "Failed to fetch remote image digest."
exit 1
fi
echo "Remote Digest: $REMOTE_DIGEST"
echo "Building Docker image locally..."
docker build --platform linux/amd64 -t wxyc_backend_service:latest .
echo "Fetching local image ID..."
LOCAL_ID=$(docker inspect --format='{{.Id}}' wxyc_backend_service:latest)
if [ -z "$LOCAL_ID" ]; then
echo "Failed to fetch local image ID."
exit 1
fi
echo "Local ID: $LOCAL_ID"
echo "Remote Digest: $REMOTE_DIGEST"
if [ "$REMOTE_DIGEST" = "sha256:$LOCAL_ID" ]; then
echo "The image to be deployed is the same as the current image in ECR."
else
echo "The image to be deployed is different from the current image in ECR."
fi
- name: Dry run - list Docker images
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
echo "Listing Docker images..."
docker images || exit 1
echo "Listing running Docker containers..."
docker ps || exit 1
build-and-deploy:
if: github.event.inputs.dry_run != 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Log in to Amazon ECR
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_REPOSITORY }}
- name: Build, tag, and push Docker image to Amazon ECR
run: |
IMAGE_URI="${{ secrets.AWS_ECR_REPOSITORY }}:latest"
echo "Building Docker image..."
docker build --platform linux/amd64 -t wxyc_backend_service:latest .
echo "Tagging Docker image..."
docker tag wxyc_backend_service:latest $IMAGE_URI
echo "Pushing Docker image to ECR..."
docker push $IMAGE_URI
- name: Execute remote commands via SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
set -e
export AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
export AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
export AWS_DEFAULT_REGION=${{ secrets.AWS_REGION }}
echo "Logging into AWS ECR..."
aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_REPOSITORY }}
echo "Pulling Docker image..."
docker pull ${{ secrets.AWS_ECR_REPOSITORY }}:latest
echo "Stopping any existing container using port 8080..."
docker ps --filter "ancestor=${{ secrets.AWS_ECR_REPOSITORY }}:latest" --format "{{.ID}}" | xargs -r docker stop
docker ps --filter "publish=8080" --format "{{.ID}}" | xargs -r docker stop
echo "Removing any existing container using port 8080..."
docker ps -a --filter "ancestor=${{ secrets.AWS_ECR_REPOSITORY }}:latest" --format "{{.ID}}" | xargs -r docker rm
docker ps -a --filter "publish=8080" --format "{{.ID}}" | xargs -r docker rm
echo "Starting new Docker container..."
docker run -d -p 8080:8080 --env-file .env ${{ secrets.AWS_ECR_REPOSITORY }}:latest
- name: Confirm server is up
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
echo "Waiting for server to start..."
sleep 30 # Adjust sleep time as needed
echo "Checking server status..."
if curl -s --head --request GET http://localhost:8080/flowsheet | grep "200 OK" > /dev/null; then
echo "Server is up and running."
else
echo "Server is not running. Deployment failed." >&2
exit 1
fi