ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 151
Numărul 150 Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 53
Abonament PDF

Integrare continuă folosind Xcode Server

Horatiu Potra
iOS Developer @ 3Pillar Global



Lucian Teodorovici
iOS Developer @ 3Pillar Global



PROGRAMARE

În procesul de dezvoltare de software, una dintre practicile devenite din ce în ce mai comune, chiar necesare în majoritatea echipelor, este integrarea continuă. În funcție de tehnologie, integrarea continuă se poate realiza în mai multe moduri.

În acest articol vom prezenta o soluție la această problemă din punctul de vedere al dezvoltării aplicațiilor mobile pe platforma iOS. Soluția noastră se bazează pe Xcode Server și pe platforma online de distribuție Fabric.IO.

Ce este Integrarea Continuă ?

Integrarea continuă (Continous Integration) este o practică în care codul mai multor programatori dintr-un proiect este integrat într-o ramură partajată dintr-un sistem de versionare. Această practică a fost propusă pentru prima dată de către Grady Booch în anul 1991. Scopul integrării continue este să ajute la rezolvarea problemelor ce pot să apară când ramurile locale ale programatorilor trebuie să fie integrate în ramura principală a proiectului. Este recomandat ca programatorii să integreze ramura principală în ramurile locale o dată pe zi, în acest mod probabilitatea de a avea viitoare conflicte este redusă.

Integrarea continuă nu se referă doar la cele spuse anterior, ci acoperă și testarea unitară a funcționalității programului și a componentelor acestuia. Aceste teste pot să fie configurate astfel încât să ruleze de fiecare dată când o ramură este integrată în ramura principală a proiectului. O dată ce testele au fost rulate cu succes un executabil se poate crea pentru echipa de QA (quality assurance) unde aceștia pot rula mai multe teste manuale.

O altă practică recomandată este aceasta: în cazul în care codul din ramura locală are teste unitare și unul dintre programatorii din echipa integrează ramura principală a proiectului în ramura sa locală, este recomandat rularea respectivelor teste pentru a verifica dacă schimbările locale nu au făcut testele să raporteze erori.

Opțiuni de Integrare Continuă

Există mai multe sisteme care oferă integrare continuă și cel mai popular dintre acestea este Jenkins. Jenkins oferă multe extensii pentru rularea de scenarii (scripturi), conexiune cu diferite sisteme de versionare (git, svn), extensii pentru trimitere de notificări prin e-mail și multe altele. Pentru a afla mai multe despre Jenkins se poate citi consultând documentația oficială.

Xcode server și boți

Apple oferă o soluție pentru integrarea continuă sub forma serverului Xcode care face parte din mac OS Server. În serverul Xcode se pot crea boți pentru proiecte create în programul(IDE) Xcode. Acești boți pot fi configurați pentru a crea pachete de instalare a proiectului, rularea de teste și scenarii automate. Serverul Xcode poate fi folosit pentru aplicații care rulează pe sistemul de operare mac OS, iOS, TV OS și Watch OS, toate dezvoltate de către Apple. Avantajul serverului Xcode este foarte buna integrare a acestuia în mediul de dezvoltare de la Apple.

Serverul Mac OS poate să fie instalat din App Store sau din portalul de dezvoltator din programul de dezvoltare de la Apple. Mai multe detalii despre cum se instalează serverul Mac OS se pot găsi consultând documentația oficială.

O dată ce serverul Xcode este configurat se poate crea un bot pentru un anumit proiect prin deschiderea proiectului respectiv, apoi din meniul Product se alege opțiunea Create Bot

Apoi se urmează pașii din Wizard.

În primul rând noul bot are nevoie de un nume, apoi trebui specificat o adresă IP care reprezintă adresa mașinii unde serverul mac OS rulează.

După ce s-a efectuat logarea în sistemul de versionare folosit în proiect, trebuie specificată ramura din proiect pe care botul o va folosi. Pentru proiectul nostru am ales ramura develop, care este și ramura principală.

Următorul ecran, ilustrează opțiunile de configurare pentru crearea pachetului de instalare. Conform documentației de la Apple, schema agregă mai multe ținte de creare, o configurație de creare și teste de executat. Vizibilitatea schemei trebuie să fie publică pentru a fi vizibilă în botul Xcode. Pentru a face o schemă publică, în proiectul pentru care se dorește crearea botului, se face click pe itemul din stânga numelui proiectului și se alege opțiunea Manage Schemes

De aici se selectează opțiunea Shared pentru schema care se va folosi în bot.

După ce s-a selectat o schemă publică, acțiunea care ne interesează este "perform archive", dar se poate opta și pentru a analiza sau rula o suită de teste. Cleaning se referă la ștergerea cache-ului și a datelor temporare a proiectului. Pentru opțiunea de configurare se pot folosi setările din schemă sau se poate alege opțiunea "release", fiindcă țelul nostru e să distribuim aplicația unui grup de testatori, nu să o rulăm în modul debug. În cazul nostru, am selectat opțiunea "release" pentru schemă la pasul de creare a arhivei de instalare.

Următorul pas este de a decide când botul Xcode va crea pachetul de instalare. Am selectat opțiunea "On Commit", deoarece vrem ca de fiecare dată când o ramură, ce conține funcționalități noi, este integrată în ramura principală, un nou pachet de instalare să fie creat. Chiar dacă există multe opțiuni la categoria "Schedule" la finalul wizardului, botul va executa o integrare, indiferent de opțiunea aleasă. Acest lucru se va întâmpla o singură dată după ce botul a fost configurat. Ulterior se va respecta opțiunea aleasă în Schedule.

Ecranul de mai sus oferă opțiunea de a alege dispozitivele fizice sau simulatoare pe care testele vor fi rulate.

Pentru diferite scopuri se pot defini variabile de sistem, altele decât cele pe care le poți accesa din Xcode Server (i.e. XCS_INTEGRATION_ID, XCS_BOT_NAME, etc.).

Există patru tipuri de declanșatori:

  1. Scenarii pre-integrare,

  2. Scenarii post-integrare,

  3. Trimitere de e-mail la probleme noi,

  4. Trimitere de e-mail periodic.

Suntem interesați de al doilea tip de declanșatori pentru că vom crea un scenariu pentru setarea automată a numărului de versiune a aplicației (Figura 10). Pentru moment nu este obligatoriu să creăm scenarii post-integrare, vom acoperi acest aspect puțin mai târziu.

Creare automată (automatic building)

Când vine vorba despre aplicații pentru dispozitivele mobile se dorește ca noile funcționalități să ajungă pe mâna echipei de testare cât mai repede. Pentru a obține acest lucru există două opțiuni:

  1. trimiterea pachetului de instalare manual,

  2. implementarea unei soluții de integrare continuă care va trimite pachetul de instalare automat.

Folosirea unei infrastructuri de integrare continuă este mai rapidă decât trimiterea manuală. O astfel de soluție presupune ca de fiecare dată când se integrează cod în ramura principală a proiectului, se va crea un pachet de instalare și se vor rula teste. Apoi, acel pachet va fi trimis echipei de testare.

Numărul de versiune

Incrementarea numărului de versiune poate să fie automatizată cu ușurință folosind programul avgtool. Programul utilitar este folosit într-un scenariu shell (shell script) care este executat înainte de fiecare creare a unui pachet de instalare. Problema cu incrementarea automată a numărului de versiune este detectarea de către sistemul de versionare a unei noi schimbări, iar acea schimbare trebuie integrată manual. Pentru a evita această problemă, propunem ideea ca numărul de versionare să fie în concordanță cu numărul de integrare de la serverul Xcode. Valoarea este obținută dintr-o variabilă de sistem având numele "XCS_INTEGRATION_NUMBER".

Următorul scenariu (script) este adăugat la faza de creare a pachetului de instalare și este adăugat în ținta curentă din Xcode.

#!/bin/sh
if [ "${CONFIGURATION}" = "Release" ]; then
    agvtool new-version -all "$XCS_INTEGRATION_NUMBER"
fi

Note informative (release notes)

De obicei, notele informative constau într-un text care descriu ce funcționalități noi au fost introduse sau ce erori au fost corectate, iar notele se distribuie împreună cu pachetul de instalare. Cel mai frecvent, notele informative se introduc manual de către o persoană, dar noi am considerat că acest lucru poate să fie automatizat elegant.

Soluția noastră se bazează pe faptul că sistemul de versionare Git este foarte răspândit și folosit și pe faptul că procesul de dezvoltare urmărește modul de lucru din ramurile cu funcționalități (Feature Branch Workflow). Integrarea este declanșată de fiecare dată când o ramură cu funcționalități noi este integrată în ramura principală a proiectului. Notele informative sunt extrase din mesajele care sunt acompaniate cu noul codul din ramura pe care funcționalitățile au fost create și care nu se găsesc pe ramura principală. Prima data, verificăm dacă există fișierul "hash.txt" și dacă acesta conține un hash de commit. Pentru o înțelegere mai bună vom abrevia acest commit hash ca OCH (old commit hash). De asemenea, menționăm că HEAD se referă la ultimul commit de pe ramura principală. Identificare mesajului de commit pentru a fi adăugat în notele informative implică folosirea funcției "git log" furnizând două granițe ca parametru ce reprezintă două hashuri și anume de la OCH la HEAD. Rezultatul rulării acestei funcții este scris în fișierul "release_notes.txt" folosind un anumit format: numele autorului pentru commit și mesajul de commit. Mesajele de integrare explicite, care conțin cuvântul merge, nu sunt incluse. În cazul în care nu avem nici un mesaj textul "No changes since last build" este folosit pentru note informative. Apoi salvăm OCH în fișierul "hash.txt" și executăm distribuirea către testatori folosind platforma Fabric.IO.

Acțiunile descrise anterior sunt împachetate într-un scenariu shell care este rulat cu succes după fiecare împachetare (build). Pentru a permite acest lucru, programatorul trebuie să deschidă secțiunea "Triggers" din secțiunea "Edit Bot", se efectuează click pe butonul "+" și se selectează "Post-Integration Script"(Figura 12).

#!/bin/sh
CM_HASH=$(cat $XCS_SOURCE_DIR/hash.txt)
echo git --git-dir $XCS_SOURCE_DIR/<NAME_OF_GIT_PROJECT>/.git log --no-merges $CM_HASH..HEAD --format="%cn: %s" > RELEASE_NOTES

if [ "${RELEASE_NOTES}" = "" ]; then
RELEASE_NOTES = "No changes since last build."
fi                  

echo "${RELEASE_NOTES}" > $XCS_SOURCE_DIR/release_notes.txt

git --git-dir $XCS_SOURCE_DIR/<NAME_OF_GIT_PROJECT>/.git rev-parse HEAD > $XCS_SOURCE_DIR/hash.txt

"${XCS_SOURCE_DIR}/<PROJECT_CRASHLYTICS_PATH>/Crashlytics/submit" <API_KEY> <BUILD_SECRET> -groupAliases <TESTING_GROUP_NAME> -ipaPath "${XCS_PRODUCT}" -notesPath $XCS_SOURCE_DIR/release_notes.txt

Observații: XCS_SOURCE_DIR este o variabilă de sistem care conține calea până la directorul ce conține codul sursă din sistemul de versionare.

Concluzii

În urma implementării soluției descrise în articol, am învățat cum să integrăm git cu Xcode Server și să distribuim pachetul de instalare echipei de QA cu ajutorul platformei Fabric.IO.

Ușurința rulării testelor automate împreună cu raportarea de erori și distribuția rapidă a pachetului de instalare către echipa de QA sunt avantaje care ne vor determina să folosim această soluție de integrare continuă.

Bibliografie

  1. https://developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Schemes.html

  2. https://developer.apple.com/library/content/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/

NUMĂRUL 150 - Technologiile SAP ABAP

Sponsori

  • Accenture
  • BT Code Crafters
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects