Continuous Integration Script Enhancements

In deze tutorialserie zullen we een zelden besproken (maar zeer waardevol) proces van het ontwikkelen van software onderzoeken dat teleurstellend afwezig is in de iOS- en mobiele wereld: continue integratie.


Ook verkrijgbaar in deze serie:

  1. Continue integratie: serie-introductie
  2. Continue integratie: Tomcat-installatie
  3. Continue integratie: Hudson-installatie
  4. Continuous Integration: Scripting Xcode Builds
  5. Continuous Integration: Script Enhancements

Waar we gebleven zijn

In deel 1 bespraken we het concept van continue integratie en hoe dit ons kan helpen om software sneller te ontwikkelen. Deel 2 ging door het installeren van Apache Tomcat, de webserver waarop onze CI-serversoftware draait. In deel 3 hebben we Hudson geïnstalleerd en geconfigureerd om ons project te volgen en het bouwproces te starten wanneer we onze projectrepository updaten. In deel 4 schreven we een basissamenstellingscript dat ons project compileerde en een IPA-bestand genereerde.


Waar te gaan vanaf hier?

Op dit moment hebben we een functionerend build-script, maar er is zoveel meer dat we kunnen doen! Deze tutorial is een beetje anders dan de andere. In plaats van dat u een reeks stappen doorloopt, zal er een verzameling nuttige toevoegingen zijn die u aan uw script kunt toevoegen en, afhankelijk van uw omstandigheden, kunt u ervoor kiezen ze toe te voegen of niet.


Optelling 1: wijzig je script om functies te gebruiken

Bash-scripts kunnen functies gebruiken net als andere talen. Grote build-scripts kunnen behoorlijk lang worden, dus het is belangrijk om het zo veel mogelijk te organiseren. Functies zijn een geweldige manier om dit te doen.

Laten we al onze bestaande code in een functie plaatsen met de naam "buildApp". Open uw script en voer de volgende code in:

 function buildApp # bestaande code gaat hier

Om onze "buildApp" -functie aan te roepen, voert u eenvoudig het volgende in onder de functieverklaring:

 buildApp

Naarmate u meer functionaliteit toevoegt aan uw script, kunt u deze plaatsen in functies met verschillende namen, zoals "distributeApp" of "signApp".


Optelling 2: Uploaden naar TestFlight

Een van de meest populaire services die ontwikkelaars gebruiken om hun apps te testen, is TestFlight. TestFlight is een geweldige (gratis!) Online service waarmee ontwikkelaars eenvoudig hun ad-hoc IPA kunnen uploaden en TestFlight zorgt voor de distributie.

TestFlight biedt een upload-API die we kunnen bellen vanuit ons bash-script. Dat betekent dat wanneer we een nieuwe build voltooien, we deze onmiddellijk kunnen uploaden naar de testvlucht en onze testers informeren dat er een nieuwe build beschikbaar is.

Zorg er eerst voor dat u een account hebt en verkrijg uw API-token en teamtoken. Zodra dit is gebeurd, voegt u de API- en team-sleutel als variabelen toe aan de bovenkant van uw script.

Ten tweede moeten we het * .dysm-bestand voorbereiden om te uploaden. Als u niet meer weet waar het * .dysm-bestand voor is, raadpleegt u artikel 4 voor een opfriscursus. Het * .dysm-bestand moet worden gecomprimeerd voordat het kan worden geüpload naar TestFlight of Apple, dus het is een goed idee om dit als onderdeel van het bouwproces te doen.

Voeg de volgende code toe na uw opdracht "xcodebuild":

 # zip dYSM-bestand voor distributie cd "$ build_location / sym.root / $ configuration- $ sdk /" || "geen map" rm -f "$ appname.app.dSYM.zip" zip -r "$ appname.app.dSYM.zip" "$ appname.app.dSYM"

De bovenstaande code verandert gewoon de map naar de locatie van het * .dysm-bestand en verwijdert eventuele zip-bestanden die al eerder bestonden. Vervolgens maakt het een ZIP van het * .dysm-bestand.

Nadat dit is toegevoegd, voegt u de volgende functie toe aan uw build-script:

 function deployToTestFlight / usr / bin / curl "http://testflightapp.com/api/builds.json" \ -F file = @ "$ build_location / $ appname.ipa" \ -F dsym = @ "$ build_location / sym .root / $ configuratie- $ sdk / $ appname.app.dSYM.zip "\ -F api_token =" $ TESTFLIGHT_APIKEY "\ -F team_token =" $ TESTFLIGHT_TEAM "\ -F notes =" $ appname geüpload via de testflight upload API "\ -F notify =" False "

Als u nu in TestFlight moet implementeren, hoeft u alleen maar uw "deployToTestFlight" -functie aan te roepen nadat een build is gegenereerd.

Voor volledige informatie over de upload-API van TestFlight, kijk op https://testflightapp.com/api/doc/.


Aanvulling 3: Werken met de Info.plist

Soms moeten we waarden uit het bestand * .plist wijzigen of lezen. We willen bijvoorbeeld builds opslaan voor elke versie van de app. We kunnen de app-versie lezen in het PLIST-bestand en opslaan in een geschikte map. We willen misschien ook het pictogram bewerken dat voor een specifieke build of soms zelfs de bundel-ID is gebruikt.

Om de bundel-ID in te stellen (d.w.z. de oorspronkelijke waarde te overschrijven), is de opdracht:

 / usr / libexec / PlistBuddy -c "Set: CFBundleIdentifier $ bundle_id" Info.plist

Zoals je kunt zien aan de bovenstaande afbeelding, is "CFBundleIdentifier" de sleutel voor de bundel-ID-waarde, dus we "stellen" het eenvoudig als $ bundle_id waarde is.

Als we een waarde uit de PLIST willen lezen en deze als een variabele in ons script willen instellen, is het een beetje lastiger. We moeten een beetje bash-trickery doen:

 app_version_number = $ (/ usr / libexec / PlistBuddy -c "Print: CFBundleVersion" Info.plist)

De bovenstaande code tussen haakjes drukt gewoon de waarde af voor 'CFBundleVersion' en het bash-script legt die waarde vast als een variabele en wijst deze toe aan de variabele 'app_version_number'.


Aanvulling 4: Een specifieke projectconfiguratie bouwen

In Xcode kunt u verschillende configuraties voor uw project gebruiken. Elke configuratie kan verschillende bouwinstellingen gebruiken, opties voor ondertekening van code, en zelfs anders compileren op basis van pre-processor macro's. Hoewel het maken van nieuwe configuraties, het aanpassen van de build-instellingen en het toevoegen van pre-processor-macro's buiten het bestek van deze zelfstudie valt, kan ik je laten zien hoe je ze kunt bouwen.

De standaardconfiguratie wanneer je bouwt is "Release", maar dit kan worden ingesteld met een speciale vlag bij het aanroepen van de opdracht "xcodebuild".


In dit voorbeeld hebben we een configuratie met de naam "Testen". Om te bouwen voor deze configuratie, passen we eenvoudig ons build-script aan op basis van het volgende:

 configuratie = "Testen" xcodebuild -target "$ appname" -configuratie "$ configuratie" OBJROOT = "$ build_location / $ app_version / $ configuration / obj.root" SYMROOT = "$ build_location / $ app_version / $ configuration / sym.root"

Hier bouwen we ons Xcode-project op basis van een specifieke configuratie en plaatsen het in zijn eigen map samen met zijn eigen versienummer (dat we kunnen verkrijgen door te kijken naar de info.plist, zie toevoeging 3).


Aanvulling 5: Werken met de sleutelhanger

Als u voor een middelgrote tot grote organisatie werkt, is de kans groot dat u meer dan één ontwikkelings- / distributiecertificaat gebruikt om uw apps te ondertekenen. Als u niet de controle heeft over het maken van deze certificaten, is er ook een kans dat alle certificaten de naam van uw bedrijf ergens in de certificaten hebben.

Dit is een probleem omdat de sleutelhanger het ondertekenen van een certificaat niet toestaat als het "dubbelzinnig" is. Gelukkig kunnen we de opdracht "security" gebruiken om certificaten toe te voegen en te verwijderen tijdens ons bouwproces.

Eerst moet u de relevante certificaten en hun privésleutels uit de sleutelhanger exporteren en toevoegen aan de scriptdirectory. Wanneer u uw certificaat en sleutel exporteert, vraagt ​​de sleutelhanger u om een ​​wachtwoordzin in te voeren. Voer een wachtwoordzin in en sla het * .p12-bestand op in de scriptdirectory van uw repository. Stel het * .p12-bestand in als variabele naam in uw script.


Ten tweede verwijdert u alle certificaten op de build-server die mogelijk conflicteren met het certificaat dat moet worden gebruikt.

Voeg ten slotte de volgende regel toe om het certificaat te importeren:

 beveiligingsimport "$ WORKSPACE / Scripts / $ CERTIFICATE_FILE.p12" -P "$ wachtwoord" -A -k ~ / Bibliotheek / Sleutelhangers / login.keychain

Deze regel importeert de aangewezen * .p12 in de login-sleutelhanger met het wachtwoord "$ wachtwoord".

Wanneer je klaar bent met de build, verwijder het dan uit de sleutelhanger zoals:

 beveiligingswissen-certificaat -c "$ certificaat"

Met behulp van de bovenstaande methode kunt u uw app meerdere keren samenstellen met meerdere certificaten die anders dubbelzinnig zouden zijn geweest.


Conclusie

Hoewel dit handige toevoegingen zijn aan elk build-script, zullen er altijd specifieke manieren zijn om het voor u beter te laten werken. Ik heb mijn best gedaan je de basisprincipes te leren en voldoende basis voor je te bieden om een ​​solide basis te hebben waarop je kunt experimenteren en verder kunt ontwikkelen.

Een script met alle hierboven beschreven stappen is te vinden op https://gist.github.com/1404526

Ik hoop dat je deze tutorialserie leuk vond en dat je CI en geautomatiseerde processen kunt implementeren in je ontwikkelworkflow. Ik hoop dat je veel blauwe bouwlichten hebt! :)