Repository navigation
Deploy Complete RAG Modulo Application #463
This file contains hidden or 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
| # ============================================================================= | |
| # Workflow: Deploy Complete RAG Modulo Application | |
| # ============================================================================= | |
| # Description: Comprehensive deployment workflow for RAG Modulo application | |
| # including infrastructure, backend, and frontend components | |
| # to IBM Cloud Code Engine with security scanning and testing. | |
| # | |
| # Author: RAG Modulo Team | |
| # Last Updated: 2025-01-13 | |
| # Version: 2.0 | |
| # | |
| # Triggers: | |
| # - Manual dispatch (workflow_dispatch) | |
| # - Daily builds (schedule: 2 AM UTC) | |
| # - Push to main/develop branches | |
| # | |
| # Prerequisites: | |
| # - IBM Cloud API Key configured as secret | |
| # - IBM Cloud Container Registry namespace created | |
| # - All application secrets configured in repository settings | |
| # | |
| # Jobs: | |
| # 1. deploy-infrastructure: Deploy PostgreSQL, MinIO, etcd, Milvus | |
| # 2. build-and-push-backend: Build and push backend Docker image | |
| # 3. build-and-push-frontend: Build and push frontend Docker image | |
| # 4. security-scan-*: Scan images for vulnerabilities with Trivy | |
| # 5. deploy-*: Deploy applications to IBM Cloud Code Engine | |
| # 6. smoke-test: Verify deployment health and functionality | |
| # | |
| # Security Features: | |
| # - Trivy vulnerability scanning with SARIF output | |
| # - Non-root container execution | |
| # - Command injection prevention | |
| # - Secret management via GitHub Secrets | |
| # | |
| # Resources Deployed: | |
| # - Backend: 1 CPU, 4GB RAM, scales 1-5 instances | |
| # - Frontend: 0.5 CPU, 1GB RAM, scales 1-3 instances | |
| # - PostgreSQL: 0.5 CPU, 2GB RAM | |
| # - MinIO: 0.25 CPU, 1GB RAM | |
| # - etcd: 0.25 CPU, 1GB RAM | |
| # - Milvus: 0.5 CPU, 2GB RAM | |
| # ============================================================================= | |
| name: Deploy Complete RAG Modulo Application | |
| # Define workflow triggers | |
| on: | |
| # Manual deployment with environment selection | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: "Deployment environment" | |
| required: true | |
| default: "dev" | |
| type: choice | |
| options: | |
| - dev | |
| - staging | |
| - production | |
| skip_security_scan: | |
| description: "Skip security scanning (not recommended)" | |
| required: false | |
| default: false | |
| type: boolean | |
| deploy_after_build: | |
| description: "Deploy after building (for daily builds)" | |
| required: false | |
| default: false | |
| type: boolean | |
| # Daily automated builds at 2 AM UTC | |
| schedule: | |
| - cron: "0 2 * * *" | |
| # Automatic deployment on code changes | |
| push: | |
| branches: | |
| - main | |
| - develop | |
| # Define environment variables for the entire workflow | |
| env: | |
| PROJECT_NAME: rag-modulo-${{ inputs.environment || 'dev' }} | |
| BACKEND_APP_NAME: ${{ vars.BACKEND_APP_NAME || 'rag-modulo-backend' }} | |
| FRONTEND_APP_NAME: ${{ vars.FRONTEND_APP_NAME || 'rag-modulo-frontend' }} | |
| IBM_CLOUD_REGION: ${{ vars.IBM_CLOUD_REGION || 'us-south' }} | |
| CR_NAMESPACE: ${{ vars.IBM_CR_NAMESPACE || 'rag_modulo' }} | |
| # ICR uses shortened region names: us-south -> us, eu-gb -> uk, ca-tor -> ca, etc. | |
| ICR_REGION: ${{ vars.IBM_CLOUD_REGION == 'eu-gb' && 'uk' || (vars.IBM_CLOUD_REGION == 'us-south' && 'us' || | |
| (vars.IBM_CLOUD_REGION == 'us-east' && 'us' || (vars.IBM_CLOUD_REGION == 'ca-tor' && 'ca' || | |
| vars.IBM_CLOUD_REGION))) }} | |
| # Prevent concurrent deployments to avoid conflicts | |
| concurrency: | |
| group: deploy-complete-app-${{ github.ref }} | |
| cancel-in-progress: false | |
| # ============================================================================= | |
| # WORKFLOW JOBS | |
| # ============================================================================= | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Job 1: Deploy Infrastructure Components | |
| # --------------------------------------------------------------------------- | |
| # Purpose: Deploy core infrastructure services (PostgreSQL, MinIO, etcd, Milvus) | |
| # Dependencies: None (runs first) | |
| # Outputs: Infrastructure services ready for application deployment | |
| # --------------------------------------------------------------------------- | |
| deploy-infrastructure: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install Ansible and dependencies | |
| run: | | |
| pip install ansible | |
| ansible-galaxy collection install -r deployment/ansible/requirements.yml | |
| - name: Set up IBM Cloud CLI | |
| uses: IBM/actions-ibmcloud-cli@v1 | |
| with: | |
| api_key: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| region: ${{ env.IBM_CLOUD_REGION }} | |
| group: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| plugins: code-engine | |
| - name: Deploy Infrastructure using Ansible | |
| env: | |
| IBM_CLOUD_API_KEY: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| IBM_CLOUD_REGION: ${{ env.IBM_CLOUD_REGION }} | |
| IBM_CLOUD_RESOURCE_GROUP: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| COLLECTIONDB_USER: ${{ secrets.COLLECTIONDB_USER }} | |
| COLLECTIONDB_PASS: ${{ secrets.COLLECTIONDB_PASS }} | |
| COLLECTIONDB_NAME: ${{ secrets.COLLECTIONDB_NAME }} | |
| MINIO_ROOT_USER: ${{ secrets.MINIO_ROOT_USER || 'minioadmin' }} | |
| MINIO_ROOT_PASSWORD: ${{ secrets.MINIO_ROOT_PASSWORD || 'minioadmin' }} | |
| run: | | |
| # Create temporary inventory for infrastructure deployment | |
| cat > /tmp/inventory.yml << EOF | |
| all: | |
| hosts: | |
| localhost: | |
| ansible_connection: local | |
| ansible_python_interpreter: "{{ ansible_playbook_python }}" | |
| vars: | |
| project_name: "rag-modulo" | |
| environment: "dev" | |
| region: "${{ env.IBM_CLOUD_REGION }}" | |
| resource_group_id: "${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }}" | |
| ibmcloud_api_key: "${{ secrets.IBM_CLOUD_API_KEY }}" | |
| EOF | |
| # Note: Full Ansible deployment will be implemented in next iteration | |
| # For now, we'll use IBM Cloud CLI directly for infrastructure | |
| echo "Deploying infrastructure components..." | |
| ibmcloud login --apikey "$IBM_CLOUD_API_KEY" --no-region | |
| ibmcloud target -r "$IBM_CLOUD_REGION" -g "$IBM_CLOUD_RESOURCE_GROUP" | |
| # Create Code Engine project if it doesn't exist (idempotent) | |
| # Check if project exists and handle soft-deleted state | |
| if ibmcloud ce project get --name "$PROJECT_NAME" 2>&1 | grep -q "soft deleted"; then | |
| echo "⚠️ Project '$PROJECT_NAME' is soft-deleted, creating new one with timestamp..." | |
| NEW_PROJECT_NAME="${PROJECT_NAME}-$(date +%s)" | |
| echo "🆕 Creating project '$NEW_PROJECT_NAME'..." | |
| ibmcloud ce project create --name "$NEW_PROJECT_NAME" | |
| ibmcloud ce project select --name "$NEW_PROJECT_NAME" | |
| echo "PROJECT_NAME=$NEW_PROJECT_NAME" >> $GITHUB_ENV | |
| elif ibmcloud ce project get --name "$PROJECT_NAME" &>/dev/null; then | |
| echo "✅ Project '$PROJECT_NAME' exists - selecting..." | |
| ibmcloud ce project select --name "$PROJECT_NAME" | |
| else | |
| echo "🆕 Creating project '$PROJECT_NAME'..." | |
| ibmcloud ce project create --name "$PROJECT_NAME" | |
| ibmcloud ce project select --name "$PROJECT_NAME" | |
| fi | |
| echo "Infrastructure deployment placeholder - will be enhanced with full Ansible playbook" | |
| # --------------------------------------------------------------------------- | |
| # Job 2: Build and Push Backend Application | |
| # --------------------------------------------------------------------------- | |
| # Purpose: Build Docker image for backend FastAPI application and push to registry | |
| # Dependencies: deploy-infrastructure (must complete first) | |
| # Outputs: Backend Docker image in IBM Cloud Container Registry | |
| # Security: Multi-stage build, non-root user, CPU-only PyTorch | |
| # --------------------------------------------------------------------------- | |
| build-and-push-backend: | |
| needs: deploy-infrastructure | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| security-events: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to IBM Cloud Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.ICR_REGION }}.icr.io | |
| username: iamapikey | |
| password: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| - name: Build and push backend Docker image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile.codeengine | |
| platforms: linux/amd64 | |
| push: true | |
| tags: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.BACKEND_APP_NAME }}:${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-and-push-frontend: | |
| needs: deploy-infrastructure | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| security-events: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to IBM Cloud Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.ICR_REGION }}.icr.io | |
| username: iamapikey | |
| password: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| - name: Build and push frontend Docker image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ./frontend | |
| file: ./frontend/Dockerfile.frontend | |
| platforms: linux/amd64 | |
| push: true | |
| tags: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.FRONTEND_APP_NAME }}:${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| security-scan-backend: | |
| needs: build-and-push-backend | |
| if: ${{ !inputs.skip_security_scan }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Run Trivy vulnerability scanner (Backend) | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 pinned to SHA | |
| with: | |
| image-ref: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.BACKEND_APP_NAME }}:${{ github.sha }} | |
| format: "sarif" | |
| output: "trivy-backend-results.sarif" | |
| - name: Upload Trivy scan results to GitHub Security tab (Backend) | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() | |
| with: | |
| sarif_file: "trivy-backend-results.sarif" | |
| - name: Run Trivy vulnerability scanner (Backend - Table) | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 pinned to SHA | |
| with: | |
| image-ref: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.BACKEND_APP_NAME }}:${{ github.sha }} | |
| format: "table" | |
| exit-code: "1" | |
| severity: "CRITICAL,HIGH" | |
| security-scan-frontend: | |
| needs: build-and-push-frontend | |
| if: ${{ !inputs.skip_security_scan }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Run Trivy vulnerability scanner (Frontend) | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 pinned to SHA | |
| with: | |
| image-ref: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.FRONTEND_APP_NAME }}:${{ github.sha }} | |
| format: "sarif" | |
| output: "trivy-frontend-results.sarif" | |
| - name: Upload Trivy scan results to GitHub Security tab (Frontend) | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() | |
| with: | |
| sarif_file: "trivy-frontend-results.sarif" | |
| - name: Run Trivy vulnerability scanner (Frontend - Table) | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 pinned to SHA | |
| with: | |
| image-ref: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.FRONTEND_APP_NAME }}:${{ github.sha }} | |
| format: "table" | |
| exit-code: "1" | |
| severity: "CRITICAL,HIGH" | |
| deploy-backend: | |
| needs: [build-and-push-backend, security-scan-backend] | |
| if: always() && (needs.security-scan-backend.result == 'success' || needs.security-scan-backend.result == 'skipped') | |
| && (github.event_name == 'workflow_dispatch' || github.event_name == 'push' || (github.event_name == 'schedule' && | |
| inputs.deploy_after_build == true)) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Set up IBM Cloud CLI | |
| uses: IBM/actions-ibmcloud-cli@v1 | |
| with: | |
| api_key: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| region: ${{ env.IBM_CLOUD_REGION }} | |
| group: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| plugins: code-engine | |
| - name: Deploy Backend to Code Engine | |
| env: | |
| IBM_CLOUD_API_KEY: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| ICR_REGION: ${{ env.ICR_REGION }} | |
| IMAGE_URL: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.BACKEND_APP_NAME }}:${{ github.sha }} | |
| APP_NAME: ${{ env.BACKEND_APP_NAME }} | |
| IBM_CLOUD_REGION: ${{ env.IBM_CLOUD_REGION }} | |
| IBM_CLOUD_RESOURCE_GROUP: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| SKIP_AUTH: ${{ secrets.SKIP_AUTH }} | |
| OIDC_DISCOVERY_ENDPOINT: ${{ secrets.OIDC_DISCOVERY_ENDPOINT }} | |
| IBM_CLIENT_ID: ${{ secrets.IBM_CLIENT_ID }} | |
| IBM_CLIENT_SECRET: ${{ secrets.IBM_CLIENT_SECRET }} | |
| FRONTEND_URL: ${{ secrets.FRONTEND_URL }} | |
| WATSONX_APIKEY: ${{ secrets.WATSONX_APIKEY }} | |
| WATSONX_INSTANCE_ID: ${{ secrets.WATSONX_INSTANCE_ID }} | |
| COLLECTIONDB_USER: ${{ secrets.COLLECTIONDB_USER }} | |
| COLLECTIONDB_PASS: ${{ secrets.COLLECTIONDB_PASS }} | |
| COLLECTIONDB_HOST: rag-modulo-postgres | |
| COLLECTIONDB_PORT: "5432" | |
| COLLECTIONDB_NAME: ${{ secrets.COLLECTIONDB_NAME }} | |
| VECTOR_DB: "milvus" | |
| MILVUS_HOST: rag-modulo-milvus | |
| MILVUS_PORT: "19530" | |
| MILVUS_USER: "" | |
| MILVUS_PASSWORD: "" | |
| MINIO_ENDPOINT: rag-modulo-minio:9000 | |
| MINIO_ACCESS_KEY: ${{ secrets.MINIO_ROOT_USER || 'minioadmin' }} | |
| MINIO_SECRET_KEY: ${{ secrets.MINIO_ROOT_PASSWORD || 'minioadmin' }} | |
| MINIO_USE_SSL: "false" | |
| JWT_SECRET_KEY: ${{ secrets.JWT_SECRET_KEY }} | |
| LOG_LEVEL: "INFO" | |
| run: | | |
| echo "Deploying backend application..." | |
| ibmcloud login --apikey "$IBM_CLOUD_API_KEY" --no-region | |
| ibmcloud target -r "$IBM_CLOUD_REGION" -g "$IBM_CLOUD_RESOURCE_GROUP" | |
| ibmcloud ce project select --name "$PROJECT_NAME" | |
| # Create or update registry access secret | |
| echo "Setting up registry access..." | |
| if ibmcloud ce secret get --name icr-secret > /dev/null 2>&1; then | |
| echo "Registry secret already exists" | |
| else | |
| echo "Creating registry access secret..." | |
| ibmcloud ce secret create --name icr-secret \ | |
| --format registry \ | |
| --server ${ICR_REGION}.icr.io \ | |
| --username iamapikey \ | |
| --password "$IBM_CLOUD_API_KEY" | |
| fi | |
| # Deploy or update backend application | |
| if ibmcloud ce app get "$APP_NAME" > /dev/null 2>&1; then | |
| echo "Updating existing backend application..." | |
| ibmcloud ce app update "$APP_NAME" \ | |
| --image "$IMAGE_URL" \ | |
| --registry-secret icr-secret \ | |
| --min-scale 1 \ | |
| --max-scale 5 \ | |
| --cpu 1 \ | |
| --memory 4G \ | |
| --env DATABASE_URL="postgresql://$COLLECTIONDB_USER:$COLLECTIONDB_PASS@$COLLECTIONDB_HOST:$COLLECTIONDB_PORT/$COLLECTIONDB_NAME?sslmode=require" \ | |
| --env MILVUS_HOST="$MILVUS_HOST" \ | |
| --env MILVUS_PORT="$MILVUS_PORT" \ | |
| --env MINIO_ENDPOINT="$MINIO_ENDPOINT" \ | |
| --env MINIO_ACCESS_KEY="$MINIO_ACCESS_KEY" \ | |
| --env MINIO_SECRET_KEY="$MINIO_SECRET_KEY" \ | |
| --env WATSONX_APIKEY="$WATSONX_APIKEY" \ | |
| --env WATSONX_INSTANCE_ID="$WATSONX_INSTANCE_ID" \ | |
| --env JWT_SECRET_KEY="$JWT_SECRET_KEY" \ | |
| --env LOG_LEVEL="$LOG_LEVEL" \ | |
| --env SKIP_AUTH="$SKIP_AUTH" | |
| else | |
| echo "Creating new backend application..." | |
| ibmcloud ce app create --name "$APP_NAME" \ | |
| --image "$IMAGE_URL" \ | |
| --registry-secret icr-secret \ | |
| --min-scale 1 \ | |
| --max-scale 5 \ | |
| --cpu 1 \ | |
| --memory 4G \ | |
| --port 8000 \ | |
| --env DATABASE_URL="postgresql://$COLLECTIONDB_USER:$COLLECTIONDB_PASS@$COLLECTIONDB_HOST:$COLLECTIONDB_PORT/$COLLECTIONDB_NAME?sslmode=require" \ | |
| --env MILVUS_HOST="$MILVUS_HOST" \ | |
| --env MILVUS_PORT="$MILVUS_PORT" \ | |
| --env MINIO_ENDPOINT="$MINIO_ENDPOINT" \ | |
| --env MINIO_ACCESS_KEY="$MINIO_ACCESS_KEY" \ | |
| --env MINIO_SECRET_KEY="$MINIO_SECRET_KEY" \ | |
| --env WATSONX_APIKEY="$WATSONX_APIKEY" \ | |
| --env WATSONX_INSTANCE_ID="$WATSONX_INSTANCE_ID" \ | |
| --env JWT_SECRET_KEY="$JWT_SECRET_KEY" \ | |
| --env LOG_LEVEL="$LOG_LEVEL" \ | |
| --env SKIP_AUTH="$SKIP_AUTH" | |
| fi | |
| echo "Backend deployment complete!" | |
| deploy-frontend: | |
| needs: [build-and-push-frontend, security-scan-frontend] | |
| if: always() && (needs.security-scan-frontend.result == 'success' || needs.security-scan-frontend.result == | |
| 'skipped') && (github.event_name == 'workflow_dispatch' || github.event_name == 'push' || (github.event_name == | |
| 'schedule' && inputs.deploy_after_build == true)) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Set up IBM Cloud CLI | |
| uses: IBM/actions-ibmcloud-cli@v1 | |
| with: | |
| api_key: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| region: ${{ env.IBM_CLOUD_REGION }} | |
| group: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| plugins: code-engine | |
| - name: Deploy Frontend to Code Engine | |
| env: | |
| IBM_CLOUD_API_KEY: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| ICR_REGION: ${{ env.ICR_REGION }} | |
| IMAGE_URL: ${{ env.ICR_REGION }}.icr.io/${{ env.CR_NAMESPACE }}/${{ env.FRONTEND_APP_NAME }}:${{ github.sha }} | |
| APP_NAME: ${{ env.FRONTEND_APP_NAME }} | |
| IBM_CLOUD_REGION: ${{ env.IBM_CLOUD_REGION }} | |
| IBM_CLOUD_RESOURCE_GROUP: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| REACT_APP_API_URL: ${{ secrets.REACT_APP_API_URL }} | |
| REACT_APP_WS_URL: ${{ secrets.REACT_APP_WS_URL }} | |
| run: | | |
| echo "Deploying frontend application..." | |
| ibmcloud login --apikey "$IBM_CLOUD_API_KEY" --no-region | |
| ibmcloud target -r "$IBM_CLOUD_REGION" -g "$IBM_CLOUD_RESOURCE_GROUP" | |
| ibmcloud ce project select --name "$PROJECT_NAME" | |
| # Create or update registry access secret (if not already created by backend) | |
| echo "Setting up registry access..." | |
| if ibmcloud ce secret get --name icr-secret > /dev/null 2>&1; then | |
| echo "Registry secret already exists" | |
| else | |
| echo "Creating registry access secret..." | |
| ibmcloud ce secret create --name icr-secret \ | |
| --format registry \ | |
| --server ${ICR_REGION}.icr.io \ | |
| --username iamapikey \ | |
| --password "$IBM_CLOUD_API_KEY" | |
| fi | |
| # Deploy or update frontend application | |
| if ibmcloud ce app get "$APP_NAME" > /dev/null 2>&1; then | |
| echo "Updating existing frontend application..." | |
| ibmcloud ce app update "$APP_NAME" \ | |
| --image "$IMAGE_URL" \ | |
| --registry-secret icr-secret \ | |
| --min-scale 1 \ | |
| --max-scale 3 \ | |
| --cpu 0.5 \ | |
| --memory 1G \ | |
| --env REACT_APP_API_URL="$REACT_APP_API_URL" \ | |
| --env REACT_APP_WS_URL="$REACT_APP_WS_URL" | |
| else | |
| echo "Creating new frontend application..." | |
| ibmcloud ce app create --name "$APP_NAME" \ | |
| --image "$IMAGE_URL" \ | |
| --registry-secret icr-secret \ | |
| --min-scale 1 \ | |
| --max-scale 3 \ | |
| --cpu 0.5 \ | |
| --memory 1G \ | |
| --port 3000 \ | |
| --env REACT_APP_API_URL="$REACT_APP_API_URL" \ | |
| --env REACT_APP_WS_URL="$REACT_APP_WS_URL" | |
| fi | |
| echo "Frontend deployment complete!" | |
| smoke-test: | |
| needs: [deploy-backend, deploy-frontend] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v5 | |
| - name: Set up IBM Cloud CLI | |
| uses: IBM/actions-ibmcloud-cli@v1 | |
| with: | |
| api_key: ${{ secrets.IBM_CLOUD_API_KEY }} | |
| region: ${{ env.IBM_CLOUD_REGION }} | |
| group: ${{ vars.IBM_CLOUD_RESOURCE_GROUP || 'rag-modulo-deployment' }} | |
| plugins: code-engine | |
| - name: Test Backend Health | |
| run: | | |
| BACKEND_URL=$(ibmcloud ce app get --name "${{ env.BACKEND_APP_NAME }}" --output json | jq -r '.status.url' | head -1) | |
| if [ -n "$BACKEND_URL" ]; then | |
| echo "Testing backend at: $BACKEND_URL/health" | |
| if curl -f -s "$BACKEND_URL/health" > /dev/null; then | |
| echo "✅ Backend health check passed" | |
| else | |
| echo "❌ Backend health check failed" | |
| exit 1 | |
| fi | |
| else | |
| echo "❌ Could not determine backend URL" | |
| exit 1 | |
| fi | |
| - name: Test Frontend Health | |
| run: | | |
| FRONTEND_URL=$(ibmcloud ce app get --name "${{ env.FRONTEND_APP_NAME }}" --output json | jq -r '.status.url' | head -1) | |
| if [ -n "$FRONTEND_URL" ]; then | |
| echo "Testing frontend at: $FRONTEND_URL" | |
| if curl -f -s "$FRONTEND_URL" > /dev/null; then | |
| echo "✅ Frontend health check passed" | |
| else | |
| echo "❌ Frontend health check failed" | |
| exit 1 | |
| fi | |
| else | |
| echo "❌ Could not determine frontend URL" | |
| exit 1 | |
| fi | |
| - name: Test Application Integration | |
| run: | | |
| BACKEND_URL=$(ibmcloud ce app get --name "${{ env.BACKEND_APP_NAME }}" --output json | jq -r '.status.url' | head -1) | |
| FRONTEND_URL=$(ibmcloud ce app get --name "${{ env.FRONTEND_APP_NAME }}" --output json | jq -r '.status.url' | head -1) | |
| echo "✅ Complete application deployed successfully!" | |
| echo "Backend URL: $BACKEND_URL" | |
| echo "Frontend URL: $FRONTEND_URL" | |
| echo "Application is ready for use!" |