CI/CD Pipeline #19
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |