Skip to content

Merge pull request #13 from maxh33/feat/tests #96

Merge pull request #13 from maxh33/feat/tests

Merge pull request #13 from maxh33/feat/tests #96

Workflow file for this run

name: Deploy to Production
on:
push:
branches:
- main
pull_request:
branches:
- main
- feat/tests # Include for testing deployment in PRs
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: |
npm run test:unit
npm run test:integration
env:
MONGODB_URI: mongodb://localhost:27017/test
RABBITMQ_URL: amqp://guest:guest@localhost:5672
build-and-deploy:
needs: test # Only deploy if tests pass
if: github.ref == 'refs/heads/main' # Only deploy on main branch
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Verify MongoDB Connection
run: npm run verify:mongodb
env:
MONGODB_URI: ${{ secrets.MONGODB_URI }}
NODE_ENV: production
- name: Set RabbitMQ Credentials
run: |
# Use localhost for GitHub Actions since we're running verification locally
echo "RABBITMQ_PASSWORD=${{ secrets.RABBITMQ_PASSWORD }}" >> $GITHUB_ENV
echo "RABBITMQ_URL=amqp://pulse_flow_user:${{ secrets.RABBITMQ_PASSWORD }}@localhost:5672" >> $GITHUB_ENV
- name: Verify RabbitMQ Connection
run: npm run verify:rabbitmq
env:
RABBITMQ_URL: ${{ secrets.RABBITMQ_URL }}
NODE_ENV: production
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create environment file
run: |
cat > .env << 'EOL'
PORT=3000
NODE_ENV=production
MONGODB_URI=${{ secrets.MONGODB_URI }}
GRAFANA_PUSH_URL=${{ secrets.GRAFANA_PUSH_URL }}
GRAFANA_PROMETHEUS_URL=${{ secrets.GRAFANA_PROMETHEUS_URL }}
GRAFANA_USERNAME=${{ secrets.GRAFANA_USERNAME }}
GRAFANA_API_KEY=${{ secrets.GRAFANA_API_KEY }}
RABBITMQ_URL=${{ secrets.RABBITMQ_URL }}
METRICS_PUSH_INTERVAL=60000
EOL
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.prod
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Install Docker Compose
run: |
sudo curl -L "https://github.com/docker/compose/releases/download/$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r .tag_name)/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
- name: Setup and Deploy
run: |
# Clean up existing deployment first
bash scripts/cleanup.sh
# Initialize network with proper labels
bash scripts/init-network.sh
# Deploy with proper project name
COMPOSE_PROJECT_NAME=pulse-flow docker-compose -f docker-compose.prod.yml up -d
env:
MONGODB_URI: ${{ secrets.MONGODB_URI }}
GRAFANA_PUSH_URL: ${{ secrets.GRAFANA_PUSH_URL }}
GRAFANA_PROMETHEUS_URL: ${{ secrets.GRAFANA_PROMETHEUS_URL }}
GRAFANA_USERNAME: ${{ secrets.GRAFANA_USERNAME }}
GRAFANA_API_KEY: ${{ secrets.GRAFANA_API_KEY }}
RABBITMQ_URL: ${{ secrets.RABBITMQ_URL }}
GITHUB_REPOSITORY: ${{ github.repository }}
- name: Wait for app to start
run: sleep 30 # Give containers time to fully start
- name: Verify Deployment
run: |
# Check if container is running and get its status
CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' pulse-flow-app 2>/dev/null || echo "not_found")
if [ "$CONTAINER_STATUS" != "running" ]; then
echo "Container pulse-flow-app is not running (status: $CONTAINER_STATUS)"
echo "Container logs:"
docker logs pulse-flow-app || true
echo "All running containers:"
docker ps
exit 1
fi
# Check container logs
echo "Container logs:"
docker logs pulse-flow-app
# Try direct health check
for i in {1..5}; do
if curl -f http://localhost:3000/healthz; then
echo "Health check passed!"
exit 0
fi
echo "Attempt $i failed, waiting..."
sleep 10
done
echo "Health check failed after 5 attempts"
exit 1
- name: Cleanup on Failure
if: failure()
run: |
docker-compose -f docker-compose.prod.yml down --volumes --remove-orphans || true
docker network rm pulse-flow_app_network || true