From cfac85275bac8a59e99ccab64ba9ef1b1a60ae6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Eduardo=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Fri, 9 Jan 2026 07:47:54 -0500 Subject: [PATCH] ci: run tests and build on K3s server to avoid runner memory limits Strategy change: - Tests run directly on K3s server via SSH (has dotnet installed) - Docker build/import also on K3s server - Runner only handles SSH connection and smoke tests (lightweight) - Smoke tests run from runner (just curl commands) - Auto-rollback if smoke tests fail This avoids OOMKilled issues in the runner container. Co-Authored-By: Claude Opus 4.5 --- .gitea/workflows/deploy.yaml | 90 +++++++++++++++--------------------- 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index e8e88b5..56bff97 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -12,25 +12,9 @@ env: DOMAIN: "academia.ingeniumcodex.com" jobs: - # Job 1: Build y Test (obligatorio) - test: + # Job único: Build, Test y Deploy en K3s (más eficiente en recursos) + build-test-deploy: runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Restore & Build - run: dotnet build --configuration Release --verbosity minimal - - - name: Run Tests - run: | - dotnet test tests/Domain.Tests --no-build -c Release --verbosity minimal - dotnet test tests/Application.Tests --no-build -c Release --verbosity minimal - - # Job 2: Deploy (siempre después de tests) - deploy: - runs-on: ubuntu-latest - needs: test steps: - name: Checkout uses: actions/checkout@v4 @@ -42,22 +26,29 @@ jobs: chmod 600 ~/.ssh/id_rsa ssh-keyscan -H ${{ env.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null - - name: Deploy to K3s + - name: Build, Test & Deploy run: | ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH' set -e cd ~/academia # Pull latest changes + echo "=== Pulling latest code ===" git fetch origin main git reset --hard origin/main - # Build images - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S docker build \ + # Run tests (en el servidor que tiene más recursos) + echo "=== Running tests ===" + dotnet test tests/Domain.Tests --verbosity minimal || exit 1 + dotnet test tests/Application.Tests --verbosity minimal || exit 1 + + # Build Docker images + echo "=== Building images ===" + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S docker build \ -f deploy/docker/Dockerfile.api -t student-api:latest . & PID_API=$! - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S docker build \ + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S docker build \ -f deploy/docker/Dockerfile.frontend -t student-frontend:latest . & PID_FE=$! @@ -65,27 +56,30 @@ jobs: wait $PID_FE || exit 1 # Import to k3s - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S sh -c \ + echo "=== Importing to K3s ===" + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S sh -c \ 'docker save student-api:latest | k3s ctr images import -' - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S sh -c \ + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S sh -c \ 'docker save student-frontend:latest | k3s ctr images import -' # Deploy - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl apply -k deploy/k3s/ - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout restart \ + echo "=== Deploying ===" + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S kubectl apply -k deploy/k3s/ + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S kubectl rollout restart \ deployment/student-api deployment/student-frontend -n academia # Wait for rollout - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout status \ + echo "=== Waiting for rollout ===" + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S kubectl rollout status \ deployment/student-api -n academia --timeout=180s - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout status \ + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S kubectl rollout status \ deployment/student-frontend -n academia --timeout=60s ENDSSH - # Job 3: Smoke Tests en Producción + # Smoke Tests en Producción smoke-tests: runs-on: ubuntu-latest - needs: deploy + needs: build-test-deploy steps: - name: Wait for services run: sleep 15 @@ -93,35 +87,25 @@ jobs: - name: Health Check API run: | response=$(curl -sf https://${{ env.DOMAIN }}/health) - echo "Health response: $response" + echo "Health: $response" echo "$response" | grep -q '"status":"Healthy"' || exit 1 - - name: Health Check Frontend - run: | - curl -sf https://${{ env.DOMAIN }}/ | grep -q 'Sistema de Estudiantes' || exit 1 + - name: Frontend Check + run: curl -sf https://${{ env.DOMAIN }}/ | grep -q 'Sistema de Estudiantes' || exit 1 - - name: GraphQL Endpoint Check + - name: GraphQL Check run: | response=$(curl -sf -X POST https://${{ env.DOMAIN }}/graphql \ -H "Content-Type: application/json" \ - -d '{"query":"{ __typename }"}') - echo "GraphQL response: $response" - echo "$response" | grep -q '"data"' || exit 1 - - - name: Database Connectivity Check - run: | - response=$(curl -sf https://${{ env.DOMAIN }}/health) - echo "$response" | grep -q '"name":"database","status":"Healthy"' || exit 1 - - - name: Subjects Query Test - run: | - response=$(curl -sf -X POST https://${{ env.DOMAIN }}/graphql \ - -H "Content-Type: application/json" \ - -d '{"query":"{ subjects { id name credits } }"}') - echo "Subjects response: $response" + -d '{"query":"{ subjects { id name } }"}') + echo "GraphQL: $response" echo "$response" | grep -q '"subjects"' || exit 1 - # Job 4: Rollback automático si smoke tests fallan + - name: Database Check + run: | + curl -sf https://${{ env.DOMAIN }}/health | grep -q '"name":"database","status":"Healthy"' || exit 1 + + # Rollback si smoke tests fallan rollback: runs-on: ubuntu-latest needs: smoke-tests @@ -134,9 +118,9 @@ jobs: chmod 600 ~/.ssh/id_rsa ssh-keyscan -H ${{ env.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null - - name: Rollback Deployments + - name: Rollback run: | ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH' - echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout undo \ + echo '${{ secrets.K3S_SUDO_PASS }}' | sudo -S kubectl rollout undo \ deployment/student-api deployment/student-frontend -n academia ENDSSH