🎯 El Desafío de los Deployments Manuales
Imagina el proceso tradicional de deployment:
1. Developer hace cambios → 10 min
2. Run tests localmente → 5 min
3. Fix issues → 15 min
4. Build Docker image → 5 min
5. Push a Docker Hub → 3 min
6. SSH a servidor → 2 min
7. Pull nueva imagen → 2 min
8. Restart servicio → 1 min
9. Verificar deployment → 3 min
10. Rollback si falla → 10 min
TOTAL: 56 minutos + posibilidad de error humano
Problemas:
- ⏱️ Tiempo desperdiciado: 1 hora por deploy
- 🐛 Errores humanos: Olvidar un paso, typo en comando
- 📝 Sin tracking: ¿Quién deployó qué, cuándo?
- 🔄 Inconsistencia: Diferentes procesos por developer
- 🚨 Sin rollback fácil: Revertir requiere proceso manual
📊 La Magnitud del Problema
Requisitos de CI/CD Moderno
- ✅ Quality Gates: Tests, linting, security scan automáticos
- 🏗️ Build Automation: Docker images con cada cambio
- 📦 Artifact Management: Versionado y storage de images
- 🚀 Auto Deployment: Deploy a staging/prod automático
- 🔍 Validation: Health checks post-deployment
- 📊 Notifications: Alertas de successes/failures
- 🔄 Rollback: Fácil volver a versión anterior
- 🔐 Secrets Management: API keys, credentials seguros
7 Workflows del Proyecto
# | Workflow | Trigger | Propósito | Duración |
---|---|---|---|---|
1 | code-quality.yml | Push/PR | Tests, linting, security | 3-5 min |
2 | docker-processing-build-publish.yml | Push/Manual | Build processing image | 4-6 min |
3 | docker-api-build-publish.yml | Push/Manual | Build API image | 5-7 min |
4 | terraform-apply-on-tf-change.yml | Push .tf files | Apply infra changes | 3-8 min |
5 | deploy-qdrant.yml | Manual/Push | Deploy Qdrant to VM | 5-10 min |
6 | update-batch-job-image.yml | Manual | Update batch job image | 2-3 min |
7 | update-api-secrets-deploy.yml | Manual | Update secrets + deploy API | 3-5 min |
💡 La Solución: GitHub Actions
¿Qué es GitHub Actions?
GitHub Actions es una plataforma de CI/CD integrada en GitHub que permite:
- 🤖 Automatización: Workflows como código (YAML)
- ⚡ Trigger flexible: Push, PR, schedule, manual
- 🔧 Actions marketplace: Miles de actions reutilizables
- 🔐 Secrets management: Secrets encriptados integrados
- 📊 Logging: Logs detallados de cada ejecución
- 💰 Free tier: 2000 minutos/mes para repos públicos
Arquitectura de un Workflow
name: Mi Workflow # Nombre del workflow
on: [push, pull_request] # Triggers
jobs: # Jobs (paralelos por defecto)
build: # Job 1
runs-on: ubuntu-latest # Runner
steps: # Steps (secuenciales)
- uses: actions/checkout@v4 # Action del marketplace
- run: echo "Hello" # Comando shell
- name: Build
run: docker build -t app . # Step con nombre
🚀 Workflow 1: Code Quality & Style
Archivo .github/workflows/code-quality.yml
:
name: Code Quality & Style
on:
push:
branches: ['**']
paths:
- 'src/**/*.py'
- 'utils/**/*.py'
- 'tests/**/*.py'
- '.pre-commit-config.yaml'
- 'pyproject.toml'
pull_request:
branches: ['**']
paths:
- 'src/**/*.py'
- 'utils/**/*.py'
jobs:
# Job 1: Pre-commit hooks
pre-commit:
name: Pre-Commit Hooks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install UV
uses: astral-sh/setup-uv@v6
with:
version: latest
- name: Install pre-commit
run: uv tool install pre-commit
- name: Cache pre-commit hooks
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
- name: Run pre-commit hooks
run: uv tool run pre-commit run --all-files --show-diff-on-failure
# Job 2: Lint API code
lint-api:
name: Lint API Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install UV
uses: astral-sh/setup-uv@v6
- name: Install ruff
run: uv tool install ruff
- name: Run ruff linter
run: uv tool run ruff check src/lus_laboris_api --output-format=github
# Job 3: Security scan
security-scan:
name: Security Scan (Bandit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install UV
uses: astral-sh/setup-uv@v6
- name: Install bandit
run: uv tool install bandit
- name: Run bandit security scan
run: uv tool run bandit -r src/ utils/ -f github
# Job 4: Type checking
type-check:
name: Type Checking (MyPy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install UV
uses: astral-sh/setup-uv@v6
- name: Install dependencies
run: |
cd src/lus_laboris_api
uv sync
- name: Run mypy
run: |
cd src/lus_laboris_api
uv run mypy api/ --ignore-missing-imports
# Job 5: Tests
test-api:
name: API Tests (PyTest)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install UV
uses: astral-sh/setup-uv@v6
- name: Install dependencies
run: |
cd src/lus_laboris_api
uv sync
- name: Run tests with coverage
run: |
cd src/lus_laboris_api
uv run pytest tests/ --cov=api --cov-report=term --cov-report=html
- name: Upload coverage reports
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: src/lus_laboris_api/htmlcov/
Quality Gates:
- ✅ Pre-commit: Formatting, trailing whitespace, YAML syntax
- ✅ Linting: Ruff (10-100x más rápido que flake8)
- ✅ Security: Bandit detecta vulnerabilidades
- ✅ Type safety: MyPy valida type hints
- ✅ Tests: PyTest con coverage report
Triggers:
- Push a cualquier branch que toque Python files
- Pull requests
Resultado: Si algún job falla → PR bloqueado → Fix required
🐳 Workflows 2-3: Docker Build & Publish
Workflow 2: Processing Image
Archivo .github/workflows/docker-processing-build-publish.yml
:
name: Build & Publish Docker Image (Processing)
on:
workflow_dispatch:
push:
paths:
- 'src/processing/Dockerfile'
- 'src/processing/extract_law_text.py'
- 'src/processing/pyproject.toml'
- 'src/processing/.python-version'
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Get date tag
id: date_tag
run: echo "tag=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v6
with:
context: ./src/processing
push: true
tags: |
${{ secrets.DOCKER_HUB_USERNAME }}/lus-laboris-processing:latest
${{ secrets.DOCKER_HUB_USERNAME }}/lus-laboris-processing:${{ steps.date_tag.outputs.tag }}
Workflow 3: API Image
Similar a workflow 2, pero para src/lus_laboris_api/
Ventajas:
- ✅ Automated tagging:
latest
+ fecha (20241016
) - ✅ Trigger smart: Solo rebuild si Dockerfile o código cambia
- ✅ Buildx: Soporte multi-platform (AMD64, ARM64)
- ✅ Registry caching: Reutiliza layers de builds anteriores
🏗️ Workflow 4: Terraform Apply
Archivo .github/workflows/terraform-apply-on-tf-change.yml
:
name: Terraform Apply on TF Change
on:
push:
paths:
- 'terraform/**/*.tf'
- 'terraform/**/*.tfvars'
workflow_dispatch:
jobs:
terraform:
runs-on: ubuntu-latest
env:
GOOGLE_APPLICATION_CREDENTIALS: gcp-key.json
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.9.0
- name: Create GCP credentials file
run: |
echo '${{ secrets.GSA_KEY }}' > gcp-key.json
- name: Create terraform.tfvars
working-directory: ./terraform
run: |
# Generate tfvars from GitHub secrets/variables
cat > terraform.tfvars <<EOF
project_id = "${{ secrets.GCP_PROJECT_ID }}"
region = "${{ secrets.GCP_REGION }}"
bucket_name = "${{ vars.GCP_BUCKET_NAME }}"
# ... (más variables)
EOF
- name: Terraform Init
working-directory: ./terraform
run: terraform init
- name: Terraform Validate
working-directory: ./terraform
run: terraform validate
- name: Terraform Plan
working-directory: ./terraform
run: terraform plan -out=tfplan
- name: Terraform Apply
working-directory: ./terraform
run: terraform apply -auto-approve tfplan
- name: Show Outputs
working-directory: ./terraform
run: terraform output -json
Triggers:
- Cambios en cualquier archivo
.tf
o.tfvars
- Manual via workflow_dispatch
Proceso:
- ✅ Checkout código
- ✅ Setup Terraform
- ✅ Create credentials file
- ✅ Generate terraform.tfvars dinámicamente
- ✅ Init → Validate → Plan → Apply
- ✅ Show outputs (IPs, URLs)
Resultado: Infraestructura actualizada automáticamente en 3-8 minutos
🗄️ Workflow 5: Deploy Qdrant to VM
Archivo .github/workflows/deploy-qdrant.yml
:
name: Deploy Qdrant to GCP VM
on:
workflow_dispatch:
push:
paths:
- 'services/vectordb/**'
- 'terraform/modules/compute_engine/**'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Authenticate to GCP
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GSA_KEY }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Get VM details
id: vm_info
run: |
VM_EXTERNAL_IP=$(gcloud compute instances describe ${{ vars.GCP_COMPUTE_ENGINE_VM_NAME }} \
--zone=${{ vars.GCP_COMPUTE_ENGINE_VM_ZONE }} \
--format='get(networkInterfaces[0].accessConfigs[0].natIP)')
echo "vm_ip=${VM_EXTERNAL_IP}" >> $GITHUB_OUTPUT
- name: Install Docker on VM
run: |
gcloud compute ssh ${{ vars.GCP_COMPUTE_ENGINE_VM_NAME }} \
--zone=${{ vars.GCP_COMPUTE_ENGINE_VM_ZONE }} \
--command="
# Install Docker if not exists
if ! command -v docker &> /dev/null; then
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker \$USER
fi
# Install Docker Compose
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-\$(uname -s)-\$(uname -m) \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
"
- name: Deploy Qdrant
run: |
# Copy docker-compose.yml
gcloud compute scp services/vectordb/docker-compose.yml \
${{ vars.GCP_COMPUTE_ENGINE_VM_NAME }}:~/docker-compose.yml \
--zone=${{ vars.GCP_COMPUTE_ENGINE_VM_ZONE }}
# Create .env with API key
gcloud compute ssh ${{ vars.GCP_COMPUTE_ENGINE_VM_NAME }} \
--zone=${{ vars.GCP_COMPUTE_ENGINE_VM_ZONE }} \
--command="
echo 'QDRANT_API_KEY=${{ secrets.QDRANT_API_KEY }}' > ~/.env
# Start Qdrant
docker-compose up -d
# Wait and verify
sleep 10
curl -f http://localhost:6333/healthz || exit 1
"
- name: Verify deployment
run: |
curl -f http://${{ steps.vm_info.outputs.vm_ip }}:6333/collections
echo "✅ Qdrant deployed successfully at ${{ steps.vm_info.outputs.vm_ip }}"
Proceso:
- Get VM external IP
- Install Docker + Docker Compose (si no existe)
- Copy docker-compose.yml
- Create .env with API key
docker-compose up -d
- Verify health check
Resultado: Qdrant running en VM con persistencia en 5-10 minutos
🚀 Workflow 6: Update Batch Job Image
Archivo .github/workflows/update-batch-job-image.yml
:
name: Update Batch Job Image
on:
workflow_dispatch:
jobs:
update-job:
runs-on: ubuntu-latest
steps:
- name: Authenticate to GCP
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GSA_KEY }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Update Cloud Run Job image
run: |
IMAGE="${{ secrets.DOCKER_HUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME_PROCESSING }}:${{ vars.GCP_CLOUD_RUN_BATCH_IMAGE_TAG }}"
echo "🔄 Updating job image to: ${IMAGE}"
gcloud run jobs update ${{ vars.GCP_CLOUD_RUN_BATCH_JOB_NAME }} \
--image=${IMAGE} \
--region=${{ secrets.GCP_REGION }} \
--project=${{ secrets.GCP_PROJECT_ID }}
echo "✅ Job updated successfully!"
- name: Verify update
run: |
gcloud run jobs describe ${{ vars.GCP_CLOUD_RUN_BATCH_JOB_NAME }} \
--region=${{ secrets.GCP_REGION }} \
--project=${{ secrets.GCP_PROJECT_ID }} \
--format='value(template.template.containers[0].image)'
Uso:
- Build nueva imagen → Push a Docker Hub (workflow 2)
- Cambiar variable
GCP_CLOUD_RUN_BATCH_IMAGE_TAG
a nuevo tag - Ejecutar workflow 6 manualmente
- Job actualizado en 2-3 minutos
🚀 Workflow 7: Update API Secrets & Deploy
Archivo .github/workflows/update-api-secrets-deploy.yml
:
name: Update API Secrets & Deploy
on:
workflow_dispatch:
jobs:
update-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Authenticate to GCP
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GSA_KEY }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Update Secrets in Secret Manager
if: ${{ vars.GCP_CLOUD_SECRETS_UPDATE == 'true' }}
run: |
echo "📝 Updating secrets..."
# Update .env secret
echo "${{ secrets.API_ENV_FILE }}" | \
gcloud secrets versions add ${{ vars.GCP_CLOUD_SECRETS_API_ENV_ID }} \
--data-file=- \
--project=${{ secrets.GCP_PROJECT_ID }}
# Update JWT public key
echo "${{ secrets.JWT_PUBLIC_KEY }}" | \
gcloud secrets versions add ${{ vars.GCP_CLOUD_SECRETS_JWT_KEY_ID }} \
--data-file=- \
--project=${{ secrets.GCP_PROJECT_ID }}
echo "✅ Secrets updated"
- name: Deploy API to Cloud Run
run: |
IMAGE="${{ secrets.DOCKER_HUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME_RAG_API }}:${{ vars.GCP_CLOUD_RUN_API_IMAGE_TAG }}"
echo "🚀 Deploying ${IMAGE}..."
gcloud run deploy ${{ vars.GCP_CLOUD_RUN_API_SERVICE_NAME }} \
--image=${IMAGE} \
--region=${{ secrets.GCP_REGION }} \
--project=${{ secrets.GCP_PROJECT_ID }} \
--port=8000 \
--update-secrets="/app/secrets/env/.env=${{ vars.GCP_CLOUD_SECRETS_API_ENV_ID }}:latest,/app/secrets/jwt/public_key.pem=${{ vars.GCP_CLOUD_SECRETS_JWT_KEY_ID }}:latest" \
--cpu=${{ vars.GCP_CLOUD_RUN_API_CPU }} \
--memory=${{ vars.GCP_CLOUD_RUN_API_MEMORY }} \
--min-instances=${{ vars.GCP_CLOUD_RUN_API_MIN_INSTANCES }} \
--max-instances=${{ vars.GCP_CLOUD_RUN_API_MAX_INSTANCES }} \
--timeout=300 \
--allow-unauthenticated
echo "✅ API deployed!"
- name: Get Service URL
run: |
URL=$(gcloud run services describe ${{ vars.GCP_CLOUD_RUN_API_SERVICE_NAME }} \
--region=${{ secrets.GCP_REGION }} \
--format='value(status.url)' \
--project=${{ secrets.GCP_PROJECT_ID }})
echo "🌐 Service URL: ${URL}"
echo "📋 Health Check: ${URL}/api/health"
echo "📊 Swagger UI: ${URL}/docs"
Proceso completo:
- (Opcional) Update secrets en Secret Manager
- Deploy nueva versión de la imagen
- Cloud Run hace rolling update (zero downtime)
- Obtener URL del servicio
- Mostrar health check y Swagger endpoints
🎯 Flujo Completo de CI/CD
Escenario: Nuevo Feature
Developer:
├─ 1. Crea branch: feature/add-reranking
├─ 2. Escribe código: reranking_service.py
├─ 3. Commit & push
│
GitHub Actions (automático):
├─ 4. [Workflow 1] Code Quality
│ ├─ Pre-commit ✅
│ ├─ Linting ✅
│ ├─ Security scan ✅
│ ├─ Type check ✅
│ └─ Tests ✅
│
Developer:
├─ 5. Create Pull Request
│
GitHub:
├─ 6. PR shows all checks passed ✅
│
Team:
├─ 7. Code review
├─ 8. Approve PR
├─ 9. Merge to main
│
GitHub Actions (automático):
├─ 10. [Workflow 3] Build API image
│ └─ Push: username/api:latest + :20241016
│
Developer:
├─ 11. Update variable: GCP_CLOUD_RUN_API_IMAGE_TAG=20241016
│
GitHub Actions (manual):
├─ 12. [Workflow 7] Deploy API
│ ├─ Update secrets (optional)
│ ├─ Deploy to Cloud Run
│ └─ Verify health check ✅
│
Production:
└─ 13. New feature live! 🎉
Total time: 15-20 minutos (automático)
Manual steps: 5 (branch, commit, PR, merge, trigger deploy)
🧪 Testing Local con Act
¿Qué es Act?
Act permite ejecutar GitHub Actions workflows localmente con Docker:
# Instalar act
brew install act # macOS
# o
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
Script Interactivo: act_menu.sh
Archivo .github/workflows/act_menu.sh
:
#!/bin/bash
# Interactive menu for running GitHub Actions locally with act
echo "=========================================="
echo " GitHub Actions Local Testing"
echo "=========================================="
echo ""
echo "1) Code Quality"
echo "2) Build Processing Image"
echo "3) Build API Image"
echo "4) Terraform Apply"
echo "5) Exit"
echo ""
read -p "Select workflow [1-5]: " option
case $option in
1)
act -j pre-commit -j lint-api -j security-scan
;;
2)
act -j build-and-push-processing \
--secret-file ../../.env \
-W docker-processing-build-publish.yml
;;
3)
act -j build-and-push-api \
--secret-file ../../.env \
-W docker-api-build-publish.yml
;;
4)
act -j terraform \
--secret-file ../../.env \
-W terraform-apply-on-tf-change.yml
;;
5)
exit 0
;;
esac
Uso:
cd .github/workflows
chmod +x act_menu.sh
./act_menu.sh
Ventajas de Act:
- ✅ Test locally: Antes de push, verify workflow
- ✅ Faster iteration: No wait for GitHub runners
- ✅ Debug: Ver logs en tiempo real
- ✅ Cost: Zero (no consume GitHub Actions minutes)
🎯 Casos de Uso Reales
Para Continuous Integration:
"Quiero asegurar calidad de código en cada PR"
Solución:
- Workflow 1 (Code Quality) se ejecuta automáticamente
- PR no se puede mergear si hay fallos
- Code review con confianza de que quality checks pasaron
Para Continuous Deployment:
"Quiero deploy automático a staging en cada merge a main"
Solución:
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
steps:
# Build image
# Push to registry
# Deploy to Cloud Run (staging environment)
Para Rollback Rápido:
"La última versión tiene un bug crítico"
Solución:
# 1. Cambiar IMAGE_TAG a versión anterior
GCP_CLOUD_RUN_API_IMAGE_TAG=20241015 # Era 20241016
# 2. Ejecutar workflow 7
# GitHub Actions → Deploy versión anterior
# 3. Verificar
curl https://api-url/api/health
# ✅ Rollback en 3 minutos
Para Multi-Environment:
"Quiero deploy a dev, staging, prod con diferentes configs"
Solución:
# Workflow con matrix strategy
jobs:
deploy:
strategy:
matrix:
environment: [dev, staging, prod]
steps:
- name: Deploy to ${{ matrix.environment }}
run: |
gcloud run deploy api-${{ matrix.environment }} \
--image=... \
--set-env-vars="ENV=${{ matrix.environment }}"
🚀 El Impacto Transformador
Antes de GitHub Actions:
- ⏱️ Deploy time: 1 hora manual
- 🐛 Error rate: 20-30% (typos, pasos olvidados)
- 📝 Tracking: Notas en Slack, memoria
- 🔄 Rollback: 30-60 minutos manual
- 💰 Cost: Jenkins server ($50-100/mes)
- 🧪 Testing: "Esperemos que funcione en prod"
Después de GitHub Actions:
- ⚡ Deploy time: 15-20 minutos automático
- ✅ Error rate: <5% (proceso automatizado)
- 📊 Tracking: Cada deploy en Git + GitHub UI
- 🔄 Rollback: 3 minutos (cambiar tag + trigger)
- 💰 Cost: $0 (free tier suficiente)
- 🧪 Testing: Tests obligatorios antes de merge
Métricas de Mejora:
Aspecto | Manual | Con GitHub Actions | Mejora |
---|---|---|---|
Deploy time | 60 min | 15 min | -75% |
Error rate | 25% | <5% | -80% |
Deploy frequency | 1-2/semana | 10-20/semana | +900% |
Rollback time | 30-60 min | 3 min | -95% |
Time to production | Días | Horas | -90% |
💡 Lecciones Aprendidas
1. Separate Workflows > Monolithic
7 workflows pequeños y específicos > 1 workflow gigante. Más fácil debug y maintain.
2. Secrets vs Variables
- Secrets: API keys, passwords (encriptados)
- Variables: Config pública (service names, regions)
3. Manual Triggers son Poder
workflow_dispatch
permite control fino sobre deployments críticos.
4. Path Filters Ahorran Minutos
Solo ejecutar workflow si archivos relevantes cambiaron = menos tiempo desperdiciado.
5. Artifacts para Debugging
- uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov/
Útil para ver coverage reports, logs, etc.
6. Act para Desarrollo de Workflows
Desarrollar workflows con act localmente = 10x más rápido que push-wait-check en GitHub.
🎯 El Propósito Más Grande
GitHub Actions no es solo CI/CD - es calidad automatizada. Al automatizar:
- ✅ Quality: Tests obligatorios en cada cambio
- 🏗️ Build: Imágenes consistentes y versionadas
- 🚀 Deploy: Proceso reproducible y traceable
- 🔍 Visibility: Cada ejecución logged y auditable
- ⚡ Speed: De código a producción en minutos
- 🛡️ Safety: Quality gates previenen broken deploys
- 💰 Cost: Zero infrastructure, pay-per-use
- 👥 Collaboration: Workflows versionados = team aligned
Estamos convirtiendo el deployment de un proceso manual propenso a errores en un pipeline automatizado confiable que entrega valor a producción múltiples veces por día.
🔗 Recursos y Enlaces
Repositorio del Proyecto
- GitHub: lus-laboris-py
Documentación Técnica
-
Workflows Folder:
.github/workflows/
-
Code Quality:
.github/workflows/code-quality.yml
-
Docker API Build:
.github/workflows/docker-api-build-publish.yml
-
Terraform Apply:
.github/workflows/terraform-apply-on-tf-change.yml
-
Deploy Qdrant:
.github/workflows/deploy-qdrant.yml
-
Update API:
.github/workflows/update-api-secrets-deploy.yml
Recursos Externos
- GitHub Actions Docs: docs.github.com/actions
- Act (Local Testing): github.com/nektos/act
- Actions Marketplace: github.com/marketplace?type=actions
- Workflow Syntax: docs.github.com/actions/reference/workflow-syntax
Próximo Post: LLPY-14 - Evaluación y Métricas de Calidad
En el siguiente y último post de la serie, exploraremos cómo evaluar y medir la calidad del sistema RAG end-to-end, incluyendo ground truth datasets, métricas de retrieval y generation, LLM-as-a-judge evaluations, y monitoreo continuo en producción.
Top comments (0)