Publié le

Déployer un projet Drupal avec GitHub Actions

Drupal
GitHub Actions
GitHub Actions

Depuis l'intégration d'outils de construction de pipelines aux principaux services d'hébergement de dépôts git (GitHub Actions pour GitHub, GitLab CI/CD pour GitLab), plus aucune excuse n'existe pour continuer le déploiement manuel via FTP.

Personnellement plus investi dans l'écosystème de GitHub que celui de GitLab, j'utilise GitHub Actions pour la majorité de mes déploiements avec une pipeline que j'ai affiné au fur et à mesure des années.

Voici celle que j'utilise pour le déploiement de mes projets Drupal.

Récupération du code

name: Build and deploy
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

Ici, nous créons une pipeline appelée Build and deploy qui tourne sur la dernière version d'Ubuntu. Elle se déclenche dès que du code est poussé sur le dépôt (ici sur toutes les branches, mais il est possible de scoper cette pipeline à la seule branche main par exemple).

Nous ajoutons ensuite une première étape qui récupère le code via l'action actions/checkout.

Installer les dépendances PHP via Composer

      - name: Validate composer.json
        run: composer validate --no-check-all

      - name: Install composer dependencies
        run: composer install --prefer-dist --no-progress

On ajoute ensuite 2 étapes :

  • Validate composer.json : on valide que le fichier composer.json est conforme, pratique recommandée par Composer
  • Install composer dependencies : on installe les dépendances du projet dans la pipeline

Compiler les assets du front-end

      - name: Install NPM dependencies
        run: npm ci

      - name: Build assets
        run: npm run build
  • Install NPM dependencies : on utilise ici la commande npm ci (pour Clean Install) à la place de npm install, pratique permettant de s'assurer que les dépendances installées le sont avec une version fixe spécifiée dans le fichier package-lock.json
  • Build assets : on lance ensuite la commande de build pour compiler les assets du front-end

Déployer les fichiers sur un serveur via SSH

      - name: Install SSH Key
        uses: shimataro/ssh-key-action@v2
        with:
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          name: id_rsa
          known_hosts: unnecessary
          if_key_exists: fail

      - name: Deploy to server
        run: rsync -avzq --no-perms --no-owner --no-group --chown=www-data:www-data -e "ssh -o StrictHostKeyChecking=no" --exclude-from="${GITHUB_WORKSPACE}/rsync-exclude.txt" $GITHUB_WORKSPACE/ ${{ secrets.SSH_HOST }}:/var/www/html/

Plusieurs choses se passent ici :

  • Install SSH Key : on installe une clef SSH pour accéder au serveur distant. J'utilise ici un secret appelé SSH_PRIVATE_KEY défini dans le dépôt à déployer côté GitHub. À noter que pour ces 2 étapes, j'ai désactivé la vérification du host avec StrictHostKeyChecking=no pour faciliter la configuration de la pipeline et du serveur distant.
  • Deploy to server : c'est ici que tout se passe. Une fois le projet compilé, je le déploie via rsync en utilisant les permissions définies sur le serveur. L'adresse de connexion au serveur ainsi que l'utilisateur SSH sont définis dans un seul et même secret SSH_HOST de la forme user@myserver.com. Le chemin /var/www/html est ici défini en dur mais peut-être enregistré dans une variable également.

    Pour ne pas déployer de fichiers qui n'ont rien à faire sur le serveur, j'utilise l'argument exclude-from qui me permet lire depuis un fichier rsync-exclude.txt une liste de fichiers/dossiers à exclure. Au minimum, celui-ci contient les dossiers .git, .github et node_modules.

Reconstruire le cache de Drupal

Jusque-là, les étapes du déploiement sont standards et peuvent-être utilisées sur la plupart des projets PHP telles quelles.

De part le fonctionnement de Drupal et de son système de cache, il est souvent nécessaire de le reconstruire pour qu'il prenne en compte les dernières modifications de fichiers, notamment lors du changement de fichiers twig ou PHP.

J'ajoute donc l'étape suivante permettant de lancer la commande drush cr pour reconstruire le cache Drupal directement sur le serveur.

Comme nous avons déjà configuré la clef SSH dans la pipeline, nous n'avons plus qu'à lancer la commande directement sur le serveur distant.

      - name: Rebuild drush cache
        run: ssh -o StrictHostKeyChecking=no ${{ secrets.SSH_HOST }} "cd /var/www/html && vendor/bin/drush cr"

Pipeline complète

name: Build and deploy
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Validate composer.json
        run: composer validate --no-check-all

      - name: Install composer dependencies
        run: composer install --prefer-dist --no-progress

      - name: Install NPM dependencies
        run: npm ci

      - name: Build assets
        run: npm run build

      - name: Install SSH Key
        uses: shimataro/ssh-key-action@v2
        with:
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          name: id_rsa
          known_hosts: unnecessary
          if_key_exists: fail

      - name: Deploy to server
        run: rsync -avzq --no-perms --no-owner --no-group --chown=www-data:www-data -e "ssh -o StrictHostKeyChecking=no" --exclude-from="${GITHUB_WORKSPACE}/rsync-exclude.txt" $GITHUB_WORKSPACE/ {{ secrets.SSH_HOST }}:/var/www/html/

      - name: Rebuild drush cache
        run: ssh -o StrictHostKeyChecking=no ${{ secrets.SSH_HOST }} "cd /var/www/html && vendor/bin/drush cr"

Bonus : réchauffer automatiquement le cache Drupal lors des déploiements

Si vous voulez réchauffer automatiquement le cache Drupal lors des déploiements pour que la vitesse de chargement des pages soit la plus rapide possible pour tous vos visiteurs, j'ai écris un article spécifique détaillant la procédure à mettre en place en utilisant le module Warmer.

Plus d'excuses pour les déploiements manuels !