10 points par GN⁺ 2026-01-15 | 3 commentaires | Partager sur WhatsApp
  • Partage de l’expérience frustrante d’un développeur face à la boucle de feedback lente et au débogage complexe de GitHub Actions
  • Dans le projet tmplr, la documentation était générée avec CUE via build.rs, mais les échecs du build CI ont déclenché le problème
  • Sur 4 plateformes, seul Linux ARM échouait au build ; la cause était le comportement de GitHub Actions qui masque les binaires x86_64 sur un runner arm64 lors d’un cross build
  • Une boucle de feedback inefficace où 2 à 3 minutes étaient nécessaires pour tester une seule modification
  • Solution adoptée : suppression de build.rs et passage à un GNU Makefile, afin de contrôler directement la logique CI et de résoudre le problème

Contexte du problème

  • tmplr est un outil de scaffolding de fichiers/projets qui utilise des fichiers de template lisibles et modifiables par des humains
  • build.rs utilisait CUE pour générer README.md, CHANGELOG.md ainsi que les fichiers de version et d’aide, afin de garantir la cohérence
  • Le travail en lui-même a été terminé en environ 1,5 heure, et l’article associé était également déjà rédigé
  • Tout fonctionnait en local, mais dans l’environnement CI de GitHub Actions, le build a échoué parce que le binaire CUE n’était pas installé

Cause de l’échec du build

  • Parmi 4 plateformes (Linux ARM, macOS ARM, Linux x86_64, macOS x86_64), seul Linux ARM produisait une erreur « command not found »
  • Cause : le matrix cross build est fortement isolé, si bien que CUE n’était installé que sur l’hôte Linux x86_64 et l’hôte macOS ARM
    • Sur macOS, exécuter un binaire x86_64 ne pose pas de problème
    • Sur Linux x86_64 non plus, exécuter un binaire x86_64 ne pose pas de problème
    • En revanche, GitHub Actions masque les binaires x86_64 sur un runner arm64, les rendant impossibles à exécuter
    Publicité

Une boucle de feedback inefficace

  • Processus répété pour tenter de résoudre le problème :
    1. chercher des corrections possibles
    2. modifier ci.yml
    3. commit et push (jj squash --ignore-immutable && jj git push)
    4. ouvrir l’onglet « Actions »
    5. ouvrir la dernière exécution
    6. ouvrir l’exécution Linux ARM
    7. attendre quelques secondes
    8. frustration
    9. recommencer
  • 2 à 3 minutes étaient nécessaires par modification
  • Dans l’idéal, GitHub fournirait soit un runner local complet, soit une fonction permettant de vérifier rapidement la progression après un push
    • Une fonctionnalité du type « scratch commit » : un moyen de tester différentes exécutions sans polluer l’historique Git ni l’historique des exécutions Actions
  • Mais à ce jour, une telle fonction n’existe pas

Solution

  • Après avoir répété cette boucle pendant 30 minutes, arrêt
  • Application d’une méthode bien connue sur Internet : « ne laissez pas GitHub Actions gérer la logique ; contrôlez directement le script et laissez Actions se contenter de l’appeler »
  • Suppression de build.rs (à regret, mais le sacrifice était nécessaire)
  • Déplacement de toutes les tâches de génération dans un GNU Makefile
  • Commit des fichiers générés dans le dépôt et annulation des changements CI
  • Problème résolu
Publicité

Conclusion

  • GitHub Actions empêche parfois de bénéficier de certaines bonnes approches
  • Beaucoup de temps est perdu à déboguer les runners ou à optimiser le processus de build
  • Mais il offre aussi des avantages difficiles à obtenir autrement, comme les builds macOS
  • Et bien sûr, il n’existe pas vraiment de système réputé plus simple à configurer que GitHub Actions

We are all doomed to GitHub Actions. …but at least I dodged the bullet early.

3 commentaires

 
anyflow 2026-01-18

On dirait que c’est un problème inévitable, puisqu’on est obligé de mettre la logique dans du YAML.

L’article ci-dessus semble proposer plus ou moins cette réponse, mais j’ai aussi l’impression que si l’on remplaçait la partie script par Dagger, ce serait peut-être la bonne solution.

« Ne laissez pas GitHub Actions gérer la logique ; contrôlez directement les scripts, et faites en sorte qu’Actions se contente d’appeler ces scripts. »

 
iolothebard 2026-01-15

Les GitHub Actions ne devraient servir qu’à configurer l’environnement (OS, toolchain de build, …) et à exécuter des scripts (shell, Python, bat, ps1…). Même si GitHub tombe, on devrait pouvoir builder n’importe où du moment que l’environnement est prêt. Quand je vois les workflows GitHub Actions en ce moment, je me dis qu’est-ce que ça vaut vraiment la peine d’aller chercher et d’utiliser jusque-là. Il y a très longtemps (?), Ansible a fait pareil et s’est planté.

 
GN⁺ 2026-01-15
Réactions sur Hacker News
  • Le problème principal de GitHub Actions, c’est que la boucle de feedback est beaucoup trop lente
    Devoir pousser puis attendre juste pour constater un échec trivial est vraiment frustrant
    Je pense qu’il vaut mieux séparer les tâches de CI dans des scripts exécutables en local, et n’utiliser les fonctionnalités d’Actions que comme amélioration progressive
    La combinaison workflow_dispatch et gh workflow run est correcte aussi, mais le fait que ce dernier ne donne pas directement l’URL du workflow lancé est pénible

    • On peut exécuter Actions en local avec nektos/act
      Ça a plutôt bien marché pour obtenir un feedback rapide
    • J’ai standardisé mes Actions pour qu’elles construisent et testent des images Docker
      Quand un problème survient, je peux déboguer dans un état presque identique à l’environnement GitHub Actions
    • Je trouve absurde qu’on ne puisse pas exécuter les étapes de CI en local
      Ça devrait être une exigence de base de tout système de CI
    • J’ai déjà envisagé de créer moi-même un outil de CI exécutable en local
      Au final, l’essentiel, ce sont des fonctions comme la mise en file d’attente, l’analyse des sorties et la télémétrie de l’historique des builds
    • Pour obtenir l’URL en utilisant gh workflow run, j’ai dû relister les exécutions du workflow via l’API GitHub
      Ça peut se mélanger s’il y a plusieurs exécutions en même temps, mais pour l’instant ça fonctionne à peu près bien
  • J’ai compilé quelques conseils de conception pour la CI

    1. utiliser un langage de script plus adapté à la CI, comme pwsh, plutôt que bash
    2. ne pas mettre de logique dans le workflow et le garder simple
    3. le concevoir comme un script indépendant pour pouvoir le tester en local
    4. conserver des sorties d’état et des informations de version pour faciliter le débogage
    5. envisager des runners tiers avec de meilleures fonctions de débogage
    • Je ne suis pas d’accord avec le point (1). Si le build ou les tests deviennent complexes, c’est une odeur de code
      Un shell simple devrait suffire
    • Je ne suis pas d’accord avec le point (1), mais je pense que le point (2) est juste
      C’est bien de définir des cibles CI dans un Makefile et de les appeler simplement, par exemple avec make ci-test
    • J’ai déjà connu l’enfer des plugins Jenkins
      Depuis, je gère toute ma CI avec des wrappers simples comme make build
    • Si on encapsule tous les builds dans un seul script, le système de CI perd sa visibilité sur les étapes détaillées
      Ce serait bien de pouvoir les séparer avec des marqueurs comme BeginStep("Step Name")
    • Au fond, avec une telle structure, je me demande s’il ne faudrait pas un nouvel outil de CI qui exécute directement les scripts
  • Le problème, plus que GitHub Actions lui-même, c’est l’automatisation bricolée qu’on a empilée dessus
    La logique devrait être scriptée dans un langage comme Python pour pouvoir être exécutée aussi en local

    • Ce qui frustre beaucoup de gens, c’est de ne pas pouvoir accéder en SSH directement à la VM en échec pour déboguer
      À chaque fois, il faut modifier le workflow, pousser et attendre
    • Certains plaisantent en disant que « ce travail de mise en scripts, c’est plusieurs semaines de boulot facturable »
    • Les fonctionnalités propres à la CI comme le déploiement, les releases ou le cache sont difficiles à reproduire complètement en local
    • Cette approche rappelle un peu l’époque où systemd appelait des scripts init.d, mais ce n’est pas forcément mauvais
    • Quelqu’un affirme même : « c’est à 100 % la faute de GitHub Actions »
  • Je fais toute ma CI dans des conteneurs
    La plateforme de CI ne fait qu’exécuter ce conteneur, donc je peux lancer exactement la même chose en local
    Les plateformes détestent cette approche, parce qu’elle casse le vendor lock-in

    • J’aime bien SourceHut CI
      En cas d’échec, on peut se connecter directement en SSH pour déboguer, et relancer après avoir modifié le manifeste sans pousser de branche
      En revanche, il faut l’auto-héberger
    • J’ai fait quelque chose de similaire avec GitLab CI en utilisant une image Docker dédiée
      Ça facilite la standardisation, mais avec le compromis de devoir maintenir l’image
    • L’inconvénient, c’est qu’il est difficile de conteneuriser les builds macOS
    • Les webhooks de GitHub sont très détaillés
      En pratique, il n’y a pas vraiment de lock-in, mais les gens sont tombés dans le cargo cult du CI/CD
    • Il y a même eu des réactions du genre : « envoyez-moi ça dans une newsletter »
  • Moi, j’aime bien GitHub Actions
    C’est mieux que Travis, que j’utilisais avant, et c’est très utile comme ressource gratuite pour les projets OSS
    Depuis que j’ai adopté Nix, la reproductibilité des environnements a beaucoup augmenté, donc l’intégration avec Actions est nettement meilleure

    • Je suis aussi d’accord avec l’approche Nix
      On peut exécuter tel quel dans Actions le conteneur construit avec flake
      Projet d’exemple
  • Je pense que GitHub Actions devrait simplement appeler des scripts bash ou python
    bash a beaucoup de limites, Python est plus flexible et plus simple à exécuter en local
    Une approche comme dans cet article, où uv s’installe automatiquement et gère les dépendances, est idéale
    C’est plus complexe que bash, mais dans l’environnement Actions, l’impact sur les performances n’est pas très important

    • En pratique, le YAML sert à définir l’environnement d’exécution, et la logique d’exécution doit rester dans des scripts externes
  • Le plus gros problème d’Actions, c’est la manière dont on le vend comme un assemblage de workflows
    Le débogage est presque impossible, et la configuration du cache est délicate, ce qui ralentit les builds
    Pour ces raisons, l’idée d’exécuter directement sur une VM persistante devient attrayante

  • Je suis le fondateur de Depot
    Nous exploitons un service qui fournit des runners GitHub Actions plus rapides et moins chers
    Les frustrations que ressentent beaucoup de gens reflètent en fait l’avis de la majorité
    Le système Actions est structurellement inefficace, et nous découvrons chaque semaine un nouveau goulot d’étranglement
    Je suis convaincu qu’il existe une meilleure façon de faire, et nous sommes en train de l’expérimenter
    Plus d’infos sur depot.dev

  • Le week-end dernier, j’ai créé un outil appelé gg watch action
    C’est un outil qui retrouve l’action la plus récente ou en cours pour la branche actuelle
    Lien GitHub

    • Les réactions étaient bonnes, avec des commentaires du type : « c’est une fonctionnalité qui aurait dû faire partie de la CLI gh »
      En revanche, il y avait un bug dans la commande gg tui où les dépôts n’apparaissaient pas
  • Je me demandais si un outil comme act pouvait aider
    nektos/act
    À cause des différences d’architecture, l’exécution locale peut différer de l’exécution en ligne, mais ça reste utile

    • La dernière fois que j’ai regardé, ce n’était pas un remplacement complet
      Il y avait environ 80 % de compatibilité
    • Ce n’est pas parfaitement identique, mais c’est très utile pour créer une boucle de feedback rapide
    • En réalité, la fonctionnalité la plus nécessaire est de pouvoir se connecter en SSH après un échec pour déboguer
      SourceHut prend ça en charge, et c’est vraiment pratique