Automatización de CI/CD para WordPress con GitHub Actions
En el ecosistema moderno de desarrollo web, la velocidad y la fiabilidad son factores críticos para el éxito de cualquier proyecto. Para los sitios construidos con WordPress, que alimentan más del 40% de la web, la gestión manual de los despliegues se ha convertido en un cuello de botella insostenible. La integración de un pipeline de CI/CD (Integración Continua y Despliegue Continuo) es la respuesta, y GitHub Actions se presenta como la herramienta más accesible y potente para implementarlo sin salir de nuestro repositorio.
Este artículo es una guía exhaustiva para construir un flujo de CI/CD WordPress robusto. Abandonaremos los plugins de FTP y los pases de archivos manuales para abrazar un proceso automatizado, auditable y repetible que nos permitirá centrarnos en lo que realmente importa: escribir código de calidad.
¿Por qué necesitas un pipeline de CI/CD para WordPress?
Antes de sumergirnos en la configuración, es crucial entender el "por qué". Un sitio WordPress típico implica temas, plugins, archivos de configuración (wp-config.php) y, a menudo, un repositorio de Git. Sin automatización, el despliegue suele ser una combinación de:
- Subida manual por FTP/SFTP (proclive a errores humanos).
- Copias de seguridad inconsistentes.
- Falta de control de versiones en producción.
- Tiempo de inactividad durante las actualizaciones.
Un pipeline de DevOps WordPress resuelve esto mediante:
- Automatización del despliegue: Cada
pusha una rama (por ejemplo,mainodevelop) puede desencadenar un despliegue automático. - Pruebas automatizadas: Ejecutar pruebas unitarias, de integración y de linting antes de tocar el servidor en vivo.
- Consistencia: El mismo proceso se ejecuta cada vez, eliminando la variabilidad humana.
- Rollback rápido: Si algo falla, revertir un commit es más fácil que restaurar una copia de seguridad manual.
El enfoque Git-centric
La base de todo es tratar el sitio de WordPress como una aplicación. Esto significa que el tema, los plugins personalizados y la configuración esencial (como wp-config.php con variables de entorno) deben estar versionados en Git. Los archivos generados por WordPress (uploads, caché, logs) deben ser ignorados o gestionados externamente.
Configurando el repositorio para CI/CD
El primer paso es estructurar correctamente nuestro repositorio. Asumiremos un escenario común donde gestionamos un tema personalizado y algunos plugins.
mi-sitio-wordpress/
├── .github/
│ └── workflows/
│ └── deploy.yml
├── wp-content/
│ ├── themes/
│ │ └── mi-tema-personalizado/
│ │ ├── style.css
│ │ ├── functions.php
│ │ └── ...
│ └── plugins/
│ └── mi-plugin-personalizado/
├── .gitignore
└── README.md
[TIP] No incluyas el núcleo de WordPress en tu repositorio. Se puede descargar durante el pipeline o ya debe estar presente en el servidor de destino. Esto mantiene el repositorio ligero y evita conflictos de actualización.
El primer pipeline: Despliegue Básico con GitHub Actions
Vamos a crear nuestro primer flujo de trabajo. Este se encargará de, al hacer push a la rama main, conectar por SSH al servidor de producción y sincronizar los archivos de wp-content.
Crea el archivo .github/workflows/deploy.yml con el siguiente contenido:
name: Desplegar WordPress a Producción
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout del código
uses: actions/checkout@v4
- name: Configurar SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts
- name: Sincronizar archivos con rsync
run: |
rsync -avz --delete \
--exclude '.git' \
--exclude '.github' \
--exclude 'node_modules' \
--exclude 'wp-config.php' \
./wp-content/ \
${{ secrets.SSH_USER }}@${{ secrets.SERVER_IP }}:/ruta/absoluta/wp-content/
Explicación de los secretos
Este pipeline utiliza GitHub Secrets para almacenar información sensible. Debes agregarlos en tu repositorio: Settings > Secrets and variables > Actions.
SSH_PRIVATE_KEY: La clave privada SSH para conectarte al servidor (sin passphrase).SSH_USER: El usuario SSH del servidor.SERVER_IP: La IP o dominio del servidor.
[WARNING] Asegúrate de que la clave pública correspondiente esté agregada al archivo ~/.ssh/authorized_keys en tu servidor de destino. Sin esto, la conexión SSH fallará.
Añadiendo Pruebas Automatizadas al Pipeline
Un pipeline de CI/CD WordPress sin pruebas es simplemente un CD (Continuous Deployment) a ciegas. Integremos pruebas de linting para PHP y JavaScript, y ejecutemos pruebas unitarias básicas.
Paso 1: Linting con PHPCS y ESLint
Agregaremos pruebas de calidad de código antes del despliegue. Modifica tu deploy.yml para incluir un nuevo job llamado tests que se ejecute en paralelo o antes del deploy.
name: CI/CD WordPress Full
on:
push:
branches:
- main
- develop
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configurar PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: composer, phpcs
- name: Instalar dependencias de Composer (si tienes)
run: |
if [ -f "composer.json" ]; then
composer install --no-interaction --prefer-dist
fi
- name: Ejecutar PHP Code Sniffer (WordPress Coding Standards)
run: |
phpcs --standard=WordPress wp-content/themes/mi-tema-personalizado/
- name: Configurar Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Instalar dependencias de npm
run: |
if [ -f "package.json" ]; then
npm ci
fi
- name: Ejecutar ESLint
run: |
if [ -f ".eslintrc.json" ]; then
npx eslint wp-content/themes/mi-tema-personalizado/
fi
deploy:
needs: test # Este job solo se ejecuta si 'test' pasa
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # Solo despliega desde main
steps:
# ... (mismos pasos de despliegue que antes) ...
Paso 2: Pruebas Unitarias con PHPUnit
Para sitios más complejos, puedes ejecutar pruebas unitarias. Necesitarás una base de datos de prueba y WordPress instalado en el runner.
- name: Configurar MySQL
run: |
sudo systemctl start mysql
mysql -e "CREATE DATABASE IF NOT EXISTS wordpress_test;" -uroot -proot
mysql -e "CREATE USER 'wp'@'localhost' IDENTIFIED BY 'wp';" -uroot -proot
mysql -e "GRANT ALL PRIVILEGES ON wordpress_test.* TO 'wp'@'localhost';" -uroot -proot
- name: Instalar WordPress para pruebas
run: |
wp core download --path=/tmp/wordpress --allow-root
wp config create --dbname=wordpress_test --dbuser=wp --dbpass=wp --path=/tmp/wordpress --allow-root
wp core install --url=http://localhost --title=Test --admin_user=admin --admin_password=admin --admin_email=test@test.com --path=/tmp/wordpress --allow-root
- name: Ejecutar PHPUnit
run: |
cd wp-content/themes/mi-tema-personalizado
phpunit
[INFO] Este enfoque de pruebas espesas es ideal para temas y plugins que siguen el patrón de desarrollo TDD. No es necesario para todos los proyectos, pero es un sello de calidad profesional.
Automatización del Despliegue con Escenarios Avanzados
Más allá de la simple sincronización de archivos, podemos automatizar otros aspectos críticos del DevOps WordPress.
Gestión de la Base de Datos
Nunca sincronices la base de datos de producción directamente desde el repositorio. En su lugar, puedes crear un flujo para ejecutar migraciones controladas.
- name: Ejecutar migraciones de base de datos
run: |
ssh ${{ secrets.SSH_USER }}@${{ secrets.SERVER_IP }} \
"cd /ruta/absoluta && wp db export backups/pre-deploy-$(date +%Y%m%d%H%M%S).sql && wp db import /ruta/absoluta/wp-content/uploads/migrations/latest.sql"
Invalidez de Caché
Después de un despliegue, es buena práctica limpiar la caché de tu CDN (Cloudflare, Fastly, etc.) o de tu plugin de caché (WP Rocket, W3 Total Cache).
- name: Limpiar caché de Cloudflare
env:
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
run: |
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
Notificaciones de Estado
Mantén a tu equipo informado. GitHub Actions puede notificar en Slack, Discord o por correo electrónico.
- name: Notificar éxito en Slack
if: success()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": "🚀 Despliegue exitoso de WordPress a producción desde la rama ${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Buenas Prácticas y Consideraciones de Seguridad
La automatización del despliegue trae consigo una gran responsabilidad. Aquí hay reglas críticas a seguir:
- Principio de Mínimo Privilegio: La clave SSH que uses en GitHub Actions debe tener permisos muy limitados. Idealmente, solo debe poder escribir en la carpeta
wp-contenty ejecutar WP-CLI. No uses la claveroot. - Variables de Entorno vs. Archivos: No subas
wp-config.phpcon credenciales reales al repositorio. Usa variables de entorno en GitHub Actions y un script de post-despliegue que genere el archivo. - Estrategia de Ramas: Usa
developpara despliegues en un entorno de staging ymainsolo para producción. Configura reglas de protección de ramas en GitHub para evitarpushesdirectos amain. - Pruebas antes de tocar producción: El job
testdebe ser un guardián. Si falla, el pipeline debe detenerse y notificar al equipo. - Manejo de
uploads: La carpetauploads(wp-content/uploads) no debe sincronizarse desde el repositorio. Debe ser gestionada por separado (por ejemplo, con un plugin de almacenamiento externo como S3 o DigitalOcean Spaces, o mediante un script de backup/sync específico).
Conclusión
Implementar un pipeline de CI/CD WordPress con GitHub Actions transforma la manera en que gestionas tu sitio. Dejas atrás el riesgo del despliegue manual y abrazas un proceso robusto, probado y automatizado que escala con tu proyecto.
Hemos visto desde un despliegue básico con rsync hasta la integración de pruebas de linting, unitarias, migraciones de base de datos y notificaciones. Este es el camino hacia una verdadera automatización despliegue de WordPress. Cada git push se convierte en un acto de confianza, sabiendo que el pipeline se encargará de todo el proceso de forma consistente y segura.
El futuro del desarrollo WordPress es DevOps. Empieza hoy configurando tu primer workflow y notarás la diferencia en productividad y tranquilidad.
[TIP] No olvides revisar los logs de tus workflows en la pestaña "Actions" de tu repositorio de GitHub. Son la mejor herramienta de depuración cuando algo no funciona según lo esperado.
