Kontinuierliche Integration in Unity: Verkürzung der Montagezeit und Einsparung von Ressourcen + Gewinnlinie als Geschenk



Hallo allerseits, ich stehe in Kontakt mit Alexander Panov, einem technischen Experten von Pixonic. In der Firma bin ich für projektübergreifende Lösungen und projektnahe Peripheriegeräte verantwortlich und möchte heute meine Erfahrungen und Best Practices teilen.

Plattformen der kontinuierlichen Weiterentwicklung und Integration oder CI / CD werden mittlerweile überall dort eingesetzt, wo iterative und gut funktionierende technische Prozesse eine entscheidende Rolle spielen. In diesem Artikel werden wir uns mit CI / CD für die Implementierung unserer Unity-Projekte für die Entwicklung mobiler Spiele befassen: Welche Probleme sind aufgetreten, wie haben wir sie gelöst, welche Verbesserungen haben wir erzielt und wie werden unsere Pipeline-Assembly-Builds registriert?

Stimmen Sie sofort zu, dass wir TeamCity von JetBrains als CI-Server, GitHub als Repository für Git-Repositorys und Nexus zum Speichern von Assembly-Artefakten verwenden.

Wir standen also vor folgenden Problemen:

  • Fehlen eines gemeinsamen Standards für die Erstellung von Assemblys: Praktisch alle Entwickler hatten Zugriff auf den TeamCity-Server, wodurch Assemblyskripte in verschiedenen Programmiersprachen (BASH, PowerShell, Python) geschrieben und die Logik häufig dupliziert wurden.
  • Schwache Flotte: Aufgrund der Tatsache, dass wir Builds für iOS erstellen müssen, mussten wir eine Flotte von Autos von Mac mini verwenden. Und da in Unity fast die gesamte Baugruppe in einem Thread abläuft, stellte sich die Parallelisierung von Baugruppen auf einer Maschine als problematisch heraus.
  • Ein wenig überarbeitete Betriebseffizienz: Aufgrund der geringen Produktivität unseres technischen Supports dauerte die Montage sehr lange.
  • Große Warteschlangen, die mit einer ausreichenden Anzahl von TeamCity-Agenten auf den Zusammenbau warten ;
  • Für jedes Projekt einen eigenen Agentenpool: Aufgrund der unterschiedlichen auf den Geräten installierten Umgebung sowie der zwischen den Projekten widersprüchlichen Konfigurationsdateien (Cache-Server-Konfigurationsdateien usw.) war es nicht möglich, einen gemeinsamen Pool zu organisieren.

Was hast du als Ergebnis gemacht?


  • Repository für Assemblerskripte

Zunächst haben wir ein einzelnes Repository mit Skripten für Assemblys in Python erstellt. Der Start erfolgt in der Pipenv-Verwaltungsumgebung für virtuelle Umgebungen, wobei Bibliotheken von Drittanbietern auf dem Server für eine schnelle Aktualisierung und Versionskontrolle der erforderlichen Bibliotheken übertragen werden. Daher haben wir einen einzigen Einstiegspunkt für Baugruppen aller vorhandenen Projekte bereitgestellt. Wir haben alle Skripte in Python neu geschrieben, die Konfigurationen vereinheitlicht, zu einem gemeinsamen Standard geführt und Duplikate des Codes entfernt.

  • Neue Flotte von Autos

Es war notwendig, die Montagezeit zu verkürzen und möglicherweise die Anzahl der verwendeten Geräte zu verringern.

Anfangs hatten wir eine Farm mit 13 Mac-Minicomputern, aber diese Lösung ist alles andere als optimal: Aufgrund der Besonderheiten von Assemblys in Unity werden etwa 80% der Montagezeit in nur einem Thread ausgeführt. Hinzu kommt ein solider Schreibzugriff auf die Festplatte, und wir erhalten, dass ein Mac mini mit 1-2 gleichzeitigen Assemblys kaum zurechtkommt.

Das Ergebnis ist die Notwendigkeit, die Hardware zu überprüfen.

Bei der Suche und dem Vergleich von Alternativen für Unity-Baugruppen haben wir festgestellt, dass AMD Ryzen-basierte Computer aufgrund ihrer Leistung die gleichzeitige Montage von bis zu 8-12 Baugruppen ohne nennenswerten Leistungsverlust ermöglichen. In diesem Zusammenhang wurde beschlossen, vier solcher Geräte mit sechs SSDs zu erwerben und zu installieren zwei Agenten pro Festplatte.

Ein Vergleich, wie es war und was wurde, ist in der Tabelle angegeben.



Durchschnittliche Bauzeit:



Darüber hinaus organisierten wir die Priorisierung der Auswahl der TeamCity-Agenten, um den Zeitaufwand für die Montage in der Warteschlange zu verringern. Bisher verfügte jedes unserer Projekte über einen eigenen Agentenpool, und aufgrund der Vielzahl von Plattformen in den Spielen war es in der projektabhängigen Umgebung nicht möglich, einen gemeinsamen Pool zu erstellen. Nach der Neuorganisation des Systems haben wir eine Reihe von Agenten für die Projekte übrig gelassen, die für automatische Assemblierungen verwendet werden. Sie konnten jedoch mehrere gemeinsame Agenten für alle Projekte hinzufügen: Sie werden in die Arbeit aufgenommen, wenn alle mit dem gewünschten Projekt verknüpften Agenten beschäftigt sind.

  • BuildPipeline-Bibliothek für Unity

Sie haben eine kleine Bibliothek für Unity gestartet, mit der Build-Builds in einem separaten Unity-Editorfenster festgelegt und Build-Builds im Batch-Modus ausgeführt werden können. Von der Hauptfunktionalität der Bibliothek: Sie können vor dem Zusammenbau Definitionen hinzufügen und entfernen, Bibliotheken von Drittanbietern oder bestimmte Dateien deaktivieren, benutzerdefinierte Vor- und Nachbearbeitungsschritte hinzufügen, alle Einstellungen in Konfigurationsdateien speichern und die Möglichkeit ihrer Vererbung nutzen.


Das Definitionsfenster in der BuildPipeline-Bibliothek

Unsere aktuelle Pipeline CI / CD


PullRequest-Assembly. Für jedes Commit:

  1. Starten von Unity, um nach Kompilierungsfehlern zu suchen, Updates zu definieren und Lösungen zu generieren.
  2. laufende Tests;
  3. Start eines statischen Analysators: Mit seiner Hilfe wird eine inkrementelle Analyse für Dateien durchgeführt, die vom aktuellen PullRequest betroffen sind.
  4. Eine Nachricht über das Überprüfungsergebnis, die auf GitHub gespeichert wird.

Schritte zum Erstellen eines Unity-Projekts:

1. Installieren von Pipenv und Ausführen von Skripten zum Erstellen in Python: Aktualisieren und Installieren von Python-Bibliotheken von Drittanbietern von unserem Server (Proxy des pypi.org- Repositorys) und Ausführen des Erstellungsskripts.

2. Vorbereitungen für die Versammlung der Einheit:

  • Löschen des Bibliotheksordners, der Bundles, ausgewählter Assets (nach Maske und / oder bestimmten Dateien), Löschen von Lösungen (SLN-Dateien) - falls erforderlich;
  • Generieren einer Baugruppeninformationsdatei: Filialname, Baugruppennummer usw. - zur weiteren Verwendung im Build zum Debuggen und Testen;
  • Einrichten eines Unity-Cache-Servers für ein Projekt. Jedes Projekt hat sein eigenes. Jeder Entwickler hat auch einen Cache-Server eingerichtet, um das Füllen zu beschleunigen: Wenn ein Entwickler ein neues Asset hinzufügt, wird es automatisch auf dem Cache-Server und auf dem Build-Server angezeigt, sodass der Import von Assets viel schneller erfolgt.

3. Führen Sie Unity aus, um nach Kompilierungsfehlern zu suchen, Definitionen zu aktualisieren und Lösungen zu generieren.

4. Führen Sie die Tests aus und beenden Sie sie, falls erforderlich, falls Fehler auftreten.

5. Starten Sie Unity BuildPipeline mit der erforderlichen Konfiguration und zusätzlichen Projektparametern.

6. Für Android / iOS-Builds - Gradle / Xcode starten:

  • Gradle - GradleWrapper;
  • Xcode - Archivieren Sie das nach Unity erhaltene XcodeProject und kopieren Sie es auf den Mac mini. Installieren und aktualisieren Sie alle erforderlichen Zertifikate und Bereitstellungsprofildateien separat. Führen Sie die Befehle Bereinigen, Archivieren, Exportieren aus.
  • Beim Export ist es möglich, die Signatur des Builds, des Entwicklers und des AppStore zu trennen. Wählen Sie je nach dem, was wir sammeln, die gewünschte Pliste oder jede einzelne nacheinander aus. Am Ausgang erhalten wir zwei Dateien: Developer und Release - zur Installation auf Testgeräten bzw. zum Hochladen in den AppStore.

7. Gießen gesammelter Builds und zugehöriger Dateien (Protokolle, Testergebnisse, .obb, Manifest zum Installieren von iOS-Anwendungen, dsym-Dateien usw.) in den Artefaktspeicher für eigenständige Assemblys - Hochladen des gesammelten Builds in den Archivspeicher.

8. Erstellen einer Seite mit einem QR-Code zum Installieren des Builds, Hinzufügen von Links aus dem Repository und Erstellen von Informationen zur Datenbank für die weitere Arbeit mit der PixLauncher-Anwendung - wir werden später darauf zurückkommen.

9. Mitteilung an Slack über das Ergebnis der Versammlung: an denjenigen, der die Versammlung gestartet hat, sowie an die erforderlichen Kanäle.


Solche Botschaften kommen zu Slack

Weitere Schritte


Als letzter Schritt des Plans werden die gesammelten Builds an Geräte zum weiteren Testen und Hochladen in den Store verteilt.

Um Builds auf Geräten zu installieren, haben wir eine kleine Anwendung für Android und iOS geschrieben - PixLauncher. Wir installieren es auf jedem Gerät, auf dem es möglich ist, einen Build von TeamCity auszuwählen. Der Einfachheit halber können Sie darin Filter festlegen, z. B. eine Konfiguration zu Ihren Favoriten hinzufügen und dann mit einem Klick Aktionen ausführen. Bei Builds für Android wird bei Bedarf die Datei in OBB-Auflösung automatisch heruntergeladen.

Darüber hinaus haben wir die Möglichkeit der Installation des Builds über Push-Benachrichtigungen organisiert: Wir haben dem TeamCity-Server ein selbst geschriebenes Plug-In hinzugefügt, mit dem wir die MAC-Adressen der mit dem lokalen Netzwerk verbundenen Geräte auf der Build-Seite auswählen können. Anschließend wird an diese Geräte eine Push-Benachrichtigung mit einem Link zur Installation gesendet - so erfolgt dies nun mit einem Klick.

So konnte die Anwendung die Suche nach dem gewünschten QS-Build durch die Abteilung und die Installation auf Geräten für eine spätere Überprüfung beschleunigen.


Aussehen der PixLauncher iOS App

Abschließend werden Builds in die Stores hochgeladen


Nach all den durchgeführten Aktionen ergibt sich natürlich die Notwendigkeit einer garantierten Ausfüllung der Build- und Metainformationen über die Anwendung an die Parteien.

Anfangs traten Probleme hauptsächlich mit dem AppStore auf:

  • Das Ausfüllen des Gates erfolgt nur von einem MacOS-Gerät aus.
  • Sie müssen Videos, Screenshots und Anwendungsbeschreibungen in mehr als 25 Sprachen hochladen.

Dies führte zu großen Zeitverlusten beim Befüllen und Abstürzen beim Herunterladen von Dateien in das Admin-Panel. Deshalb haben wir uns Gedanken über die Prozessautomatisierung gemacht.

Als Ergebnis haben wir Folgendes:

  1. In Google Disk haben wir ein Tablet mit einer Beschreibung der Anwendung in allen Sprachen erhalten.
  2. Die Videos und Screenshots der Anwendung sind in Ordnern mit einer bestimmten Benennung angeordnet.
  3. In Teamcity wurde eine Konfiguration vom Release-Build abhängig gemacht, um einen bereits zusammengestellten Build auszuwählen.
  4. Geben Sie über die GooglePlay-API und den iTMSTransporter für Apple die Builds und Metainformationen zur Anwendung im Store für alle erforderlichen Sprachen ein. Bei Problemen (zum Beispiel mit dem Netzwerk) unternehmen wir mehrere Versuche und senden eine Nachricht mit dem Fehlertext an Slack.


So sieht das Hochladen des Builds in den AppStore aus

Als Ergebnis - ein paar Zahlen


  • Derzeit haben wir ungefähr 400 Baugruppen und bis zu 60 Installationen von Geräten pro Tag.
  • Es gibt 57 verschiedene Build-Konfigurationen in TeamCity.
  • Wir verwenden 22 TeamCity-Agenten, während es möglich ist, die Leistung ohne nennenswerte Einbußen auf 48 Agenten zu erweitern.
  • Es besteht die Möglichkeit einer horizontalen Erweiterung der Flotte.

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


All Articles