CI/CD Pipeline #67
Workflow file for this run
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
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: patchpathregistry.azurecr.io | |
| IMAGE_NAME: patchpath-ai | |
| NODE_VERSION: '20' | |
| jobs: | |
| # Job 1: Lint and Test | |
| test: | |
| name: Test & Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run linter | |
| run: npm run lint | |
| - name: Type check | |
| run: npx tsc --noEmit | |
| - name: Build application | |
| run: npm run build | |
| env: | |
| NEXT_TELEMETRY_DISABLED: 1 | |
| # Job 2: Build and Push Docker Image | |
| build-and-push: | |
| name: Build & Push Docker Image | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| outputs: | |
| image-tag: ${{ steps.meta.outputs.tags }} | |
| image-digest: ${{ steps.build.outputs.digest }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Azure Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ secrets.AZURE_REGISTRY_USERNAME }} | |
| password: ${{ secrets.AZURE_REGISTRY_PASSWORD }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache | |
| cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max | |
| build-args: | | |
| NODE_ENV=production | |
| - name: Image summary | |
| run: | | |
| echo "### Docker Image Built! 🐳" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Registry:** ${{ env.REGISTRY }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Image:** ${{ env.IMAGE_NAME }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Tags:**" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "**Digest:** ${{ steps.build.outputs.digest }}" >> $GITHUB_STEP_SUMMARY | |
| # Job 3: Deploy to Azure Container Apps (placeholder - requires #20) | |
| deploy: | |
| name: Deploy to Azure | |
| runs-on: ubuntu-latest | |
| needs: build-and-push | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| environment: | |
| name: production | |
| url: https://patchpath.azurecontainerapps.io | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Azure Login | |
| uses: azure/login@v2 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Deploy to Azure Container Apps | |
| run: | | |
| echo "🚀 Deployment to Azure Container Apps" | |
| echo "⚠️ Note: This requires Azure Container App to be created first (Issue #20)" | |
| echo "" | |
| echo "Deployment command will be:" | |
| echo "az containerapp update \\" | |
| echo " --name patchpath-app \\" | |
| echo " --resource-group patchpath-rg \\" | |
| echo " --image ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" | |
| echo "" | |
| echo "Skipping actual deployment until Container App exists..." | |
| - name: Deployment summary | |
| run: | | |
| echo "### Deployment Status 🚀" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Status:** Ready for deployment" >> $GITHUB_STEP_SUMMARY | |
| echo "**Image:** ${{ needs.build-and-push.outputs.image-tag }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "⚠️ **Action Required:** Complete Issue #20 to enable automatic deployment" >> $GITHUB_STEP_SUMMARY | |
| # Job 4: Security Scan (Optional but recommended) | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| needs: build-and-push | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Log in to Azure Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ secrets.AZURE_REGISTRY_USERNAME }} | |
| password: ${{ secrets.AZURE_REGISTRY_PASSWORD }} | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| - name: Upload Trivy results to GitHub Security | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| - name: Security summary | |
| run: | | |
| echo "### Security Scan Complete 🔒" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Vulnerability scan completed. Check Security tab for results." >> $GITHUB_STEP_SUMMARY |