Skip to content

chore(deps): remove conflicting Flask pin from requirements #32

chore(deps): remove conflicting Flask pin from requirements

chore(deps): remove conflicting Flask pin from requirements #32

Workflow file for this run

# CI/CD Pipeline: Build, Push to ECR, Deploy to EC2
# Triggers on push to main and pull requests
# Jobs: CI (test) → Build & Push to ECR → Deploy to EC2 instance
name: CI/CD - Deploy to EC2
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
permissions:
contents: read
jobs:
# ===== CI: Run tests and validation =====
ci:
name: Continuous Integration
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Lint with flake8 (optional)
continue-on-error: true
run: |
pip install flake8
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics || true
- name: Run tests (if present)
continue-on-error: true
run: |
if [ -d "tests" ] || ls *test*.py 2>/dev/null; then
pip install pytest
pytest -v || true
else
echo "No tests found, skipping test step"
fi
# ===== BUILD: Build Docker image and push to ECR =====
build-and-push:
name: Build and Push to ECR
runs-on: ubuntu-latest
needs: ci
# Only build and push on direct push to main (not PRs)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
outputs:
image: ${{ steps.build-image.outputs.image }}
steps:
- name: Checkout code
uses: actions/checkout@v5
- 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: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
IMAGE_TAG: ${{ github.sha }}
run: |
# Build Docker image
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
# Push both tags to ECR
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "✅ Image pushed: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
# ===== DEPLOY: Deploy to EC2 instance =====
deploy:
name: Deploy to EC2
runs-on: ubuntu-latest
needs: build-and-push
steps:
- 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: Deploy to EC2 via SSH
uses: appleboy/ssh-action@v1.0.3
env:
IMAGE_TAG: ${{ github.sha }}
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
envs: ECR_REGISTRY,ECR_REPOSITORY,IMAGE_TAG,AWS_REGION
script: |
set -e
echo "🚀 Starting deployment on EC2..."
# Install AWS CLI if not present
if ! command -v aws &> /dev/null; then
echo "Installing AWS CLI..."
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -q awscliv2.zip
sudo ./aws/install
fi
# Login to ECR
echo "🔐 Logging into Amazon ECR..."
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}
# Pull latest image
echo "📦 Pulling Docker image..."
docker pull ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}:$IMAGE_TAG
# Stop and remove old container (if exists)
echo "🛑 Stopping old container..."
docker stop mlproject 2>/dev/null || true
docker rm mlproject 2>/dev/null || true
# Run new container
echo "▶️ Starting new container..."
docker run -d \
--name mlproject \
--restart unless-stopped \
-p 80:8080 \
${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}:$IMAGE_TAG
# Wait for container to be healthy
echo "⏳ Waiting for container to start..."
sleep 5
# Check container status
if docker ps | grep -q mlproject; then
echo "✅ Deployment successful!"
docker ps | grep mlproject
else
echo "❌ Container failed to start"
docker logs mlproject
exit 1
fi
# Cleanup old images (keep last 3)
echo "🧹 Cleaning up old images..."
docker image prune -af --filter "until=72h" || true
echo "🎉 Deployment completed successfully!"