Intégration continue dans Unity: comment réduire le temps d'assemblage et économiser des ressources + ligne de paiement en cadeau



Bonjour à tous, je suis en contact avec Alexander Panov, un expert technique de Pixonic. Dans l'entreprise, je suis responsable des solutions inter-projets et des périphériques proches du projet et aujourd'hui je souhaite partager mon expérience et mes meilleures pratiques.

Les plateformes de développement et d'intégration continus, ou CI / CD, sont désormais utilisées partout dans les secteurs où les processus techniques itératifs et performants jouent un rôle décisif. Dans cet article, nous parlerons de CI / CD pour la mise en œuvre de nos projets Unity pour le développement de jeux mobiles: quels problèmes nous avons rencontrés, comment nous avons réussi à les résoudre, quelles améliorations nous avons obtenues et comment nos builds d'assemblage de pipeline sont enregistrés.

Acceptez immédiatement que nous utilisons TeamCity de JetBrains comme serveur CI, GitHub comme référentiel des référentiels Git et Nexus pour stocker les artefacts d'assemblage.

Nous avons donc été confrontés aux problèmes suivants:

  • Absence d'une norme de création d'assemblage commune: pratiquement tous les développeurs avaient accès au serveur TeamCity, à la suite de quoi les scripts d'assemblage étaient écrits dans différents langages de programmation (BASH, PowerShell, Python), et la logique était souvent dupliquée;
  • Flotte faible: en raison du fait que nous devons construire des builds pour iOS, nous avons dû utiliser une flotte de voitures de Mac mini. Et comme dans Unity, la quasi-totalité de l'assemblage se déroule dans un seul fil, la parallélisation des assemblages sur une machine s'est révélée problématique;
  • Une efficacité opérationnelle un peu déboguée: du fait de la faible productivité de notre support technique, les assemblages ont pris très longtemps;
  • Grandes files d'attente en attente d'assemblage avec un nombre suffisant d'agents TeamCity;
  • Un pool d'agents distinct pour chaque projet: en raison des différents environnements installés sur les appareils, ainsi que des fichiers de configuration en conflit entre les projets (fichiers de configuration du serveur de cache, etc.), il était impossible d'organiser un pool commun.

Qu'avez-vous fait en conséquence?


  • Référentiel pour les scripts d'assemblage

Tout d'abord, nous avons créé un référentiel unique de scripts pour les assemblys en Python. Le lancement est effectué dans l'environnement de gestion de l'environnement virtuel Pipenv avec proxy de bibliothèques tierces sur son serveur pour une mise à jour rapide et un contrôle de version des bibliothèques requises. Ainsi, nous avons fourni un point d'entrée unique pour les assemblages de tous les projets existants. Nous avons réécrit tous les scripts en Python, unifié les configurations, conduit à un standard commun, supprimé les doublons du code.

  • Nouvelle flotte de voitures

Il était nécessaire de réduire le temps de montage, réduisant éventuellement le nombre d'appareils utilisés.

Initialement, nous avions une batterie de 13 mini-ordinateurs Mac, mais cette solution est loin d'être optimale: en raison de la particularité des assemblages sur Unity, environ 80% du temps d'assemblage sera effectué dans un seul thread. Ajoutez à cela une quantité solide d'accès en écriture sur le disque dur et nous obtenons qu'un Mac mini peut à peine faire face à 1-2 assemblages simultanés.

Le résultat est la nécessité de revoir le matériel.

Lors de la recherche et de la comparaison d'alternatives pour les assemblages Unity, nous avons remarqué que les ordinateurs basés sur AMD Ryzen, en raison de leurs performances, permettent d'assembler jusqu'à 8-12 assemblages en même temps sans perte de performances significative, dans le cadre de laquelle il a été décidé d'acheter quatre de ces appareils avec six SSD et d'installer deux agents par disque dur.

Une comparaison de comment c'était et de ce qui est devenu est donnée dans le tableau.



Temps de construction moyen:



De plus, nous avons organisé la priorisation de la sélection des agents TeamCity afin de réduire le temps passé par l'assemblage dans la file d'attente. Auparavant, chacun de nos projets avait son propre pool d'agents, et en raison de la nature multiplateforme des jeux, l'environnement dépendant du projet ne permettait pas de créer un pool commun. Maintenant, après la réorganisation du système, nous avons laissé un certain nombre d'agents affectés aux projets, qui sont utilisés pour les assemblages automatiques, mais ont pu ajouter plusieurs agents communs pour tous les projets: ils sont inclus dans le travail lorsque tous les agents associés au projet souhaité sont occupés.

  • Bibliothèque BuildPipeline pour Unity

Ils ont démarré une petite bibliothèque pour Unity, qui permet de définir des builds de build dans une fenêtre d'éditeur Unity distincte, et a également la possibilité d'exécuter des builds de build en mode batch. De la fonctionnalité principale de la bibliothèque: il vous permet d'ajouter et de supprimer des définitions avant assemblage, de désactiver des bibliothèques tierces ou des fichiers spécifiques, d'ajouter des étapes de pré et post-traitement personnalisées, tous ses paramètres sont stockés dans des fichiers de configuration, il y a aussi la possibilité de leur héritage.


La fenêtre de définition de la bibliothèque BuildPipeline

Notre pipeline actuel CI / CD


Assemblage PullRequest. Pour chaque commit:

  1. lancer Unity pour vérifier les erreurs de compilation, définir les mises à jour et générer des solutions;
  2. exécution de tests;
  3. lancement d'un analyseur statique: avec son aide, une analyse incrémentale est effectuée sur les fichiers affectés par la PullRequest actuelle;
  4. Un message sur le résultat de la vérification, qui est enregistré sur GitHub.

Étapes de construction du projet Unity:

1. Installation de Pipenv et exécution de scripts pour la construction en Python: mise à jour et installation de bibliothèques Python tierces à partir de notre serveur (proxy du référentiel pypi.org ) puis exécution du script de construction.

2. Préparation préliminaire à l'assemblage de l'Unity:

  • suppression du dossier Bibliothèque, des bundles, des actifs sélectifs (par masque et / ou fichiers spécifiques), suppression des solutions (fichiers .sln) - si nécessaire;
  • Génération d'un fichier d'informations d'assemblage: nom de la branche, numéro d'assemblage, etc. - pour une utilisation ultérieure dans la version de débogage et de test;
  • configuration d'un serveur de cache Unity pour un projet. Chaque projet a son propre. Chaque développeur dispose également d'un serveur de cache configuré pour un remplissage plus rapide: lorsqu'un développeur ajoute un nouvel actif, celui-ci apparaîtra automatiquement sur le serveur de cache et sur le serveur de génération - ainsi, l'importation d'actifs est beaucoup plus rapide.

3. Exécuter Unity pour vérifier les erreurs de compilation, mettre à jour définit et générer des solutions.

4. Exécutez les tests et quittez-les en cas d'erreur - si nécessaire.

5. Lancement de Unity BuildPipeline avec la configuration nécessaire et les paramètres de projet supplémentaires.

6. Pour les versions Android / iOS - lancez Gradle / Xcode:

  • Gradle - GradleWrapper;
  • Xcode - archivez le XcodeProject obtenu après Unity et copiez-le sur Mac mini. Installez et mettez à jour séparément tous les certificats et fichiers de profil de provisionnement nécessaires. Exécutez les commandes Nettoyer, Archiver, Exporter.
  • Au stade de l'exportation, il est possible de séparer la signature de la build, du développeur et de l'AppStore. Selon ce que nous collectons, sélectionnez le plist souhaité, ou chacun à son tour. À la sortie, nous obtenons deux fichiers: Developer et Release - pour l'installation sur les appareils de test et pour le téléchargement sur l'AppStore, respectivement.

7. Verser les builds collectés et les fichiers associés (journaux, résultats des tests, .obb, manifeste pour l'installation des applications iOS, fichiers dsym, etc.) dans le stockage d'artefacts, pour les assemblages autonomes - télécharger la build collectée dans le stockage d'archives.

8. Générer une page avec un code QR pour installer la construction, ajouter des liens du référentiel et des informations de construction à la base de données pour un travail ultérieur avec l'application PixLauncher - nous en parlerons plus tard.

9. Message à Slack sur le résultat du montage: à celui qui a lancé le montage, ainsi qu'aux canaux nécessaires.


De tels messages arrivent à Slack

Etapes supplémentaires


En tant qu'étape finale du plan, les versions collectées sont distribuées sur les appareils pour des tests supplémentaires et le téléchargement vers le magasin.

Pour installer des builds sur des appareils, nous avons écrit une petite application pour Android et iOS - PixLauncher. Nous l'installons sur tous les appareils où il est possible de choisir une version de TeamCity. Pour plus de commodité, vous pouvez y définir des filtres - par exemple, ajouter une configuration à vos favoris, puis effectuer des actions avec elle en un seul clic. Dans le cas de builds pour Android, si nécessaire, le fichier en résolution .obb est automatiquement téléchargé.

De plus, nous avons organisé la possibilité d'installer la build via des notifications push: nous avons ajouté un plug-in auto-écrit au serveur TeamCity, qui nous permet de sélectionner les adresses MAC des appareils connectés au réseau local sur la page de build. Une notification push est ensuite envoyée à ces appareils avec un lien vers l'installation - de cette façon, elle est maintenant effectuée en un seul clic.

Ainsi, l'application a permis d'accélérer la recherche du build QA souhaité par le service et l'installation sur les appareils pour une vérification ultérieure.


Apparence de l'application iOS PixLauncher

Enfin, le téléchargement de builds dans les magasins


Après toutes les actions effectuées, le besoin d'un remplissage garanti de la build et des méta-informations sur l'application aux parties se forme naturellement.

Au départ, des problèmes sont apparus principalement avec l'AppStore:

  • remplir la porte se fait uniquement à partir d'un appareil MacOS;
  • Vous devez télécharger des vidéos, des captures d'écran et des descriptions d'applications dans plus de 25 langues.

Cela a entraîné de grandes pertes de temps pour le remplissage et des plantages lors du téléchargement de fichiers vers le panneau d'administration. Nous avons donc pensé à l'automatisation des processus.

En conséquence, nous avons les éléments suivants:

  1. Dans Google Disk, nous avons obtenu une tablette avec une description de l'application dans toutes les langues;
  2. Les vidéos et captures d'écran de l'application sont organisées dans des dossiers avec une certaine dénomination;
  3. Dans Teamcity, afin de sélectionner une version déjà assemblée, ils ont rendu une configuration dépendante de la version;
  4. Grâce à l'API GooglePlay et iTMSTransporter pour Apple, remplissez les versions et les méta-informations sur l'application dans le magasin pour toutes les langues nécessaires. En cas de problème (par exemple, avec un réseau) - nous faisons plusieurs tentatives et envoyons un message à Slack avec le texte d'erreur.


Voici à quoi ressemble le téléchargement de la build sur l'AppStore

En conséquence - quelques chiffres


  • Nous avons maintenant environ 400 assemblages et jusqu'à 60 installations de builds sur des appareils par jour;
  • Il existe 57 configurations de construction différentes sur TeamCity;
  • Nous utilisons 22 agents TeamCity, alors qu'il est possible de s'étendre sans perte significative de performance à 48 agents;
  • Il existe la possibilité d'une expansion horizontale de la flotte.

Source: https://habr.com/ru/post/fr484172/


All Articles