refactor: Restructure to true monorepo (apps/ + infrastructure/) #1
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: Build & Deploy to Cloud | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: # Manual trigger | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_PREFIX: ${{ github.repository_owner }}/taskflow | |
| jobs: | |
| # ============================================================================= | |
| # Build all Docker images and push to GHCR | |
| # ============================================================================= | |
| build-images: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| matrix: | |
| include: | |
| - name: api | |
| context: apps/api | |
| dockerfile: apps/api/Dockerfile | |
| - name: sso | |
| context: apps/sso | |
| dockerfile: apps/sso/Dockerfile | |
| - name: mcp-server | |
| context: apps/mcp-server | |
| dockerfile: apps/mcp-server/Dockerfile | |
| - name: notification-service | |
| context: apps/notification-service | |
| dockerfile: apps/notification-service/Dockerfile | |
| - name: web | |
| context: apps/web | |
| dockerfile: apps/web/Dockerfile | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GHCR | |
| 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_PREFIX }}/${{ matrix.name }} | |
| tags: | | |
| type=sha,prefix= | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ${{ matrix.context }} | |
| file: ${{ matrix.dockerfile }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # ============================================================================= | |
| # Deploy to Kubernetes cluster | |
| # ============================================================================= | |
| deploy: | |
| needs: build-images | |
| runs-on: ubuntu-latest | |
| environment: production | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up kubectl | |
| uses: azure/setup-kubectl@v3 | |
| with: | |
| version: 'v1.28.0' | |
| - name: Set up Helm | |
| uses: azure/setup-helm@v3 | |
| with: | |
| version: 'v3.13.0' | |
| # For Azure AKS | |
| - name: Azure Login | |
| if: ${{ vars.CLOUD_PROVIDER == 'azure' }} | |
| uses: azure/login@v1 | |
| with: | |
| creds: ${{ secrets.AZURE_CREDENTIALS }} | |
| - name: Get AKS credentials | |
| if: ${{ vars.CLOUD_PROVIDER == 'azure' }} | |
| run: | | |
| az aks get-credentials \ | |
| --resource-group ${{ vars.AZURE_RESOURCE_GROUP }} \ | |
| --name ${{ vars.AZURE_CLUSTER_NAME }} | |
| # For GKE | |
| - name: Authenticate to GKE | |
| if: ${{ vars.CLOUD_PROVIDER == 'gke' }} | |
| uses: google-github-actions/auth@v1 | |
| with: | |
| credentials_json: ${{ secrets.GCP_CREDENTIALS }} | |
| - name: Get GKE credentials | |
| if: ${{ vars.CLOUD_PROVIDER == 'gke' }} | |
| uses: google-github-actions/get-gke-credentials@v1 | |
| with: | |
| cluster_name: ${{ vars.GKE_CLUSTER_NAME }} | |
| location: ${{ vars.GKE_CLUSTER_ZONE }} | |
| # For any provider with kubeconfig | |
| - name: Set kubeconfig | |
| if: ${{ vars.CLOUD_PROVIDER == 'kubeconfig' }} | |
| run: | | |
| mkdir -p ~/.kube | |
| echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config | |
| chmod 600 ~/.kube/config | |
| - name: Add Dapr Helm repo | |
| run: | | |
| helm repo add dapr https://dapr.github.io/helm-charts/ | |
| helm repo update | |
| - name: Install/Upgrade Dapr | |
| run: | | |
| helm upgrade --install dapr dapr/dapr \ | |
| --version=1.15 \ | |
| --namespace dapr-system \ | |
| --create-namespace \ | |
| --wait | |
| - name: Create namespace | |
| run: kubectl create namespace taskflow --dry-run=client -o yaml | kubectl apply -f - | |
| - name: Create GHCR pull secret | |
| run: | | |
| kubectl create secret docker-registry ghcr-secret \ | |
| --namespace taskflow \ | |
| --docker-server=ghcr.io \ | |
| --docker-username=${{ github.actor }} \ | |
| --docker-password=${{ secrets.GITHUB_TOKEN }} \ | |
| --dry-run=client -o yaml | kubectl apply -f - | |
| - name: Deploy with Helm | |
| run: | | |
| helm upgrade --install taskflow ./infrastructure/helm/taskflow \ | |
| --namespace taskflow \ | |
| --values infrastructure/helm/taskflow/values-cloud.yaml \ | |
| --set global.imageRegistry="${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}" \ | |
| --set global.imageTag="${{ github.sha }}" \ | |
| --set global.imagePullSecrets[0].name=ghcr-secret \ | |
| --set managedServices.neon.enabled=true \ | |
| --set "managedServices.neon.ssoDatabase=${{ secrets.NEON_SSO_DATABASE_URL }}" \ | |
| --set "managedServices.neon.apiDatabase=${{ secrets.NEON_API_DATABASE_URL }}" \ | |
| --set "managedServices.neon.chatkitDatabase=${{ secrets.NEON_CHATKIT_DATABASE_URL }}" \ | |
| --set "managedServices.neon.notificationDatabase=${{ secrets.NEON_NOTIFICATION_DATABASE_URL }}" \ | |
| --set managedServices.upstash.enabled=true \ | |
| --set "managedServices.upstash.host=${{ secrets.UPSTASH_REDIS_HOST }}" \ | |
| --set "managedServices.upstash.password=${{ secrets.UPSTASH_REDIS_PASSWORD }}" \ | |
| --set "managedServices.upstash.restUrl=${{ secrets.REDIS_URL }}" \ | |
| --set "managedServices.upstash.restToken=${{ secrets.REDIS_TOKEN }}" \ | |
| --set "sso.env.BETTER_AUTH_SECRET=${{ secrets.BETTER_AUTH_SECRET }}" \ | |
| --set "api.openai.apiKey=${{ secrets.OPENAI_API_KEY }}" \ | |
| --set notificationService.enabled=true \ | |
| --set dapr.enabled=true \ | |
| --set "global.domain=${{ vars.DOMAIN }}" \ | |
| --wait \ | |
| --timeout 10m | |
| - name: Verify deployment | |
| run: | | |
| echo "Checking pod status..." | |
| kubectl get pods -n taskflow | |
| echo "" | |
| echo "Checking services..." | |
| kubectl get svc -n taskflow | |
| echo "" | |
| echo "Checking ingress..." | |
| kubectl get ingress -n taskflow 2>/dev/null || echo "No ingress configured" | |
| - name: Post deployment URLs | |
| run: | | |
| echo "## Deployment Complete! :rocket:" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Service | URL |" >> $GITHUB_STEP_SUMMARY | |
| echo "|---------|-----|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Web Dashboard | https://${{ vars.DOMAIN }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| SSO Platform | https://sso.${{ vars.DOMAIN }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| API | https://api.${{ vars.DOMAIN }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Commit: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY |