Aller au contenu

Déployer via GitHub Actions (VPS, mutualisé)

Un VPS ou un hébergement mutualisé n’a pas de deploy hook. La voie par défaut : à chaque publication, Menestrel déclenche un workflow GitHub Actions par repository_dispatch. Le workflow construit le site et pousse dist/ vers ton serveur, en rsync pour un VPS, en FTP pour un mutualisé. GitHub fournit la machine de build : le serveur n’a besoin ni de Node ni de Git, il ne reçoit que des fichiers statiques.

Prérequis : le code du site dans un dépôt GitHub, et un site branché sur le loader Menestrel.

  1. Créer le token d’accès GitHub

    Dans GitHub, ouvre Settings > Developer settings > Personal access tokens > Fine-grained tokens. Crée un token limité au seul dépôt du site, avec deux permissions :

    • « Contents : Read and write ». GitHub l’exige pour appeler repository_dispatch, l’endpoint que Menestrel utilise pour déclencher le workflow.
    • « Actions : Read ». Menestrel s’en sert pour lire l’état du run et suivre le déploiement jusqu’à « En ligne ».

    Donne-lui une date d’expiration et note-la quelque part : un token expiré est la première cause de cible en panne.

  2. Connecter l’hébergeur dans Menestrel

    Dans l’admin, ouvre « Réglages du site », onglet « Déploiement », puis « Connecter un hébergeur ». Choisis le fournisseur GitHub Actions, donne un nom (par exemple Production), puis remplis les trois champs propres à GitHub, tous obligatoires :

    • « Propriétaire » : le compte ou l’organisation GitHub, par exemple mon-agence.
    • « Dépôt » : le nom du dépôt, par exemple site-client.
    • « Token d’accès personnel » : le token de l’étape 1.
  3. Ajouter le workflow au dépôt

    Crée .github/workflows/menestrel.yml sur la branche par défaut. Version VPS, complète :

    name: menestrel-publish
    on:
    repository_dispatch:
    types: [menestrel_publish]
    # Une publication plus récente annule le build en cours : le dernier snapshot gagne.
    concurrency:
    group: menestrel-publish
    cancel-in-progress: true
    jobs:
    deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v5
    - uses: actions/setup-node@v5
    with:
    node-version: 24
    cache: npm
    - run: npm ci
    - name: Build du site
    run: npm run build
    env:
    MENESTREL_CONTENT_URL: ${{ vars.MENESTREL_CONTENT_URL }}
    MENESTREL_SNAPSHOT_ID: ${{ github.event.client_payload.snapshot_id }}
    - name: Préparer la clé SSH
    run: |
    install -d -m 700 ~/.ssh
    printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
    chmod 600 ~/.ssh/id_ed25519
    ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts
    - name: Déployer en rsync
    run: rsync -az --delete dist/ "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:/var/www/mon-site/"

    Trois lignes portent tout le câblage :

    • types: [menestrel_publish] : le event_type envoyé par Menestrel. Ne le renomme pas.
    • concurrency avec cancel-in-progress : deux publications rapprochées ne font pas deux mises en ligne qui se doublent ; le run annulé apparaît « Annulé » dans Menestrel, c’est le comportement attendu.
    • MENESTREL_SNAPSHOT_ID épingle le build sur le snapshot qui vient d’être publié, MENESTREL_CONTENT_URL dit où le lire. Détail des priorités dans Variables d’environnement.
  4. Poser les secrets et la variable côté GitHub

    Dans le dépôt, Settings > Secrets and variables > Actions :

    • Secrets : DEPLOY_SSH_KEY (une clé privée dédiée au déploiement, pour un utilisateur limité au dossier du site), DEPLOY_HOST et DEPLOY_USER.
    • Variable : MENESTREL_CONTENT_URL, par exemple https://content.menestrel.dev/p/prj_xxx/pk_xxx. Ce n’est pas un secret, une variable suffit.

    Le ssh-keyscan du workflow accepte la clé du serveur au premier contact. Pour la figer, remplace-le par un secret contenant ta ligne known_hosts.

  5. Mutualisé : remplacer rsync par FTP

    Sur un hébergement mutualisé sans SSH, remplace les deux dernières étapes du workflow (clé SSH et rsync) par une seule :

    - name: Déployer en FTP
    uses: SamKirkland/FTP-Deploy-Action@v4.3.6
    with:
    server: ${{ secrets.FTP_SERVER }}
    username: ${{ secrets.FTP_USERNAME }}
    password: ${{ secrets.FTP_PASSWORD }}
    protocol: ftps
    local-dir: dist/
    server-dir: www/

    Ajoute les secrets FTP_SERVER, FTP_USERNAME et FTP_PASSWORD, et ajuste server-dir au dossier public de ton hébergeur. Garde protocol: ftps si l’hébergeur le supporte : le mot de passe passe chiffré. L’action ne renvoie que les fichiers modifiés d’un déploiement à l’autre.

  6. Tester la cible

    Le bouton « Tester » envoie un vrai repository_dispatch sur le dernier snapshot publié, sans rien publier de nouveau : le workflow tourne et déploie pour de bon. Le résultat s’affiche aussitôt : « Hébergeur joint, déploiement déclenché. » si GitHub a accepté le dispatch, « Échec du test » avec le détail sinon. Le test ne figure pas dans « Déploiements récents » : suis le run dans l’onglet Actions du dépôt. Le suivi complet arrive avec la première publication.

Menestrel envoie un POST /repos/{owner}/{repo}/dispatches avec ce contenu :

Clé Contenu
event_type Toujours menestrel_publish. C’est la valeur attendue dans types:.
client_payload.snapshot_id L’id du snapshot publié, à passer dans MENESTREL_SNAPSHOT_ID. null si tu testes la cible avant toute publication : la variable arrive vide et le loader retombe sur le dernier snapshot publié.
client_payload.project Le slug du projet. Utile si un même dépôt sert plusieurs sites.
client_payload.cache_bust Réservé à une future option de reconstruction à neuf. Toujours false aujourd’hui ; le workflow peut l’ignorer.

Le suivi est automatique : avec le même token, Menestrel liste les runs du dépôt déclenchés par repository_dispatch depuis l’heure du déclenchement et suit le run jusqu’au bout. Contrairement à Vercel ou Netlify, il n’y a aucun champ facultatif à remplir. Dès que le run est repéré, le nom du déploiement dans « Déploiements récents » devient un lien vers le run GitHub.

État Sens
En file Menestrel a mis le déclenchement en file d’attente.
Déclenché GitHub a accepté le dispatch. Le run n’a pas encore été repéré.
En construction Le run est en file ou en cours d’exécution côté GitHub.
En ligne Le run s’est terminé en succès.
Échec Le run a échoué, ou le déclenchement n’a pas abouti.
Annulé Le run a été annulé, le plus souvent par cancel-in-progress quand une publication plus récente arrive.

Menestrel repère le run par son événement et sa date de création. Si d’autres workflows du dépôt écoutent aussi repository_dispatch, le suivi peut s’accrocher au mauvais run : un seul workflow à l’écoute est plus sûr.

Après 3 échecs consécutifs, Menestrel met la cible « En pause » et cesse de la déclencher : marteler un workflow cassé ne répare rien et noie l’historique. Corrige la cause (token expiré, workflow absent de la branche par défaut, serveur injoignable), puis clique « Reprendre ». Le compteur d’échecs repart à zéro et la publication reconstruit à nouveau le site.