Objaśnienie ciągłej integracji systemu iOS z serwerem Xcode
Opublikowany: 2022-03-11Wstęp
Przed Xcode 9 korzystanie z narzędzi ciągłej integracji Apple było żmudnym i złożonym procesem, który wymagał zakupu i instalacji dodatkowej aplikacji macOS Server. Doprowadziło to wielu programistów do porzucenia pomysłu ciągłej integracji w swoich projektach iOS lub skorzystania z rozwiązań innych firm, z bardzo różnym poziomem powodzenia.
Jednak po wydaniu Xcode 9.0 we wrześniu 2017 r. proces został znacznie uproszczony, w tym opcja automatycznego podpisywania kodu, i jest teraz całkowicie zintegrowany z Xcode. Dlatego nie wymaga żadnych dodatkowych aplikacji ani narzędzi.
Chociaż rozwiązania innych firm, takie jak Fastlane, Bluepill itp., są bardzo pomocne i mogą wykonać dla Ciebie wiele prac gruntownych, w tym artykule omówimy możliwości korzystania z samych narzędzi Xcode i Apple do potrzeb ciągłej integracji. Będziemy również używać ręcznego podpisywania kodu, ponieważ często wydaje się to być problemem dla wielu osób, a automatyczne podpisywanie również nie jest optymalnym rozwiązaniem, jeśli chodzi o wiele konfiguracji kompilacji.
Uwaga: ten artykuł jest oparty na Xcode 9.4.1 i koncentruje się na tworzeniu aplikacji na iOS, ale wiele z niego dotyczy Xcode 10 (obecnie dostępnego jako kompilacja beta 5) i tworzenia aplikacji na macOS.
Konfigurowanie serwera Xcode
Oprócz uproszczenia samego procesu integracji, Xcode 9 uprościł również proces konfiguracji Xcode Server.
Uruchom aplikację Xcode na komputerze z systemem macOS, który został wyznaczony jako serwer CI, i otwórz Preferencje.
Przejdź do ostatniej zakładki o nazwie Serwer i boty .
Włącz funkcje Xcode Server, klikając przełącznik w prawym górnym rogu. Następnie zostaniesz poproszony o wybranie użytkownika do uruchamiania i wykonywania skryptów kompilacji na tym komputerze. Prawdopodobnie dobrym pomysłem jest posiadanie dedykowanego użytkownika tylko do tego celu, zamiast korzystania z już istniejącego.
Pamiętaj, że ten użytkownik musi być zalogowany w systemie, aby uruchomić dowolny bot Xcode. Po zalogowaniu powinieneś zobaczyć zielone kółko obok nazwy użytkownika.
Otóż to! Przyjrzyjmy się bliżej botom Xcode.
Jak skonfigurować boty Xcode
Teraz możesz rozpocząć konfigurowanie botów Xcode do działania na tym serwerze. Można to zrobić na dowolnym komputerze deweloperskim podłączonym do tej samej sieci co serwer.
Otwórz Xcode na swoim komputerze deweloperskim i kliknij Xcode > Preferencje z górnego menu. Następnie przejdź do zakładki Konta i kliknij ikonę + w lewym dolnym rogu. W wyświetlonym oknie dialogowym wybierz Xcode Server.
Aby stworzyć bota, po prostu otwórz swój projekt w Xcode i wybierz opcję Product > Create Bot… z górnego menu. Konfiguracja botów składa się z kilku kroków, które omówimy w kolejnych sekcjach.
Automatyzacja dystrybucji aplikacji
Jednym z najczęstszych zastosowań automatyzacji tworzenia aplikacji na iOS jest konfigurowanie bota do przesyłania aplikacji na platformę dystrybucyjną iOS, taką jak TestFlight, Fabric itp.
Jak wyjaśniłem wcześniej, w tym artykule omówimy tylko przesyłanie do App Store Connect i pobieranie bezpośrednio z serwera Xcode, ponieważ są to natywne narzędzia Apple do dystrybucji aplikacji na iOS.
App Store Connect Dystrybucja za pomocą Xcode
Przed skonfigurowaniem bota upewnij się, że masz rekord aplikacji App Store Connect, który jest zgodny z identyfikatorem pakietu projektu tworzenia aplikacji. Warto również zauważyć, że każda kompilacja musi mieć unikalny identyfikator składający się z wersji kompilacji i numeru kompilacji. Omówimy, jak zapewnić spełnienie tych warunków, gdy później omówimy ustawienia botów Xcode.
Krok 1: Ustawienie prawidłowej konfiguracji kompilacji jest kluczowym krokiem, aby uzyskać to, czego chcesz. Upewnij się, że wybrałeś schemat i konfigurację, które tworzą aplikację, którą chcesz przesłać do App Store Connect. Obejmuje to upewnienie się, że konfiguracja kompilacji używa odpowiedniego identyfikatora pakietu, który jest zarejestrowany w portalu Apple Developer Twojego zespołu (służy do podpisywania kodu), a także w portalu App Store Connect (służy do automatycznego przesyłania aplikacji) .
Krok 2: Pozostając na karcie „Konfiguracja”, musimy określić opcje eksportu. Zamierzamy zbadać listę właściwości opcji eksportu, więc upewnij się, że wybrana jest opcja „Użyj listy niestandardowych opcji eksportu”.
Krok 3: Nadszedł czas, aby utworzyć listę właściwości opcji eksportu. Pełna lista kluczy do użycia w tym pliku jest dostępna, jeśli wpiszesz xcodebuild --help
, ale tutaj omówimy te używane w tej konfiguracji bota:
-
compileBitcode
— Bitcode to tymczasowy format wyjściowy firmy Apple dla kodu źródłowego aplikacji. Innymi słowy, jest to format, w którym kod źródłowy jest konwertowany przed skompilowaniem do kodu maszynowego dla określonej architektury. Jego celem jest posiadanie pojedynczego kontenera kodu, który można dalej zoptymalizować, jeśli w zestawie instrukcji zostanie wykonana optymalizacja, a także możliwość skompilowania go do przyszłych architektur z tego samego formatu. Nie ma to jednak żadnego wpływu na twoją aplikację. Od Ciebie zależy, czy chcesz go włączyć, czy nie. -
method
— ten argument określa rodzaj eksportowanego produktu. Apple rozróżnia produkty według ich wyznaczonych odbiorców — programiści pozwalają na zainstalowanie ich tylko na urządzeniach określonych w profilu aprowizacji, firma pozwala na zainstalowanie go wszystkim, ale muszą jawnie zaufać temu profilowi programistycznemu przed uruchomieniem aplikacji, a sklep z aplikacjami jest przeznaczony dystrybuując go do App Store lub App Store Connect, więc użyjemy tej wartości. -
provisioningProfiles
— to nie wymaga wyjaśnień. Należy jednak zwrócić uwagę na kilka rzeczy: Profile udostępniania na liście właściwości opcji eksportu to słownik, w którym klucz odpowiada identyfikatorowi pakietu produktu, a wartość odpowiada nazwie profilu udostępniania używanego do podpisywania go. -
signingCertificate
– Kolejny argument, który nie wymaga wyjaśnień. Wartością tego pola może być pełna nazwa certyfikatu lub skrót SHA-1. -
teamID
– Kolejny argument, który nie wymaga wyjaśnień. Jest to 10-znakowy identyfikator, który firma Apple wydała Twojej organizacji podczas rejestracji w programie Apple Developer. -
uploadBitcode
— określa, czy należy przesłać kod bitowy (jeśli zdecydowano się na jego kompilację), aby można go było używać w AppStore Connect do generowania nowych zoptymalizowanych kompilacji lub kompilacji dla przyszłych architektur. -
uploadSymbols
— przesyła symbole debugowania, dzięki czemu można uzyskać znaczący raport o awariach, a nie tylko zrzut pamięci i stos zestawu.
Więc teraz lista właściwości opcji eksportu może wyglądać mniej więcej tak:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>compileBitcode</key> <false/> <key>method</key> <string>app-store</string> <key>provisioningProfiles</key> <dict> <key>com.bundle.id</key> <string>ProvisioningProfileName</string> </dict> <key>signingCertificate</key> <string>Signing Certificate Exact Name or SHA-1 hash value</string> <key>teamID</key> <string>??????????</string> <key>uploadBitcode</key> <false/> <key>uploadSymbols</key> <true/> </dict> </plist>
Krok 4: Wybierz plik .plist, który utworzyłeś jako listę właściwości opcji eksportu.
Krok 5: Następna jest zakładka "Harmonogram" - skonfiguruj ją zgodnie z własnymi preferencjami.
Krok 6: Na karcie Podpisywanie usuń zaznaczenie opcji „Zezwalaj serwerowi Xcode na zarządzanie moimi certyfikatami i profilami” i samodzielnie prześlij pasujący certyfikat podpisywania i profil aprowizacji na stronie Certyfikaty i profile .
Krok 7: Karta Urządzenia powinna pozostać bez zmian, ponieważ przesyłamy aplikację, a nie ją testujemy.
Krok 8: Karta Argumenty umożliwia jawne ustawienie argumentów xcodebuild lub zmiennych środowiskowych, które mogą być używane w kompilacji lub skryptach przed i po integracji.
Krok 9: Wreszcie dochodzimy do zakładki Wyzwalacze , która jest również ostatnią zakładką w konfiguracji bota ciągłej integracji Xcode. To najpotężniejsze narzędzie w arsenale Xcode Server. Na początek chciałbym dodać następujące dwa polecenia jako skrypt przedintegracyjny:
#!/bin/sh set printenv
Pierwszy z nich drukuje wszystkie zmienne, których używa Xcode Server oraz ich wartości w bieżącym przebiegu integracji. Drugi wypisuje wszystkie zmienne środowiskowe i ich wartości. Zgodnie z oczekiwaniami może to być pomocne w debugowaniu skryptów, więc trafnie nazywam to „informacjami o debugowaniu”.
Pamiętaj, że wspomnieliśmy, że musimy upewnić się, że każda kompilacja przesłana do App Store Connect musi mieć unikalną parę wersji kompilacji i numeru kompilacji. Możemy użyć wbudowanego narzędzia PlistBuddy, ale potrzebujemy również sposobu na posiadanie unikalnego numeru kompilacji. Jedną z rzeczy, która jest zawsze obecna podczas integracji Xcode Server — i jest również dogodnie unikalna — jest numer integracji, ponieważ jest on automatycznie zwiększany. Stworzymy kolejny skrypt przedintegracyjny o nazwie „ustaw numer kompilacji” z następującą zawartością, aby zapewnić, że za każdym razem otrzymamy unikalny numer kompilacji:

#!/bin/sh buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}") buildNumber=$XCS_INTEGRATION_NUMBER /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
Jeśli używasz CocoaPods i zdecydowałeś się nie zatwierdzać katalogu Pods do swojego DVCS, powinieneś również dołączyć skrypt integracji wstępnej o następującej treści:
#!/bin/sh cd $XCS_PRIMARY_REPO_DIR pod install
Krok 10: prawie skończyliśmy, ale nie określiliśmy nigdzie, że chcemy przesłać kompilację do AppStore Connect ani na które konto. W tym celu dodamy skrypt pointegracyjny i kolejne wbudowane narzędzie o nazwie Application Loader. Umieść w skrypcie:
#!/bin/sh /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --upload-app -f $XCS_PRODUCT -u $TESTFLIGHT_USERNAME -p $TESTFLIGHT_PASSWORD
$XCS_PRODUCT
jest zmienną serwera Xcode i zawiera ścieżkę do aplikacji, która została utworzona w bieżącym przebiegu integracji. Jednak $TESTFLIGHT_USERNAME
i $TESTFLIGHT_PASSWORD
nie są zmiennymi systemowymi ani Xcode Server. Muszą one być skonfigurowane przez Ciebie i mieć wartość Twojego Apple ID i hasła. Niestety firma Apple zaprzestała obsługi generowania klucza API do przesyłania kompilacji AppStore Connect. Ponieważ są to informacje poufne, najlepiej jest skonfigurować je bezpośrednio na serwerze Mac (zakładając, że jest to Twoja własna) jako zmienna środowiskowa, a nie w konfiguracji bota Xcode Server.
Dystrybucja serwera Xcode
Bot dystrybucyjny Xcode Server w rzeczywistości używa tej samej konfiguracji, co w przypadku dystrybucji App Store Connect, z wyjątkiem skryptów postintegracyjnych. Jednak pobranie aplikacji i zainstalowanie jej nadal może być trudne. Nadal musisz upewnić się, że profil aprowizacji, za pomocą którego została podpisana Twoja aplikacja, umożliwia zainstalowanie aplikacji na używanym urządzeniu.
Mając to na miejscu, musisz otworzyć Safari na swoim urządzeniu z systemem iOS i przejść do pulpitu nawigacyjnego serwera Xcode Server na serwerze. Na przykład, jeśli nazwa twojego serwera to „serwer Mac”, możesz go znaleźć pod adresem „nazwa-serwera-mac.local/xcode”, jeśli jesteś w tej samej sieci co serwer. Znajdziesz tam listę wszystkich swoich botów Xcode i statystyki ich ostatnich integracji.
Wybierz ten, który utworzył aplikację, którą chcesz pobrać. Na następnym ekranie będziesz mieć dwa przyciski — Zainstaluj i Profil . Jeśli pobierasz plik z tego serwera po raz pierwszy, musisz kliknąć Profil , aby dodać jego certyfikat do listy zaufanych źródeł. Następnie kliknij przycisk Instaluj na tej samej stronie, a pojawi się okno dialogowe potwierdzenia iOS „Czy na pewno chcesz zainstalować * na swoim urządzeniu?” Potwierdź to, klikając Tak , a Twoja aplikacja zostanie zainstalowana i uruchomiona z ekranu głównego.
W przypadku systemu iOS 10.3 i nowszych przyczyną niepowodzenia z „Nie można połączyć się z *.local” jest to, że certyfikat z podpisem własnym należy zaufać ręcznie w Ustawieniach na urządzeniu testowym.
Wykonaj następujące kroki:
Krok 1: Zainstaluj certyfikat(y) z podpisem własnym ze strony botów serwera Xcode na swoim iPhonie.
Krok 2: Przejdź do Ustawienia iPhone'a > Ogólne > Informacje > Ustawienia zaufania certyfikatu .
Krok 3: Znajdź certyfikat(y) z podpisem własnym swojego serwera w sekcji WŁĄCZ PEŁNE ZAUFANIE DLA CERTYFIKATÓW ROOT i włącz przełącznik.
Krok 4: Wróć do strony integracji botów na Xcode Server, kliknij Zainstaluj .
Automatyczne testowanie aplikacji Xcode Server
Innym świetnym zastosowaniem Xcode Server jest automatyczne testowanie aplikacji, niezależnie od tego, czy jest to testowanie jednostkowe, czy testowanie interfejsu użytkownika. Aby to zrobić, musisz ustawić odpowiedni cel dla swojego projektu. Oznacza to, że musisz mieć cel, który uruchamia testy jednostkowe lub testy interfejsu użytkownika, w zależności od celu.
Proces konfiguracji jest taki sam jak poprzedni, ale wybieramy inne opcje. Pierwsza poważna różnica dotyczy zakładki Konfiguracja . Oczywiście zaznaczymy pola „Analizuj” i „Testuj”, ponieważ jest to naszym głównym celem. Radziłbym też ani archiwizować, ani eksportować produktu za pomocą tego bota. Możliwe jest zarówno testowanie, jak i dystrybucja przy tej samej konfiguracji bota. Jednak te dwa scenariusze różnią się pod względem wyników i harmonogramu. Dystrybucja jest często prowadzona pod koniec cyklu.
Niezależnie od tego, czy pracujesz w Scrumie, Kanbanie, czy w jakimkolwiek innym frameworku, powinien istnieć predefiniowany cykl oparty na czasie lub zdarzeniach, na końcu którego powinieneś mieć wyeksportowany i użyteczny produkt. Z drugiej strony, powinieneś uruchamiać swojego bota testowego przy każdym zatwierdzeniu, ponieważ jest to Twoja pierwsza linia obrony przed regresją. Ponieważ bot testowy jest oczywiście uruchamiany częściej, połączenie tych dwóch botów w jeden może szybko wykorzystać miejsce na dysku na twoim serwerze. Ponadto każda integracja zajęłaby więcej czasu.
Pomijając to, przechodzimy do zakładki „Harmonogram” i omówiliśmy to już w poprzednim akapicie. Tak więc kolejnym interesującym tematem jest podpisywanie kodu. Zwróć uwagę, że nawet jeśli cel testowania może wskazywać, że nie wymaga profilu aprowizacji na stronie ustawień projektu, należy skonfigurować go tak, aby używał tego samego certyfikatu zespołu i podpisu, co aplikacja hosta. Jest to wymagane, jeśli chcesz przetestować swoją aplikację na urządzeniu z systemem iOS, a nie tylko na symulatorze. Jeśli tak jest w Twoim przypadku, musisz również upewnić się, że urządzenie z systemem iOS używane do testowania nie zostanie zablokowane z powodu braku aktywności, ponieważ może to spowodować zawieszenie się integracji bez powiadomienia.
Teraz jesteśmy na karcie „Urządzenia”, która nie wymaga konkretnego wyjaśnienia. Po prostu wybierz jedno, wiele lub wszystkie urządzenia (iOS i symulator), na których chcesz przetestować swój kod. Możesz także sprawdzić, czy uruchamiać testy na wielu urządzeniach równolegle, czy sekwencyjnie. Aby to skonfigurować, należy wziąć pod uwagę potrzeby projektu (niezależnie od tego, czy celujesz w określony zestaw urządzeń, czy wszystkie obsługiwane urządzenia z systemem iOS), a także zasoby sprzętowe serwera.
Na karcie Argumenty . nie ma potrzeby jawnego określania czegokolwiek, ponieważ będziemy używać tylko wbudowanych zmiennych środowiskowych.
Na koniec na karcie Wyzwalacze wprowadzimy jeden skrypt przed i po integracji. Pierwsza jest po to, aby pomóc nam w debugowaniu na wypadek, gdybyśmy napotkali jakieś problemy. Jest to właściwie ten, którego już używaliśmy:
#!/bin/sh set printenv
Drugi to ten, który powiadomi nas w przypadku niepowodzenia co najmniej jednego z naszych testów w obecnej integracji. Upewnij się, że jest ustawiony na uruchamianie tylko w przypadku niepowodzeń testu. I wpisz:
#!/bin/sh echo "$XCS_TEST_FAILURE_COUNT test(s) failed for $XCS_BOT_NAME bot on build $XCS_INTEGRATION_NUMBER" echo "You can see bot integration at:" echo "https://$HOSTNAME/xcode/bots/$XCS_BOT_TINY_ID/integrations/$XCS_INTEGRATION_TINY_ID"
Jest kilka rzeczy, które należy tutaj wyjaśnić. Po pierwsze, zmienne $HOSTNAME przechowują wartość w następującym formacie: nazwa-komputera.lokalny. Oczywiście łącze działałoby tylko wtedy, gdy można było połączyć się z tym serwerem za pośrednictwem sieci lokalnej. Ponadto najprawdopodobniej otrzymasz ostrzeżenie o zabezpieczeniach w przeglądarce podczas odwiedzania tego linku, ponieważ jest to połączenie https z miejscem docelowym, któremu nie można ufać. Wreszcie, jest to tylko punkt wyjścia do skryptu „Niepowodzenie testu”. Możesz wysłać wiadomość e-mail do całego zespołu programistów lub otworzyć problem z JIRA za pomocą żądania API lub cokolwiek innego, co uważasz za najbardziej odpowiednie i produktywne.
Zawijanie
Mamy nadzieję, że ten artykuł zachęcił Cię do poświęcenia czasu na poznanie możliwości Xcode Server poza zwykłym tworzeniem aplikacji. Chociaż ten post mógł nie pomóc ci dokładnie tak, jak chciałeś lub oczekiwałeś, celem było wprowadzenie cię w otwarty sposób korzystania z wbudowanych środowisk i zmiennych Xcode Server w celu osiągnięcia wyższego poziomu automatyzacji.
Istnieje wiele usług innych firm, które zapewniają większą funkcjonalność i mogą wykonać dla Ciebie o wiele więcej pracy, w tym Fabric, Bluepill i Fastlane. Ale nieuchronnie poleganie na stronie trzeciej wprowadza do projektu nową zależność i wymaga czasami prostej, a czasami złożonej instalacji i konfiguracji. Opisane tutaj techniki wymagają tylko narzędzi już zainstalowanych na każdym komputerze Mac, więc nie wymaga czasu na konfigurację poza konfiguracją samych botów, które będą uruchamiać Twoje automatyczne kompilacje!