Automatización de deploys con GitHub Actions para WordPress
Imagina que cada cambio en tu repositorio de WordPress se despliega automáticamente en producción sin intervención manual, sin riesgos de error humano y con un registro impecable de cada versión. Eso es exactamente lo que consigues con GitHub Actions. En este artículo, vamos a construir un pipeline de CI/CD WordPress completo, desde el commit hasta el servidor, usando exclusivamente GitHub Actions.
Si eres desarrollador o sysadmin, sabes que mantener un WordPress actualizado y estable es un reto. Entre plugins, temas y el núcleo, cualquier cambio mal sincronizado puede romper el sitio. La automatización de deploys con GitHub Actions WordPress no solo acelera el proceso, sino que lo vuelve predecible y auditable.
A continuación, desglosamos cómo implementar un flujo DevOps real para WordPress, con ejemplos prácticos, configuraciones YAML y buenas prácticas para que tu WordPress pipeline sea robusto y eficiente.
¿Por qué necesitas un pipeline CI/CD para WordPress?
El desarrollo tradicional de WordPress suele ser caótico: editas archivos directamente en producción, usas FTP o plugins de sincronización que a menudo fallan. Con un enfoque DevOps, introduces control de versiones, pruebas automatizadas y despliegues repetibles.
Beneficios clave de la automatización de deploys:
- Consistencia: Cada deploy sigue exactamente los mismos pasos, eliminando desviaciones.
- Velocidad: Pasar de un commit a producción en minutos, no horas.
- Seguridad: Nunca tocas el servidor directamente; todo pasa por el pipeline.
- Rollback inmediato: Si algo falla, puedes revertir a una versión anterior con un solo clic.
- Auditoría: Cada cambio queda registrado en los logs de GitHub Actions.
[INFO] No confundas CI/CD con simple sincronización de archivos. CI/CD incluye pruebas, compilación y validación antes del deploy. Es un proceso completo, no solo copiar archivos.
Componentes esenciales de un WordPress pipeline
Antes de escribir código, necesitas entender los actores de este flujo:
- Repositorio Git (GitHub): Almacena todo el código: temas, plugins, archivos de configuración (wp-config.php, .htaccess, etc.).
- GitHub Actions: Orquesta el pipeline. Se ejecuta en máquinas virtuales (runners) que GitHub proporciona.
- Servidor de destino: Puede ser un VPS, un hosting compartido con SSH, o un servicio como AWS, DigitalOcean, etc.
- Secrets de GitHub: Almacena credenciales como claves SSH, tokens de API o contraseñas de base de datos.
Flujo típico de un pipeline CI/CD WordPress
- Commit en la rama
mainoproduction. - Trigger de GitHub Actions.
- Checkout del código.
- Instalación de dependencias (composer, npm si usas preprocesadores).
- Pruebas (PHP lint, comprobación de plugins, validación de assets).
- Build (compilar CSS/JS, minificar, optimizar imágenes).
- Deploy (subir archivos vía rsync/SSH, ejecutar migraciones de BD si aplica).
- Notificación (Slack, email, o comentario en el PR).
Configuración paso a paso del pipeline con GitHub Actions
1. Preparar tu repositorio
Estructura recomendada para el repositorio de WordPress:
/
├── .github/
│ └── workflows/
│ └── deploy.yml
├── wp-content/
│ ├── themes/
│ │ └── tu-tema/
│ └── plugins/
├── wp-config.php
├── composer.json (opcional)
└── package.json (opcional)
[TIP] No incluyas el núcleo de WordPress (wp-admin, wp-includes) en el repositorio. Es mejor gestionarlo aparte o usando Composer. Tu repositorio debe contener solo tu código personalizado.
2. Crear el workflow YAML
Crea el archivo .github/workflows/deploy.yml con el siguiente contenido base:
name: Deploy WordPress
on:
push:
branches:
- main
- production
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout del código
uses: actions/checkout@v4
- name: Configurar PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- name: Instalar dependencias (Composer)
run: composer install --no-dev --optimize-autoloader
if: hashFiles('composer.json') != ''
- name: Compilar assets (si usas npm)
run: |
npm ci
npm run build
if: hashFiles('package.json') != ''
- name: Lint PHP
run: find wp-content -name "*.php" -exec php -l {} \;
- name: Sincronizar archivos al servidor (rsync)
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET_DIR: ${{ secrets.TARGET_DIR }}
run: |
mkdir -p ~/.ssh
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H $REMOTE_HOST >> ~/.ssh/known_hosts
rsync -avz --delete --exclude='.git' --exclude='.github' \
--exclude='node_modules' --exclude='vendor' \
./ $REMOTE_USER@$REMOTE_HOST:$TARGET_DIR/
3. Explicación de cada paso
- Checkout: Descarga el código del repositorio.
- Setup PHP: Configura la versión de PHP que usará el runner para validaciones.
- Composer: Instala dependencias de PHP (plugins, temas gestionados con Composer).
- Build: Compila assets si usas preprocesadores (Sass, Webpack, etc.).
- Lint: Verifica que no haya errores de sintaxis PHP.
- Rsync: Sincroniza los archivos al servidor remoto vía SSH, eliminando archivos obsoletos (
--delete).
[WARNING] El flag
--deleteen rsync es peligroso si no excluyes correctamente carpetas comowp-content/uploads. Asegúrate de queuploads/esté en el servidor pero no en el repositorio, y exclúyelo explícitamente en el comando rsync.
4. Configurar los Secrets en GitHub
Ve a Settings > Secrets and variables > Actions de tu repositorio y añade:
SSH_PRIVATE_KEY: La clave privada SSH (sin passphrase) que tiene acceso al servidor.REMOTE_HOST: IP o dominio del servidor.REMOTE_USER: Usuario SSH (ej:deploy,root,www-data).TARGET_DIR: Ruta absoluta en el servidor donde está WordPress (ej:/var/www/html).
[INFO] Nunca pongas credenciales en el código. GitHub Actions las inyecta como variables de entorno de forma segura.
Mejoras avanzadas para tu pipeline CI/CD WordPress
a) Despliegue condicional por ramas
Puedes tener diferentes entornos (dev, staging, production) usando la misma acción pero con distintos secretos:
on:
push:
branches:
- develop
- staging
- main
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.ref_name == 'main' && 'production' || 'staging' }}
Luego defines entornos en GitHub con sus propios secrets (ej: REMOTE_HOST_STAGING, REMOTE_HOST_PRODUCTION).
b) Ejecutar migraciones de base de datos
Si usas un plugin como WP Migrate DB Pro o tienes scripts SQL, puedes ejecutarlos después del deploy:
- name: Ejecutar migraciones
run: |
ssh $REMOTE_USER@$REMOTE_HOST "cd $TARGET_DIR && wp db migrate"
if: github.ref == 'refs/heads/main'
[TIP] La herramienta WP-CLI es tu mejor aliada. Instálala en el servidor y úsala desde el pipeline para tareas como actualizar plugins, limpiar caché o cambiar URLs.
c) Notificaciones y alertas
Integra notificaciones para saber si el deploy fue exitoso o falló:
- name: Notificar éxito
if: success()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": "✅ Deploy exitoso a producción desde ${{ github.sha }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
- name: Notificar fallo
if: failure()
run: echo "Deploy falló. Revisa los logs."
d) Cache de dependencias para acelerar el pipeline
- name: Cache Composer
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-
- name: Cache npm
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Errores comunes y cómo evitarlos
❌ Subir archivos sensibles (wp-config.php con credenciales)
Solución: Usa variables de entorno en el servidor o un archivo .env que no esté versionado. En el pipeline, puedes generar el wp-config.php dinámicamente desde secrets.
❌ Olvidar excluir wp-content/uploads
Solución: Añade --exclude='wp-content/uploads' al comando rsync. Las imágenes subidas por usuarios no deben estar en el repositorio.
❌ Permisos incorrectos en el servidor
Solución: Después del rsync, ejecuta un comando SSH para ajustar permisos:
- name: Ajustar permisos
run: |
ssh $REMOTE_USER@$REMOTE_HOST "chown -R www-data:www-data $TARGET_DIR && find $TARGET_DIR -type d -exec chmod 755 {} \; && find $TARGET_DIR -type f -exec chmod 644 {} \;"
❌ No probar antes de desplegar
Solución: Añade un paso de pruebas unitarias o de integración. Por ejemplo, con PHPUnit si tu tema/plugin tiene tests.
Conclusión: De despliegues manuales a DevOps real
La automatización de deploys con GitHub Actions WordPress transforma la forma en que gestionas tu sitio. Dejas atrás el FTP, los errores por subir el archivo equivocado y las noches sin dormir por un deploy fallido.
Implementar un WordPress pipeline no solo es técnicamente factible, sino que es una inversión que paga dividendos en tiempo, seguridad y tranquilidad. Empieza con un pipeline simple como el que hemos visto, y ve añadiendo capas de complejidad según tu proyecto lo requiera: tests, múltiples entornos, notificaciones, etc.
[TIP] Si trabajas en equipo, define una rama
developpara integración continua ymainpara producción. Cada merge amaindispara el deploy automático. Así, nunca despliegas código sin revisión.
Ahora tienes el conocimiento y el código listo para implementar tu propio CI/CD WordPress. ¿A qué esperas para automatizar?
