Pendant longtemps, notre process de déploiement tenait en une phrase : « on se connecte en SSH et on fait un git pull ». Ça fonctionnait, jusqu’au jour où quelqu’un a oublié de vérifier que la branche locale était bien à jour, écrasant deux jours de travail d’un collègue directement en production. C’est cet incident, plus qu’une envie de modernité, qui nous a poussés à mettre en place un vrai pipeline GitHub Actions.
Voici le pipeline tel qu’il existe aujourd’hui, avec les étapes qu’on a ajoutées progressivement après nos premières erreurs de configuration.
La structure du fichier de workflow
Un pipeline GitHub Actions se définit dans un fichier YAML placé dans .github/workflows/. Le nôtre se déclenche différemment selon la branche : les tests tournent sur toute pull request, le déploiement uniquement sur un push vers main.
name: CI/CD WordPress
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
- run: composer install --prefer-dist --no-progress
- run: composer run lint
- run: vendor/bin/phpunit
Ajouter le lint JavaScript pour les blocs
Sur nos projets avec des blocs Gutenberg personnalisés, on ajoute une deuxième vérification en parallèle, pour le JavaScript géré via @wordpress/scripts :
test-js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- run: npm run lint:js
- run: npm run build

Faire tourner ces deux jobs (test et test-js) en parallèle plutôt qu’en séquence réduit sensiblement le temps total du pipeline. Sur GitHub Actions, deux jobs sans dépendance déclarée entre eux s’exécutent automatiquement en parallèle, sans configuration supplémentaire.
Le job de déploiement
Le déploiement ne se déclenche que si les tests précédents ont réussi, et uniquement sur la branche main — jamais sur une simple pull request :
deploy:
needs: [ test, test-js ]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Déploiement via rsync
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
ARGS: "-avz --delete --exclude=wp-content/uploads --exclude=.env"
SOURCE: "wp-content/themes/mon-theme/"
REMOTE_HOST: ${{ secrets.DEPLOY_HOST }}
REMOTE_USER: ${{ secrets.DEPLOY_USER }}
TARGET: "/var/www/site/wp-content/themes/mon-theme/"
La clé needs: [ test, test-js ] est celle qui nous a fait le plus défaut au début : sans elle, notre tout premier pipeline déployait en parallèle des tests, sans attendre leur résultat. Un code qui ne passait pas le lint pouvait quand même finir déployé en production.
Les secrets, jamais dans le code
La clé SSH de déploiement, l’utilisateur et l’hôte distant sont stockés dans les secrets du dépôt GitHub (menu Settings puis Secrets and variables), jamais en clair dans le fichier YAML. GitHub Actions les injecte comme variables d’environnement au moment de l’exécution, et les masque automatiquement dans les journaux d’exécution si jamais ils apparaissaient par erreur dans une sortie de commande.
| Secret | Contenu |
|---|---|
DEPLOY_SSH_KEY | Clé privée SSH dédiée au déploiement, distincte des clés personnelles |
DEPLOY_HOST | Adresse du serveur de production |
DEPLOY_USER | Utilisateur système avec des droits limités au dossier du site |
Ce qu’on a appris en cours de route
- Toujours utiliser une clé SSH dédiée au déploiement, avec des droits restreints — jamais la clé personnelle d’un développeur
- Ajouter une étape de vidage de cache après le déploiement, via une commande SSH exécutant
wp cache flush - Vérifier systématiquement le résultat du job de test avant de considérer qu’un pipeline « fonctionne » : un pipeline vert peut cacher des tests qui ne testent en réalité rien
Le vrai bénéfice de ce pipeline n’est pas la vitesse de déploiement, c’est l’impossibilité de déployer du code qui ne compile pas ou qui échoue au lint. C’est un garde-fou qu’aucune procédure manuelle, aussi bien documentée soit-elle, ne remplace vraiment.
En résumé
Un premier pipeline GitHub Actions pour WordPress n’a rien d’un projet titanesque : une trentaine de lignes YAML suffisent à couvrir tests, lint et déploiement conditionnel. L’essentiel tient dans la rigueur de la configuration — dépendances entre jobs, branche ciblée, secrets correctement isolés — plus que dans la complexité des outils utilisés.