CI/CD para Salesforce: Automatización de Despliegues
Implementación completa de pipelines CI/CD para Salesforce usando GitHub Actions, SFDX CLI y Scratch Orgs. Incluye mejores prácticas y troubleshooting.
Automatización de Despliegues

1. La Filosofía: El Desarrollador al Mando
Nuestro flujo principal es manual, basado en workflow_dispatch:
on:
workflow_dispatch:
inputs:
action:
description: 'Acción a ejecutar (Deploy o Validate)'
required: true
default: 'Validate'
environment:
description: 'Entorno de destino'
required: true
default: 'develop'
testLevel:
description: 'Nivel de testing'
required: true
default: 'RunLocalTests'
Ventajas:
- ✅ Control total por el desarrollador
- ✅ Evita despliegues automáticos no intencionados
- ✅ Mejora la trazabilidad

2. Verificación y Estado del Pull Request
Verificamos que el PR exista y que esté limpio (CLEAN):
PR_STATE=$(gh pr list --head $GITHUB_REF_NAME --json state --jq '.[0].state')
Objetivo: garantizar que el cambio ha sido revisado y es integrable sin conflictos.
3. Sincronización y Fusión
- name: Merge target branch into current
run: git merge origin/$TARGET_BRANCH
Esto garantiza que probamos sobre el código actualizado de la rama destino (ej: develop).
4. Generación de Paquetes Delta Inteligentes
¿Por qué despliegue incremental?
En proyectos grandes, desplegar todo el metadata puede ser extremadamente lento. Nuestra estrategia delta solo despliega componentes modificados, reduciendo tiempos de horas a minutos.
Implementación con sfdx-git-delta
# Crear paquetes delta para metadata nuevo, modificado o eliminado
branch="$GITHUB_REF"
environment_branch="origin/$TARGET_BRANCH"
mkdir $CHANGE_SOURCE
sfdx sgd:source:delta --to="$branch" --from $(git merge-base "$branch" "$environment_branch") \
--output changed-sources/ --generate-delta --source force-app/ --ignore scripts/CI/.deltaignore
# Verificar contenido generado
echo "========== package.xml =========="
cat "changed-sources/package/package.xml"
echo "========== destructiveChanges.xml =========="
cat "changed-sources/destructiveChanges/destructiveChanges.xml"
Archivos generados:
package.xml: Componentes añadidos/modificadosdestructiveChanges.xml: Componentes eliminados.deltaignore: Archivos a omitir (estáticos, configuraciones CI)
Ventajas:
- ⏩ Solo se despliega lo que cambió
- 🔎 Máxima visibilidad con
package.xml - ⚖️ Compatible con
.deltaignore - 🚀 Evita efectos colaterales en componentes no relacionados

5. Estrategia de Testing Selectiva con RunSpecifiedTests
El Problema: Cobertura vs Velocidad
Salesforce exige 75% de cobertura promedio para producción. Con RunLocalTests esto se basa en el promedio global, pero con RunSpecifiedTests cada clase del paquete debe alcanzar 75% individualmente - un criterio más estricto pero que garantiza calidad.
Selección Inteligente de Pruebas
1. Mapeo CSV de Clases a Tests
Clase,ClaseDeTest
MyService,MyServiceTest
UserUtil,UserUtilTest
TriggerHandler,TriggerHandlerTest
2. Determinación Automática de Tests
- name: Get Apex Tests
if: env.METADATA_CHANGES == 'yes'
run: |
TESTS="$INPUT_APEX_TESTS"
BASE_PATH="scripts/CI/"
folder_path="changed-sources/force-app/main/default/classes"
if [ "$TEST_LEVEL" == "Run all specified tests" ]; then
TESTS=$(node "${BASE_PATH}getAllTests.js" "$SKIP_TESTS")
elif [ -z "$TESTS" ] && test -f "${BASE_PATH}getTestsToRun.js"; then
TESTS=$(node "${BASE_PATH}getTestsToRun.js" "${folder_path}")
fi
echo "APEX_TESTS=$TESTS" >> $GITHUB_ENV
3. Comando de Despliegue con Tests Específicos
sfdx force:source:deploy -u $TARGET_ORG -x changed-sources/package/package.xml \
-l RunSpecifiedTests -r "$APEX_TESTS"
Ventajas de RunSpecifiedTests:
- 📊 Criterio más estricto: Cada clase nueva debe tener 75% cobertura
- ⚡ Testing más rápido: Solo tests relevantes
- 🎯 Precisión: Tests específicos para cambios reales
- 🛡️ Calidad: Evita que código con baja cobertura “se cuele” bajo promedio global
Beneficios adicionales:
- 📊 Testing más rápido
- 🌐 Tests independientes por paquete
- 🧳 Precisión por cambios reales
6. Barreras de Seguridad Adicionales
checkDeploymentAllowed.sh: Validaciones según horario, entorno y reglas corporativas.- Reintentos en el estado del PR:
while [ $attempt -le 3 ]; do
pr_state=$(gh pr list --head $GITHUB_REF_NAME --json state --jq '.[0].state')
[ "$pr_state" != "UNKNOWN" ] && break
sleep 5; ((attempt++))
done
7. Monitoreo Continuo y Ejecuciones Programadas
Ejecuciones Completas Periódicas
Aunque usamos tests selectivos en cada despliegue, ejecutamos verificaciones completas programadas:
# workflow: run_all_tests.yaml
schedule:
- cron: '0 2 * * *' # Todas las noches a las 2 AM
Esto nos da:
- 🔄 Verificación continua de la base de código completa
- 🚨 Detección temprana de regresiones inesperadas
- 📊 Reporte de cobertura global actualizado
8. Notificaciones y Cierre del Ciclo
Integración con Comunicaciones
- 💬 Webhooks Slack/Teams: Notificaciones automáticas de estado
- 🔗 Enlaces directos: Links a PR, ejecución y logs
- 📈 Métricas de cobertura: Reporte de texto con líneas cubiertas
Auto-merge Inteligente
- ✅ Merge automático si despliegue exitoso
- 🔄 Alineación de ramas sin intervención manual
- 🚨 Alertas inmediatas en caso de fallos

9. Resultados y Métricas
Mejoras Cuantificables
- Tiempo de despliegue: De horas a minutos
- Cobertura de código: 75% garantizado por componente (no solo promedio)
- Calidad: Criterio más estricto evita regresión de calidad
- Eficiencia: Menos tests ejecutados, mayor precisión
Casos de Uso
- 🟢 Desarrollo: NoTestRun para velocidad
- 🟡 Staging: RunSpecifiedTests para validación
- 🔴 Producción: RunSpecifiedTests obligatorio
Conclusión
Nuestra estrategia combina velocidad y calidad mediante:
📦 Despliegues delta: Solo cambios relevantes
🧪 Testing selectivo: RunSpecifiedTests con criterio estricto de 75% por clase
🔄 Monitoreo continuo: Ejecuciones programadas para verificación global
🤖 Automatización inteligente: Selección automática de tests vía mapeo CSV
Este pipeline CI/CD es una herramienta clave en nuestra cultura DevOps para Salesforce. Nos permite entregar con confianza, auditar con facilidad y mejorar continuamente.
🚀 Automatizado, pero bajo control.
💡 Rápido, pero seguro.
😎 Eficiente, pero transparente.
Referencias
Configuración basada en mejores prácticas de Salesforce y herramientas de la comunidad como sfdx-git-delta para despliegues incrementales y uso avanzado del parámetro testLevel del Metadata API.
Artículos Relacionados
Salesforce Destacado Query Plan Architecture: Patrón para Triggers Apex
Descubre cómo estructurar triggers complejos en Salesforce con el patrón Query Plan Architecture. Separa la lógica en 4 fases (Collect, Load, Run, Commit) para eliminar SOQL duplicados, respetar governor limits y facilitar el testing.
Salesforce Bulk DML Service Pattern: Operaciones DML Parciales en Salesforce
Documentación técnica completa del framework Bulk DML Service Pattern para Salesforce. Aprende a realizar operaciones DML resilientes con éxito parcial usando una API familiar estilo Unit of Work.
Salesforce Arquitectura Salesforce con FFLib: Patrones Enterprise
Guía completa sobre la implementación de patrones arquitectónicos enterprise en Salesforce utilizando FFLib. Incluye Domain Layer, Selector Layer, Service Layer y Unit of Work.