ProHoster > Blog > Verwaltung > Mobile CICD-Erfahrung: ein Fastlane-Standard für viele mobile Anwendungen
Mobile CICD-Erfahrung: ein Fastlane-Standard für viele mobile Anwendungen
Ich würde gerne über kontinuierliche Integration und Bereitstellung für mobile Apps mit Fastlane sprechen. Wie wir CI/CD in allen mobilen Anwendungen implementieren, wie wir dorthin gekommen sind und was am Ende passiert ist.
Zu dem Tool, das uns am Anfang so gefehlt hat, gibt es im Netz bereits genügend Material, daher beschreibe ich das Tool bewusst nicht im Detail, sondern beziehe mich nur auf das, was wir damals hatten:
Hintergrund zur Entstehung von mobilem CI/CD im Unternehmen
Technische Lösung zur Einführung von CI/CD für N-Anwendungen
Der erste Teil ist eher Nostalgie für die alten Zeiten und der zweite Teil ist eine Erfahrung, die Sie auf sich selbst anwenden können.
So hat es sich historisch zugetragen
Jahr 2015
Wir haben gerade erst angefangen, mobile Anwendungen zu entwickeln, damals wussten wir nichts über kontinuierliche Integration, über DevOps und andere modische Dinge. Jedes Anwendungsupdate wurde vom Entwickler selbst auf seinem Computer ausgerollt. Und wenn es für Android ganz einfach ist – zusammengebaut, signiert .apk und lud es in die Google Developer Console hoch, dann bescherte uns das damalige Verteilungstool über Xcode für iOS tolle Abende – Versuche, das Archiv herunterzuladen, endeten oft mit Fehlern und wir mussten es erneut versuchen. Es stellte sich heraus, dass der fortschrittlichste Entwickler nicht mehrmals im Monat Code schreibt, sondern die Anwendung veröffentlicht.
Jahr 2016
Als wir aufwuchsen, hatten wir bereits darüber nachgedacht, wie wir Entwicklern einen ganzen Tag für eine Veröffentlichung freigeben könnten, und es erschien auch eine zweite Anwendung, die uns nur noch mehr in Richtung Automatisierung drängte. Im selben Jahr haben wir Jenkins zum ersten Mal installiert und eine Reihe gruseliger Skripte geschrieben, die denen sehr ähnlich sind, die Fastlane in seiner Dokumentation zeigt.
Leider wussten bisher nur unsere Entwickler, wie diese Skripte funktionieren und warum dieser endlose Stapel von Schlüsseln benötigt wird, und als wieder etwas kaputt ging, bekamen sie die „wunderschönen Abende“ für die Protokollanalyse.
Jahr 2017
Dieses Jahr haben wir gelernt, dass es so etwas wie Fastlane gibt. Es gab nicht so viele Informationen wie jetzt – wie man ein Programm startet und wie man es nutzt. Und das Tool selbst war damals noch grob: Ständige Fehler enttäuschten uns nur und man konnte kaum an die magische Automatisierung glauben, die es versprach.
Die wichtigsten im Fastlane-Kern enthaltenen Dienstprogramme sind jedoch: gym и pilot, wir haben es geschafft, es zu starten.
Sie wurden verbessert, schon allein deshalb, weil nicht alle dafür notwendigen Parameter vorhanden sind xcodebuild, müssen Sie angeben - gym wird selbstständig verstehen, wo und was liegt. Und für eine weitere Feinabstimmung können Sie die gleichen Schlüssel wie in angeben xcodebuild, nur die Benennung der Tasten ist klarer.
Dieses Mal sind die Build-Protokolle dank Gym und dem integrierten xcpretty-Formatierer viel besser lesbar geworden. Dies sparte Zeit bei der Reparatur defekter Baugruppen und manchmal konnte das Release-Team es selbst herausfinden.
Leider Montagegeschwindigkeitsmessungen xcodebuild и gym Wir haben es nicht getan, aber wir vertrauen der Dokumentation – bis zu 30 % Beschleunigung.
Ein Prozess für alle Anwendungen
Jahr 2018 und heute
Bis 2018 wurde der Prozess der Erstellung und Einführung von Anwendungen vollständig auf Jenkins verlagert, Entwickler stellten die Veröffentlichung von Veröffentlichungen auf ihren Maschinen ein und nur das Veröffentlichungsteam hatte das Recht zur Veröffentlichung.
Wir wollten bereits den Start von Tests und statischen Analysen verbessern und unsere Skripte wuchsen und wuchsen. Mit unseren Anwendungen ist es gewachsen und hat sich verändert. Damals gab es etwa 10 Anwendungen. Wenn man bedenkt, dass wir zwei Plattformen haben, sind das etwa 20 „lebende“ Skripte.
Jedes Mal, wenn wir dem Skript einen neuen Schritt hinzufügen wollten, mussten wir die Teile kopieren und in alle Shell-Skripte einfügen. Vielleicht hätten wir sorgfältiger arbeiten können, aber oft endeten solche Änderungen mit Tippfehlern, die für das Release-Team zu Abenden wurden, um Skripte zu korrigieren und herauszufinden, welcher kluge Kerl diesen Befehl hinzugefügt hat und was er tatsächlich bewirkt. Im Allgemeinen kann nicht gesagt werden, dass die Skripte für die Assemblierung für eine Plattform zumindest einigermaßen ähnlich waren. Obwohl sie sicherlich das Gleiche getan haben.
Um einen Prozess für eine neue Anwendung zu starten, musste man einen Tag damit verbringen, eine „frische“ Version dieser Skripte auszuwählen, sie zu debuggen und zu sagen: „Ja, es funktioniert.“
Im Sommer 2018 richteten wir unseren Blick erneut auf die sich noch entwickelnde Fastlane.
Aufgabe Nr. 1: Fassen Sie alle Skriptschritte zusammen und schreiben Sie sie in Fastfile neu
Als wir anfingen, sahen unsere Skripte wie ein Fußtuch aus, das aus allen Schritten und Krücken in einem Shell-Skript in Jenkins bestand. Wir sind noch nicht stufenweise auf Pipeline und Division umgestiegen.
Wir haben uns angeschaut, was wir haben, und vier Schritte identifiziert, die zur Beschreibung unseres CI/CD passen:
Test – Ausführen von Entwickler-Unit-Tests, Berechnen der Abdeckung,
Sonar – startet alle Linters und sendet Berichte an SonarQube,
Deploy – Senden eines Artefakts an Alpha (TestFlight).
Und wenn Sie nicht ins Detail gehen und die in Aktionen verwendeten Schlüssel weglassen, erhalten Sie dieses Fastfile:
default_platform(:ios)
platform :ios do
before_all do
unlock
end
desc "Build stage"
lane :build do
match
prepare_build
gym
end
desc "Prepare build stage: carthage and cocoapods"
lane :prepare_build do
pathCartfile = ""
Dir.chdir("..") do
pathCartfile = File.join(Dir.pwd, "/Cartfile")
end
if File.exist?(pathCartfile)
carthage
end
pathPodfile = ""
Dir.chdir("..") do
pathPodfile = File.join(Dir.pwd, "/Podfile")
end
if File.exist?(pathPodfile)
cocoapods
end
end
desc "Test stage"
lane :test do
scan
xcov
end
desc "Sonar stage (after run test!)"
lane :run_sonar do
slather
lizard
swiftlint
sonar
end
desc "Deploy to testflight stage"
lane :deploy do
pilot
end
desc "Unlock keychain"
private_lane :unlock do
pass = ENV['KEYCHAIN_PASSWORD']
unlock_keychain(
password: pass
)
end
end
Tatsächlich erwies sich unser erstes Fastfile als ungeheuerlich, wenn man bedenkt, welche Krücken wir noch brauchten und wie viele Parameter wir ersetzten:
lane :build do
carthage(
command: "update",
use_binaries: false,
platform: "ios",
cache_builds: true)
cocoapods(
clean: true,
podfile: "./Podfile",
use_bundle_exec: false)
gym(
workspace: "MyApp.xcworkspace",
configuration: "Release",
scheme: "MyApp",
clean: true,
output_directory: "/build",
output_name: "my-app.ipa")
end
lane :deploy do
pilot(
username: "[email protected]",
app_identifier: "com.example.app",
dev_portal_team_id: "TEAM_ID_NUMBER_DEV",
team_id: "ITS_TEAM_ID")
end
Im obigen Beispiel müssen wir nur einen Teil der Parameter angeben: Dies sind die Build-Parameter – Schema, Konfiguration, Namen der Bereitstellungsprofile sowie Verteilungsparameter – Apple-ID des Entwicklerkontos, Passwort, Anwendungs-ID usw An. In erster Näherung legen wir alle diese Schlüssel in speziellen Dateien ab – Gymfile, Matchfile и Appfile.
Jetzt können Sie in Jenkins kurze Befehle aufrufen, die die Sicht nicht verwischen und für das Auge gut lesbar sind:
Was hast du bekommen? Klare Befehle für jeden Schritt. Bereinigte Skripte, übersichtlich in Fastlane-Dateien angeordnet. Voller Freude rannten wir zu den Entwicklern und baten sie, alles, was sie brauchten, zu ihren Repositories hinzuzufügen.
Aber mit der Zeit wurde uns klar, dass wir auf die gleichen Schwierigkeiten stoßen würden – wir hätten immer noch 20 Assembler-Skripte, die auf die eine oder andere Weise beginnen würden, ihr eigenes Leben zu führen, es wäre schwieriger, sie zu bearbeiten, da die Skripte in Repositories verschoben würden, und wir hatten dort keinen Zugang. Und im Allgemeinen wird es nicht möglich sein, unseren Schmerz auf diese Weise zu lösen.
Aufgabe Nr. 2: Holen Sie sich ein einzelnes Fastfile für N Anwendungen
Nun scheint es, dass die Lösung des Problems nicht mehr so schwierig ist – stellen Sie die Variablen ein und los geht’s. Ja, tatsächlich wurde das Problem so gelöst. Aber in dem Moment, als wir es vermasselt haben, hatten wir weder Fachwissen in Fastlane selbst, noch in Ruby, in dem Fastlane geschrieben ist, noch nützliche Beispiele im Netzwerk – jeder, der damals über Fastlane schrieb, war auf ein Beispiel für eine Anwendung beschränkt ein Entwickler.
Fastlane kann mit Umgebungsvariablen umgehen, und wir haben dies bereits versucht, indem wir das Schlüsselbundkennwort festgelegt haben:
ENV['KEYCHAIN_PASSWORD']
Nachdem wir uns unsere Skripte angesehen hatten, identifizierten wir die gemeinsamen Teile:
#for build, test and deploy
APPLICATION_SCHEME_NAME=appScheme
APPLICATION_PROJECT_NAME=app.xcodeproj
APPLICATION_WORKSPACE_NAME=app.xcworkspace
APPLICATION_NAME=appName
OUTPUT_IPA_NAME=appName.ipa
#app info
APP_BUNDLE_IDENTIFIER=com.example.appName
[email protected]
TEAM_ID=ABCD1234
FASTLANE_ITC_TEAM_ID=123456789
Um diese Schlüssel nun in Fastlane-Dateien verwenden zu können, mussten wir herausfinden, wie wir sie dort bereitstellen können. Fastlane hat hierfür eine Lösung: Laden von Variablen über dotenv. In der Dokumentation heißt es: Wenn es für Sie wichtig ist, Schlüssel für verschiedene Zwecke zu laden, erstellen Sie mehrere Konfigurationsdateien im Fastlane-Verzeichnis .env, .env.default, .env.development.
Und dann haben wir beschlossen, diese Bibliothek etwas anders zu nutzen. Platzieren wir im Entwickler-Repository nicht die Fastlane-Skripte und ihre Metainformationen, sondern die eindeutigen Schlüssel dieser Anwendung in der Datei .env.appName.
Als sie selbst Fastfile, Appfile, Matchfile и Gymfile, wir haben es in einem separaten Repository versteckt. Dort war eine zusätzliche Datei mit Passwortschlüsseln von anderen Diensten versteckt - .env.
Sie können ein Beispiel sehen hier.
Bei CI hat sich am Aufruf nicht viel geändert; ein Konfigurationsschlüssel für eine bestimmte Anwendung wurde hinzugefügt:
Ich habe diese Lösung vorerst belassen, obwohl Fastlane eine Lösung zum Herunterladen von Fastfile über hat Aktionimport_from_git, aber es funktioniert nur für Fastfile, nicht aber für andere Dateien. Wenn Sie „wirklich schön“ wollen, können Sie Ihr eigenes schreiben action.
Ein ähnlicher Satz wurde für Android-Anwendungen und ReactNative erstellt. Die Dateien befinden sich im selben Repository, jedoch in unterschiedlichen Zweigen iOS, android и react_native.
Wenn das Release-Team einen neuen Schritt hinzufügen möchte, werden Änderungen im Skript über MR in Git aufgezeichnet, es besteht keine Notwendigkeit mehr, nach den Schuldigen fehlerhafter Skripte zu suchen, und im Allgemeinen müssen Sie jetzt versuchen, es zu beschädigen.
Nun, das ist es sicher
Zuvor haben wir viel Zeit damit verbracht, alle Skripte zu warten, sie zu aktualisieren und alle Konsequenzen von Updates zu beheben. Es war sehr enttäuschend, wenn die Gründe für Fehler und Ausfallzeiten in Releases einfache Tippfehler waren, die im Durcheinander der Shell-Skripte so schwer zu erkennen waren. Jetzt werden solche Fehler auf ein Minimum reduziert. Änderungen werden auf alle Anwendungen gleichzeitig übertragen. Und es dauert 15 Minuten, eine neue Anwendung in den Prozess einzubinden – richten Sie eine Vorlagenpipeline auf CI ein und fügen Sie die Schlüssel zum Repository des Entwicklers hinzu.
Es scheint, dass der Punkt mit Fastfile für Android und der Anwendungssignatur ungeklärt bleibt; wenn der Artikel interessant ist, werde ich eine Fortsetzung schreiben. Ich freue mich über Ihre Fragen oder Vorschläge „Wie würden Sie dieses Problem lösen?“ in den Kommentaren oder auf Telegram Baschkirowa.