Integrarea continuă iOS cu serverul Xcode explicată
Publicat: 2022-03-11Introducere
Înainte de Xcode 9, folosirea instrumentelor de integrare continuă Apple era un proces obositor și complex care necesita achiziționarea și instalarea unei aplicații suplimentare pentru macOS Server. Acest lucru i-a determinat pe mulți dezvoltatori să renunțe la ideea integrării continue pentru proiectele lor iOS sau să recurgă la soluții terțe, cu niveluri de succes foarte diferite.
Cu toate acestea, după ce Xcode 9.0 a fost lansat în septembrie 2017, procesul a fost mult simplificat, inclusiv opțiunea de semnare automată a codului, iar acum este complet integrat în Xcode. Prin urmare, nu necesită aplicații sau instrumente suplimentare.
În timp ce soluțiile de la terți precum Fastlane, Bluepill etc. sunt de mare ajutor și pot face o mulțime de muncă groaznică pentru dvs., acest articol va explora capabilitățile utilizării instrumentelor Xcode și Apple numai pentru nevoile dvs. de integrare continuă. Vom folosi, de asemenea, semnarea manuală a codului, deoarece aceasta pare adesea a fi o problemă pentru mulți oameni, iar semnarea automată tinde să nu fie soluția optimă atunci când vine vorba de configurații multiple de build.
Notă: Acest articol se bazează pe Xcode 9.4.1 și se concentrează pe dezvoltarea aplicației iOS, dar o mare parte este aplicabilă pentru Xcode 10 (disponibil în prezent ca versiune beta 5) și dezvoltarea aplicației macOS.
Configurarea serverului Xcode
Pe lângă simplificarea procesului real de integrare, Xcode 9 a simplificat și procesul de configurare a serverului Xcode.
Lansați aplicația Xcode pe computerul dvs. macOS care a fost desemnat ca server CI și deschideți Preferințe.
Navigați la ultima filă, numită Server & Bots .
Activați capabilitățile serverului Xcode făcând clic pe comutatorul din colțul din dreapta sus. Apoi, vi se va cere să selectați un utilizator care să ruleze și să execute scripturi de compilare pe această mașină. Probabil că este o idee bună să ai un utilizator dedicat doar pentru acest scop, în loc să folosești unul preexistent.
Rețineți că acest utilizator trebuie să fie conectat la sistem pentru ca orice bot Xcode să poată rula. După conectare, ar trebui să vedeți un cerc verde lângă numele de utilizator.
Asta e! Să aruncăm o privire mai atentă la roboții Xcode.
Cum se configurează Xcode Bots
Acum sunteți gata să începeți configurarea boților Xcode pentru a rula pe acest server. Acest lucru se poate face pe orice mașină de dezvoltare conectată la aceeași rețea cu serverul.
Deschideți Xcode pe mașina dvs. de dezvoltare și faceți clic pe Xcode > Preferințe din meniul de sus. Apoi, accesați fila Conturi și faceți clic pe pictograma + din colțul din stânga jos. Selectați Xcode Server din caseta de dialog care apare.
Pentru a crea un bot, pur și simplu deschideți proiectul în Xcode și alegeți opțiunea Produs > Creare bot... din meniul de sus. Configurarea botului are o serie de pași și îi vom explora în secțiunile următoare.
Automatizarea distribuției aplicațiilor
Una dintre cele mai frecvente aplicații de automatizare a construcției de aplicații iOS este configurarea unui bot pentru a încărca o aplicație pe o platformă de distribuție iOS, cum ar fi TestFlight, Fabric etc.
După cum am explicat mai devreme, acest articol va explora doar încărcarea în App Store Connect și descărcarea direct de pe serverul dvs. Xcode, deoarece acestea sunt instrumentele native Apple pentru distribuirea aplicațiilor iOS.
App Store Conectați distribuția folosind Xcode
Înainte de a configura un bot, asigurați-vă că aveți o înregistrare a aplicației App Store Connect care se potrivește cu ID-ul pachetului al proiectului dvs. de dezvoltare a aplicației. De asemenea, este de remarcat faptul că fiecare build trebuie să aibă un identificator unic constând din versiunea build și numărul build. Vom explora cum să ne asigurăm că aceste condiții sunt îndeplinite atunci când discutăm despre setările botului Xcode mai târziu.
Pasul 1: Configurarea configurației corecte de construcție este pasul crucial pentru a obține ceea ce doriți. Asigurați-vă că selectați schema și configurația care generează aplicația pe care doriți să o încărcați în App Store Connect. Aceasta include să vă asigurați că configurația de compilare utilizează ID-ul pachetului corespunzător care este înregistrat în portalul Apple Developer al echipei dvs. (acesta este folosit pentru semnarea codului), precum și în portalul dvs. App Store Connect (acesta este folosit pentru încărcarea automată a aplicației) .
Pasul 2: În timp ce suntem încă în fila „Configurare”, trebuie să specificăm opțiunile de export. Vom explora lista de proprietăți cu opțiuni de export, așa că asigurați-vă că este selectat „Utilizați opțiunile de export personalizate lista”.
Pasul 3: Acum este momentul să facem lista noastră de proprietăți cu opțiuni de export. O listă completă de chei care vor fi utilizate în acest fișier este disponibilă dacă introduceți xcodebuild --help
, dar le vom explora pe cele utilizate în această configurație bot aici:
-
compileBitcode
– Bitcode este formatul de ieșire intermediar al Apple pentru codul sursă al aplicației. Cu alte cuvinte, este formatul în care codul sursă este convertit înainte de a fi compilat în cod de mașină pentru o anumită arhitectură. Acesta își propune să aibă un singur container de cod care să poată fi optimizat în continuare dacă se face o optimizare în setul de instrucțiuni și, de asemenea, să îl poată compila în arhitecturi viitoare din același format. Cu toate acestea, acest lucru nu are niciun efect asupra aplicației dvs. Depinde de dvs. să decideți dacă doriți să îl activați sau nu. -
method
– Acest argument specifică ce tip de produs exportați. Apple distinge produsele după publicul desemnat — dezvoltarea vă permite să îl instalați doar pe dispozitivele specificate în profilul de furnizare, întreprinderea permite tuturor să le instaleze, dar trebuie să aibă încredere în mod explicit în acest profil de dezvoltare înainte de a rula aplicația, iar magazinul de aplicații este pentru distribuindu-l în App Store sau App Store Connect, așa că vom folosi această valoare. -
provisioningProfiles
– Acest lucru se explică de la sine. Dar există câteva lucruri de remarcat aici: Profilurile de furnizare din lista de proprietăți cu opțiuni de export sunt un dicționar în care o cheie corespunde ID-ului pachetului al unui produs, iar valoarea corespunde numelui profilului de furnizare utilizat pentru a-l semna în cod. -
signingCertificate
– Un alt argument care se explică de la sine. Valoarea acestui câmp poate fi un nume complet de certificat sau un hash SHA-1. -
teamID
– Un alt argument care se explică de la sine. Acesta este identificatorul de 10 caractere pe care Apple l-a emis organizației dvs. atunci când v-ați înscris la programul Apple Developer. -
uploadBitcode
– Dacă încărcați sau nu codul de biți (dacă ați optat pentru compilarea în el), astfel încât să poată fi utilizat în AppStore Connect pentru a genera noi versiuni optimizate sau versiuni pentru arhitecturi viitoare. -
uploadSymbols
– Încarcă simbolurile dvs. de depanare, astfel încât să puteți obține un raport de blocare semnificativ, mai degrabă decât doar o descărcare de memorie și o stivă de asamblare.
Deci, acum, lista de proprietăți cu opțiuni de export ar putea arăta cam așa:
<?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>
Pasul 4: Alegeți .plist pe care l-ați creat ca listă de proprietăți cu opțiuni de export.
Pasul 5: Urmează fila „Programare” – configurați-o în funcție de preferințele dvs.
Pasul 6: În fila Semnare, asigurați-vă că debifați opțiunea „Permite serverului Xcode să-mi gestioneze certificatele și profilurile” și încărcați singur un certificat de semnare și un profil de furnizare corespunzătoare, pe pagina Certificate și profiluri .
Pasul 7: Fila Dispozitive ar trebui lăsată așa cum este, deoarece încărcăm aplicația în loc să o testăm.
Pasul 8: Fila Argumente vă permite să setați în mod explicit argumente xcodebuild sau variabile de mediu care pot fi utilizate în scripturile dvs. de compilare sau pre-integrare și post-integrare.
Pasul 9: În sfârșit, ajungem la fila Triggers , care este și ultima filă în configurarea botului de integrare continuă Xcode. Acesta este cel mai puternic instrument din arsenalul Xcode Server. Pentru început, îmi place să adaug următoarele două comenzi ca script de pre-integrare:
#!/bin/sh set printenv
Prima imprimă toate variabilele pe care Xcode Server le folosește și valorile acestora în rularea curentă de integrare. Al doilea imprimă toate variabilele de mediu și valorile acestora. După cum era de așteptat, acest lucru poate fi util în depanarea scripturilor dvs., așa că îl numesc în mod potrivit „informații de depanare”.

Amintiți-vă că am menționat că trebuie să ne asigurăm că fiecare versiune încărcată în App Store Connect trebuie să aibă o versiune unică de versiune și o pereche de numere de versiune. Putem folosi instrumentul încorporat PlistBuddy, dar avem nevoie și de o modalitate de a avea un număr unic de versiune. Un lucru care este întotdeauna prezent în timpul integrării Xcode Server - și este, de asemenea, convenabil unic - este numărul de integrare, deoarece este incrementat automat. Vom crea un alt script de pre-integrare, numit „set build number” cu următorul conținut pentru a ne asigura că avem de fiecare dată un număr unic de build:
#!/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}"
Dacă utilizați CocoaPods și ați ales să nu trimiteți directorul Pods în DVCS, ar trebui să includeți și un script de preintegrare cu următorul conținut:
#!/bin/sh cd $XCS_PRIMARY_REPO_DIR pod install
Pasul 10: Aproape am terminat, dar nu am specificat nicăieri că vrem să încărcăm versiunea în AppStore Connect sau în ce cont. În acest scop, vom adăuga un script de post-integrare și un alt instrument încorporat, numit Application Loader. Pune următoarele în script:
#!/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
este o variabilă Xcode Server și conține calea către aplicația care a fost creată în rularea curentă de integrare. Cu toate acestea, $TESTFLIGHT_USERNAME
și $TESTFLIGHT_PASSWORD
nu sunt nici variabile de sistem, nici de server Xcode. Acestea trebuie să fie configurate de dvs. și să aibă valoarea ID-ului și parolei Apple. Din păcate, Apple a întrerupt suportul pentru generarea unei chei API pentru încărcarea versiunii AppStore Connect. Deoarece acestea sunt informații confidențiale, este cea mai bună practică să o configurați direct pe serverul Mac (presupunând că este a dvs.) ca o variabilă de mediu, mai degrabă decât în configurația bot Xcode Server.
Distribuția serverului Xcode
Botul de distribuție Xcode Server utilizează de fapt aceeași configurație ca cea pentru distribuția App Store Connect, cu excepția scripturilor de post-integrare. Cu toate acestea, descărcarea aplicației și instalarea acesteia pot fi încă dificile. Încă trebuie să vă asigurați că profilul de furnizare cu care v-ați semnat aplicația permite instalarea aplicației pe dispozitivul pe care îl utilizați.
Cu aceasta, va trebui să deschideți Safari pe dispozitivul iOS și să navigați la tabloul de bord web al serverului Xcode Server. De exemplu, dacă numele serverului dvs. este „Server Mac”, îl puteți găsi la „nume-server-mac.local/xcode” dacă vă aflați în aceeași rețea cu serverul. Acolo, veți găsi o listă cu toți roboții dvs. Xcode și statisticile celor mai recente integrări ale acestora.
Selectați-o pe cea care a creat aplicația pe care doriți să o descărcați. Pe următorul ecran, veți avea două butoane — Instalare și Profil . Dacă este prima dată când descărcați de pe acest server, trebuie să faceți clic pe Profil pentru a adăuga certificatul acestuia la lista de surse de încredere. După aceea, faceți clic pe butonul Instalare de pe aceeași pagină și veți fi întâmpinat cu dialogul de confirmare iOS „Sunteți sigur că doriți să instalați * pe dispozitiv?” Confirmați-l făcând clic pe Da , iar aplicația dvs. va fi instalată și rulată din ecranul de pornire.
Pentru iOS 10.3 și versiuni ulterioare , un motiv pentru care poate eșua cu „Nu se poate conecta la *.local” este că certificatul autosemnat trebuie să fie de încredere manual în Setări de pe dispozitivul de testare.
Urmați acești pași:
Pasul 1: Instalați certificate autosemnate de pe pagina de roboți a serverului Xcode de pe iPhone.
Pasul 2: Accesați Setările iPhone > General > Despre > Setări de încredere în certificat .
Pasul 3: Găsiți certificatele autosemnate ale serverului dvs. în secțiunea ENABLE FULL TRUST FOR ROOT CERTIFICATES și porniți comutatorul.
Pasul 4: Reveniți la pagina de integrare a botului de pe serverul Xcode, faceți clic pe Instalare .
Testarea automată a aplicațiilor Xcode Server
O altă utilizare excelentă a Xcode Server este testarea automată a aplicațiilor, fie că este vorba de testare unitară sau de UI. Pentru a face acest lucru, trebuie să aveți ținta adecvată configurată pentru proiectul dvs. Adică, trebuie să aveți o țintă care rulează teste unitare sau UI, în funcție de obiectivul dvs.
Procesul de configurare este același cu cel precedent, dar vom selecta opțiuni diferite. Prima diferență majoră este în fila Configurare . Evident, vom bifa casetele „Analiză” și „Testează”, deoarece acesta este scopul nostru principal. De asemenea, aș sfătui să nu arhivați și nici să exportați produsul cu acest bot. Este posibil să se realizeze atât testarea, cât și distribuția cu aceeași configurație de bot. Cu toate acestea, aceste două scenarii diferă în ceea ce privește rezultatul, precum și programul lor. Distribuția este adesea efectuată la sfârșitul ciclului.
Indiferent dacă lucrați în Scrum sau Kanban sau în alt cadru, ar trebui să existe un ciclu predefinit, bazat pe timp sau pe evenimente, la sfârșitul căruia ar trebui să fi exportat și utilizabil un produs. Pe de altă parte, ar trebui să rulați botul de testare la fiecare comitere, deoarece este prima ta linie de apărare împotriva regresiilor. Deoarece botul de testare este în mod evident rulat mai des, îmbinarea acelor doi roboți într-unul singur ar putea folosi rapid spațiul pe disc de pe serverul dvs. Și, de asemenea, fiecare integrare ar dura mai mult timp pentru finalizare.
Cu acest lucru în afara drumului, trecem la fila „Programare” și am abordat deja acest lucru în paragraful anterior. Deci, următorul subiect de interes este semnarea codului. Observați că, deși ținta dvs. de testare ar putea să afirme că nu are nevoie de profil de furnizare în pagina de setări a proiectului, ar trebui să o configurați pentru a utiliza aceeași echipă și certificat de semnare ca și aplicația gazdă. Acest lucru este necesar dacă doriți să testați aplicația pe un dispozitiv iOS și nu doar pe un simulator. Dacă acesta este cazul dvs., trebuie să vă asigurați, de asemenea, că dispozitivul iOS folosit pentru testare nu va fi blocat din cauza inactivității, deoarece acest lucru ar putea face ca rularea dvs. de integrare să se blocheze pe termen nelimitat fără a vă anunța.
Acum ne aflăm în fila „Dispozitive”, care nu are nevoie de explicații specifice. Pur și simplu selectați unul, mai multe sau toate dispozitivele (iOS și simulator) cu care doriți să testați codul. De asemenea, puteți verifica dacă să rulați teste pe mai multe dispozitive în paralel sau secvenţial. Pentru a configura acest lucru, ar trebui să luați în considerare nevoile proiectului dvs. (fie că vizați un anumit set de dispozitive sau toate dispozitivele iOS acceptate) și, de asemenea, resursele hardware ale serverului.
În fila Argumente . nu este nevoie să specificați nimic în mod explicit, deoarece vom folosi doar variabile de mediu încorporate.
În cele din urmă, în fila Declanșatoare , vom introduce un script de pre-integrare și unul de post-integrare. Primul este doar acolo pentru a ne ajuta să depanăm în cazul în care întâmpinăm unele probleme. Este de fapt cel pe care l-am folosit deja:
#!/bin/sh set printenv
Al doilea este cel care ne va anunța în cazul în care unul sau mai multe dintre testele noastre eșuează în integrarea curentă. Asigurați-vă că este setat să ruleze numai în cazul eșecurilor de testare. Și introduceți următoarele:
#!/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"
Sunt câteva lucruri care ar trebui explicate aici. În primul rând, variabilele $HOSTNAME stochează valoarea următorului format: computer-name.local. Evident, legătura ar funcționa numai dacă puteți ajunge la acel server prin rețeaua locală. De asemenea, cel mai probabil veți primi un avertisment de securitate din browser atunci când vizitați acest link, deoarece este o conexiune https către o destinație care nu poate fi de încredere. În cele din urmă, acesta este doar un punct de plecare pentru scriptul „Eșec de testare”. Puteți trimite un e-mail întregii echipe de dezvoltare sau puteți deschide problema JIRA printr-o solicitare API sau orice altceva considerați că este cel mai potrivit și mai productiv.
Încheierea
Sperăm că acest articol v-a încurajat să vă faceți timp pentru a explora capabilitățile serverului Xcode în afara pur și simplu de a construi o aplicație. Deși este posibil ca această postare să nu te fi ajutat exact așa cum ți-ai dorit sau te-ai așteptat, scopul a fost să te introducă într-o modalitate deschisă de utilizare a mediilor încorporate și a variabilelor Xcode Server pentru a obține un nivel mai ridicat de automatizare.
Există o mulțime de servicii terță parte care permit mai multe funcționalități și pot face mult mai multă muncă pentru dvs., inclusiv Fabric, Bluepill și Fastlane. Dar, în mod inevitabil, bazarea pe o terță parte introduce o nouă dependență în proiectul dvs. și necesită uneori o configurare și o configurare simple, alteori complexe. Tehnicile descrise aici necesită doar instrumente deja instalate pe fiecare Mac, așa că nu necesită timp de configurare în afară de configurarea roboților care vor rula versiunile automate!