academia/.gitea/workflows/deploy.yaml

143 lines
4.7 KiB
YAML

name: CI/CD Pipeline
on:
push:
branches: [main]
workflow_dispatch:
env:
K3S_HOST: "100.67.198.92"
K3S_USER: "andres"
NAMESPACE: "academia"
DOMAIN: "academia.ingeniumcodex.com"
jobs:
# Job 1: Build y Test (obligatorio)
test:
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
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.K3S_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ env.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Deploy to K3s
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
set -e
cd ~/academia
# Pull latest changes
git fetch origin main
git reset --hard origin/main
# Build 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 \
-f deploy/docker/Dockerfile.frontend -t student-frontend:latest . &
PID_FE=$!
wait $PID_API || exit 1
wait $PID_FE || exit 1
# Import 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 \
'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 \
deployment/student-api deployment/student-frontend -n academia
# Wait 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 \
deployment/student-frontend -n academia --timeout=60s
ENDSSH
# Job 3: Smoke Tests en Producción
smoke-tests:
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Wait for services
run: sleep 15
- name: Health Check API
run: |
response=$(curl -sf https://${{ env.DOMAIN }}/health)
echo "Health response: $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: GraphQL Endpoint 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"
echo "$response" | grep -q '"subjects"' || exit 1
# Job 4: Rollback automático si smoke tests fallan
rollback:
runs-on: ubuntu-latest
needs: smoke-tests
if: failure()
steps:
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.K3S_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ env.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Rollback Deployments
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout undo \
deployment/student-api deployment/student-frontend -n academia
ENDSSH