Skip to content

refactor: Restructure to true monorepo (apps/ + infrastructure/) #1

refactor: Restructure to true monorepo (apps/ + infrastructure/)

refactor: Restructure to true monorepo (apps/ + infrastructure/) #1

Workflow file for this run

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