top of page

Mille builds par mois — et pas un seul ne coûte un centime ⚙️

Photo du rédacteur: Marcel Dütscher
Marcel Dütscher
26 juil.
4 min de lecture

D'abord, une correction. La première version de cet article affirmait que nos minutes de build sur GitHub étaient épuisées et que cela nous avait obligés à passer à un compte Pro. C'était faux, et d'une manière qu'un seul coup d'œil à la documentation aurait suffi à éclaircir : pour les dépôts publics, les minutes de build GitHub sont gratuites. Les artefacts et les caches aussi. Notre dépôt est public depuis fin mai — nous n'avons donc jamais payé une seule minute, et nous ne le ferons jamais. Plutôt que de corriger le texte en douce, nous préférons le réécrire et vous raconter ce que les mesures ont vraiment montré. C'est d'ailleurs bien plus intéressant que la version erronée.


D'abord deviner, ensuite vérifier. Tout est parti d'un soir où une pull request terminée attendait dans le navigateur sans qu'une seule vérification ne se déclenche. Pas de coches vertes, juste le silence. Nous avons misé sur l'explication évidente — « quota épuisé » — et pris un compte Pro. Ensuite, tout a de nouveau fonctionné, ce qui semblait confirmer la théorie. Ce n'était pas le cas : le silence avait une autre cause (une pull request que GitHub ne peut pas, à ce moment-là, fusionner proprement avec la branche principale ne lance aucune vérification). Depuis, nous avons interrogé les données de facturation de chaque exécution, une par une. La réponse, pour chaque exécution et sur chaque système d'exploitation : temps facturable = 0 milliseconde. Soutenir une plateforme avec un abonnement, c'est tout à fait bien — mais comme explication pour ce dépôt, ça ne tient pas.


Ce qui est vrai : la machinerie a grandi. Chaque pull request met en route une petite usine : tout le serveur est compilé et sa suite de tests exécutée, le linter et l'analyse de code passent tout en revue, CodeQL traque les failles de sécurité, et des images Docker sont produites pour le serveur de jeu, le portail, le WorldHost et le backend d'IA. Une publication ajoute les builds Windows, Linux et macOS du client, plus la version WebGL pour le jeu dans le navigateur. Depuis fin mai, ça fait 1 723 exécutions de build, dont 1 092 rien qu'en juillet — pour 131 pull requests fusionnées en quatre semaines. Et oui, la récente envolée a vraiment un rapport avec l'IA 😉 : le projet est développé à 100 % avec l'aide de l'IA, et avec l'abonnement plus important, il se passe tout simplement plus de choses en parallèle. Seulement, la monnaie, ce n'est pas l'argent — c'est le temps d'attente.


Où passe le temps d'attente. Mesuré sur huit jours : le parcours de vérification normal (CI) 379 minutes, l'analyse de sécurité CodeQL 230, les builds de publication 126, le reste, ce sont des broutilles. Une seule version coûte environ 110 minutes de calcul, réparties entre WebGL (31,6), l'image Docker (19,4), macOS (13,7), Linux (13,7), le grand contrôle de tests (12,1), Windows (10,9) et l'empaquetage (7,2). C'est le temps qui sépare « terminé » de « installable chez vous ».


Et maintenant, ce qui est vraiment rare : le cache. Pour qu'un build ne reparte pas de zéro à chaque fois, GitHub stocke des résultats intermédiaires — et pour ça, on a droit à 10 Go par dépôt, peu importe à quel point on est public. Le nôtre en contient actuellement 5,3 Go, répartis en 63 entrées. Le problème, c'est la répartition : environ deux tiers sont des couches intermédiaires Docker, stockées à nouveau à chaque exécution — et elles évincent justement ce qui aiderait le plus. C'est le véritable goulot d'étranglement, et aucun abonnement au monde ne permet de s'en sortir en payant.


La plus belle trouvaille était un vrai bug. Pendant le build, Unity crée un énorme dossier intermédiaire (Library), dont la réutilisation fait gagner des minutes. Les mesures ont révélé que pour Windows, Linux et macOS, ce dossier n'était jamais sauvegardé — les builds essayaient consciencieusement de le restaurer, mais personne ne l'avait jamais écrit. Et le build Windows était le seul dont la clé de cache ne portait aucune indication de plateforme. Résultat : il téléchargeait 1,7 Go d'état intermédiaire WebGL, qu'Unity jetait ensuite consciencieusement avant de tout réimporter. Le journal le montre noir sur blanc : 257 secondes d'import des assets au lieu de 85 quand le cache est chaud. Ça fait presque neuf minutes perdues par version — parce qu'il manquait un mot dans une clé.


Ce que nous avons encore remarqué. Notre suite de tests tourne trois fois par commit livré (dans la pull request, après la fusion, et encore une fois lors de la publication). CodeQL vérifie trois langages à chaque pull request, alors que ce n'est même pas une vérification obligatoire. Il manque complètement un cache pour les paquets .NET. Un émulateur pour d'autres architectures de processeur est mis en place, alors que nous ne compilons que pour une seule. Et 7,4 Go d'anciens artefacts de build traînent là, avec la durée de conservation par défaut de 90 jours. Rien de tout ça n'est dramatique — mais mis bout à bout, ça fait un bon morceau de vie.


La leçon est la même que celle de notre serveur. À l'époque, nous avions mesuré que la moitié de la mémoire occupée n'allait pas du tout au jeu, mais à Docker et à la surveillance. Cette fois, c'était encore plus gênant : nous avons supposé une facture qui n'a jamais existé, et nous avons payé avant de vérifier. Mesurer plutôt que deviner — apparemment, cette phrase reste valable jusqu'à ce qu'on l'ait vraiment intégrée. Le grand ménage est prévu, mais pas encore fait ; une fois qu'il sera lancé, nous vous dirons ce qu'il nous a apporté. 🚀

Posts récents

Voir tout

Commentaires


Les commentaires sur ce post ne sont plus acceptés. Contactez le propriétaire pour plus d'informations.
bottom of page