Beuiot.info @beuiot

Pensées du moment et trucs que j'ai fait

19
Février
2015
Intégration continue dans un petit studio

Développer pour beaucoup de plate-formes en étant 2 ou 3 programmeurs peut devenir salement épineux. Le moindre changement, d'apparence anodin, fait en développant sous Windows peut causer mort et désolation sur les versions Mac, Linux ou console.

Après plusieurs tâches "test stabilité autres plate-formes" qui se sont transformées en hydres à 20 têtes, on s'est mis à faire de l'intégration continue. C'est-à-dire, dans notre cas, à avoir des machines dans un coin qui sont en permanence en train de récupérer les dernières versions du code source et des données des jeux, et de faire fonctionner le tout, de manière autonome. Ça sonne bien, non ?

La vaillante équipe

Commençons par le matériel : j'avais besoin de plusieurs machines, qui seraient entièrement dédiées à ça. Donc, peu puissantes, pas chères, qui consomment peu, avec une carte graphique compatible DirectX 10.

J'ai choisi une carte mère ITX ASROCK B85M, avec un Core i3-4130 (consomme peu et chipset graphique assez puissant pour le besoin), 4Go de RAM, une petite alimentation 300W et un boîtier compact pour pouvoir les empiler. Sur le serveur maître, un gros disque dur pour stocker tous les builds successifs; sur les serveurs esclaves, un petit SSD pour la rapidité. Le tout connecté sur un switch dédié pour ne pas perturber le reste du réseau (qui a déjà mal) et avec un lien réseau direct vers le serveur subversion.

Le starter pack (1 maître et 2 esclaves) a coûté moins de 1000€, plus une journée de montage et d'installation. Un mini datacenter sous le bureau !

Ils ont fière allure n'est-ce pas ?

Ils ont fière allure n'est-ce pas ?

Enter Jenkins

Pour le choix du logiciel, après un rapide tour d'horizon, Jenkins s'impose de lui même. Très répandu et activement développé, il peut paraître un peu sur-dimensionné pour nos besoins mais n'a pas vraiment d'équivalent.

L'installation elle-même est bien documentée, je vais donc m'attarder sur les points spécifiques liés au développement avec Unity3D.

Qui dit serveur dit accès à distance au bureau. Il ne faut surtout pas utiliser le bureau à distance de Windows (RDP) ! Vraiment, pas du tout. À chaque connexion ou déconnexion l'OS a le chic de foirer de manière spectaculaire les contextes DirectX et les accès à la carte graphique. Unity3D en faisant un usage intensif, je vous laisse imaginer les dégâts ! Un bon vieux serveur VNC fera l'affaire.

Il a fallu crafter quelques fichiers .bat (so 90's !) et des scripts Unity pour lancer la compilation du jeu automatiquement (voir la documentation Unity), et au bout de quelques essais majestueusement foirés, le tour est joué.

Tableau de bord d'un des projets de test

Tableau de bord d'un des projets de test

L'outil de build sous Unity a été mis à jour pour simuler l'environnement Jenkins, pour pouvoir tester extensivement le système de build avant de l'envoyer au turbin sur les serveurs :

L'environnement Jenkins simulé sous Unity

L'environnement Jenkins simulé sous Unity

Ça marche !!! ... Mais ça sert à rien !

Dans cette version brutte de pomme, les résultats sont peu utilisables. Soit le build a réussi, dans ce cas on peut le télécharger, soit a échoué, et euh... ben rien, c'est juste tout rouge dans la fenêtre. Pas de log d'erreur, pas de résultat de compilation, et pas de remontée d'alerte en cas de problèmes non bloquants.

Il a fallu développer un plugin pour ça, sobrement appelé "Upper SWAGGG", qui extrait des logs de compilation des infos utiles : erreurs et alertes de compilation, infos sur la taille du build et des assets. Il informe ensuite Jenkins de ce qui le concerne : build échoué ou pas, alertes à la compilation, ...

Le plugin sort des informations utiles des builds

Le plugin sort des informations utiles des builds

Niveau organisation, on a créé des projets ayant pour seul but de vérifier la stabilité indépendante de chacune de nos librairies (librairie de base, librairie platformer, ...).

Marie Thérèse, un de nos projets de test

Marie Thérèse, un de nos projets de test

Cool, on se fait spammer.

La discipline revient à l'ordre. Dès qu'on pète un autre projet ou une autre plate-forme, on le corrige directement. C'est fastidieux sur le moment, surtout si c'est sur un autre projet : il faut mettre à jour sa version locale, faire le patch, faire quelques tests pour voir si tout va bien. Mais faire les corrections petit à petit, en maîtrisant le contexte (le patch fautif vient d'être fait) est au final bien plus rapide et évite une bonne partie des cauchemars interminables en fin de projet.

On a pété un des projets en touchant au système de caméra

On a pété un des projets en touchant au système de caméra

Et puis bon, on se fait spammer à chaque modification si on ne fait rien. Le seul moyen d'y remédier est de corriger le problème !

Alors, heureux ?

Après un an d'utilisation, ce système a été salvateur pour garantir la stabilité des librairies. Il nous a bien souvent rappelé à l'ordre lors de commits yolo sur des composants partagés entre plusieurs projets. Alors, oui, c'est fastidieux, mais c'est la vie.

C'est aussi bien pratique d'avoir à portée de clic une version toute fraîche du jeu, sans avoir à faire le build soi même ou à demander à un dev de le faire !

Il y a eu un certain manque de communication et d'éducation pour l'utilisation régulière de cet outil même quand il ne nous fouette pas (infos sur le contenu du build, mise en place de tests spontanés et autonomes de n'importe qui de l'équipe, ...)

La maintenance du système s'est avérée douloureuse, surtout lors du changement de version Unity. Rien d'insurmontable, mais à prendre en compte lors des estimations !

Et après ?

Arrivant sur la fin d'un projet, je me rends compte que j'ai sous utilisé la disponibilité des machines. Chaque niveau du jeu a besoin d'un traitement lourd (principalement pour l'optimisation), qui est effectué via les outils éditeur sur les postes de développement. Ce serait quand même vachement sympa de déporter ce travail sur les workers disponibles.

Et puis bon, il ne faut pas oublier qu'un des intérêts principaux de l'intégration continue est de l'utiliser pour faire des tests fonctionnels et/ou unitaires automatiques. Ce qu'on n'a pas du tout fait... Mais ça, c'est une autre histoire.