name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: test: runs-on: ubuntu-latest services: postgres: image: postgis/postgis:15-3.3 env: POSTGRES_PASSWORD: test POSTGRES_DB: iom_test options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 redis: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 6379:6379 steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install pytest pytest-asyncio pytest-cov - name: Run tests env: DATABASE_URL: postgresql://postgres:test@localhost:5432/iom_test REDIS_URL: redis://localhost:6379/0 run: | pytest tests/ -v --cov=. --cov-report=xml - name: Upload coverage uses: codecov/codecov-action@v3 with: file: ./coverage.xml fail_ci_if_error: false lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Install linting tools run: | pip install flake8 black isort mypy - name: Run linters run: | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics black --check . isort --check-only . mypy . --ignore-missing-imports build: needs: [test, lint] runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Build and push API image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - name: Build and push Worker image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile.worker push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-worker:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max deploy-staging: needs: build runs-on: ubuntu-latest if: github.ref == 'refs/heads/develop' environment: staging steps: - uses: actions/checkout@v4 - name: Deploy to staging run: | echo "Deploying to staging..." # Add deployment commands here # e.g., SSH to server, pull images, restart services - name: Run smoke tests run: | echo "Running smoke tests..." # Add smoke test commands here deploy-production: needs: build runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' environment: production steps: - uses: actions/checkout@v4 - name: Deploy to production run: | echo "Deploying to production..." # Add deployment commands here - name: Run health checks run: | echo "Running health checks..." # Add health check commands here - name: Notify on success if: success() run: | echo "Deployment successful!" # Add notification commands here (Slack, email, etc.) - name: Rollback on failure if: failure() run: | echo "Deployment failed! Rolling back..." # Add rollback commands here