{"id":11017,"date":"2014-10-07T14:06:34","date_gmt":"2014-10-07T12:06:34","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=11017"},"modified":"2014-10-07T14:11:17","modified_gmt":"2014-10-07T12:11:17","slug":"xcodeci-creare-un-continuous-integration-service-con-ruby-e-dropbox","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/xcodeci-creare-un-continuous-integration-service-con-ruby-e-dropbox\/","title":{"rendered":"XcodeCI: Creare un Continuous Integration service con Ruby e Dropbox"},"content":{"rendered":"<p>Per chi non sapesse cos&#8217;\u00e8 un &#8220;Continuous Integration service&#8221; (per gli amici anche &#8220;CI&#8221;) sappiate che si tratta di un software il cui compito \u00e8 quello di aiutare i team di sviluppatori a mettere in pratica la &#8220;Continuous Integration&#8221;. In breve recuperare dal sistema di versioning tutte le features scritte dai diversi programmatori del team, metterle insieme e creare la nuova build dell&#8217;applicazione da distribuire ai beta tester.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/XcodeCI.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/XcodeCI.png\" alt=\"XcodeCI\" width=\"1500\" height=\"480\" class=\"alignnone size-full wp-image-11030\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/XcodeCI.png 1500w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/XcodeCI-300x96.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/XcodeCI-1024x327.png 1024w\" sizes=\"auto, (max-width: 1500px) 100vw, 1500px\" \/><\/a><\/p>\n<p>Questo significa che a differenza di avere un numero limitato di builds in cui sono presenti magari decine di nuove funzinonalit\u00e0 da testare, avremo molte pi\u00f9 builds, ciascuna con un numero molto minore (teoricamente solo una) di nuove funzioni. Il vantaggio risultante \u00e8 misurabile in termini di testabilit\u00e0 del prodotto perch\u00e9 in questo modo \u00e8 facile risalire all&#8217;esatta versione del software in cui \u00e8 stato introdotto un bug, il lavoro del tester \u00e8 focalizzato su specifiche e circoscritte funzionalit\u00e0 e in generale tutto \u00e8 pi\u00f9 bello e organizzato \ud83d\ude42<\/p>\n<p>Tipicamente se utilizzate git e un workflow come git-flow (<a href=\"https:\/\/www.atlassian.com\/git\/tutorials\/comparing-workflows\/#!workflow-gitflow\" target=\"_blank\">https:\/\/www.atlassian.com\/git\/tutorials\/comparing-workflows\/#!workflow-gitflow<\/a>) siete gi\u00e0 a buon punto, perche&#8217; non vi resta che eseguire una build ogni volta che un\u00a0feature-branch\u00a0viene integrato nel vostro\u00a0master-branch,\u00a0in questo modo avrete una nuova versione dell&#8217;app per ciascuna nuova funzionalit\u00e0.<\/p>\n<p>Quando si parla di Continuous Integration service il primo nome che viene in mente \u00e8 quello di Jenkins (<a href=\"http:\/\/jenkins-ci.org\/\" target=\"_blank\">http:\/\/jenkins-ci.org\/<\/a>) una tra le pi\u00f9 diffuse piattaforme che assolve perfettamente a questo scopo. Jenkins \u00e8 in grado di buildare anche progetti iOS a patto di installare e configurare l&#8217;apposito plugin (<a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Xcode+Plugin\" target=\"_blank\">https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Xcode+Plugin<\/a>) ed \u00e8 anche free. L&#8217;unico lato negativo \u00e8 che non \u00e8 proprio semplice da configurare e probabilmente far\u00e0 molto pi\u00f9 di quello che realmente vi serve.<\/p>\n<p>Altrimenti potete usare un servizio esterno come travis-ci\u00a0<a href=\"https:\/\/travis-ci.org\/\" target=\"_blank\">https:\/\/travis-ci.org\/<\/a>\u00a0il problema in questo caso \u00e8 che per utilizzare il servizio con i vostri progetti privati dovete pagare la cifra non indifferente di 129 dollari al mese.<\/p>\n<p>Ovviamente esiste un&#8217;altra alternativa, cio\u00e8 quella di farvi da voi uno script che faccia esattamente quello che vi serva&#8230; io c&#8217;ho provato ed ho deciso di condividere con voi il risultato nella speranza che possa essere utile a qualcuno.<\/p>\n<p>Il codice sorgente \u00e8 disponibile qui: <a href=\"https:\/\/github.com\/ignazioc\/xcodeci\" target=\"_blank\">https:\/\/github.com\/ignazioc\/xcodeci<\/a>, il linguaggio utilizzato \u00e8 Ruby, ho voluto infatti approfittare di questo progetto per approfondire un po&#8217; questo linguaggio.<\/p>\n<p>xcodeci verifica ciclicamente (default ogni 5 minuti) uno o pi\u00f9 repository git e quando su uno specifico branch viene rilevato un nuovo commit, parte la procedura di build del repository ed esecuzione dei tests. Alla fine delle operazioni di build vengono\u00a0generati automaticamente il file *.ipa e il file manifest.plist, che vengono poi salvati nella cartella &#8220;public&#8221; \u00a0di dropbox.<\/p>\n<p>Quando tutti i progetti sono stati compilati viene generato un report html con le informazioni sul processo di build e il link per installare l&#8217;applicazione tramite OTA. Il report viene anch&#8217;esso salvato nella cartella pubblica di dropbox cos\u00ec che tutti coloro in possesso del link potranno installare le vostre beta.<\/p>\n<p>Mentre lo script \u00e8 attivo in console potrete vedere lo stato di esecuzione delle diverse operazioni:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-11018 size-full\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-01.png\" alt=\"creare-un-conituous-integration-service-con-ruby-e-dropbox-01\" width=\"552\" height=\"394\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-01.png 552w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-01-300x214.png 300w\" sizes=\"auto, (max-width: 552px) 100vw, 552px\" \/><\/a><\/p>\n<p>mentre al termine dell&#8217;esecuzione il report si presenter\u00e0 cos\u00ec:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11019\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-02.png\" alt=\"creare-un-conituous-integration-service-con-ruby-e-dropbox-02\" width=\"1600\" height=\"242\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-02.png 1600w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-02-300x45.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-02-1024x154.png 1024w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\" \/><\/a><\/p>\n<h2>Installazione e configurazione<\/h2>\n<p>La prima cosa da fare \u00e8 quella di clonare il repository git <a href=\"https:\/\/github.com\/ignazioc\/xcodeci\">https:\/\/github.com\/ignazioc\/xcodeci<\/a> in una cartella del vostro mac. Potete farlo da terminale digitando:<\/p>\n<pre class=\"lang:sh decode:true \">git clone https:\/\/github.com\/ignazioc\/xcodeci<\/pre>\n<p>Il secondo step \u00e8 quello di installare le\u00a0dipendenze, il progetto richiede alcune gemme Ruby ed xctool. Potete installare le prime direttamente eseguendo da terminale (all&#8217;interno della cartella del progetto)<\/p>\n<pre class=\"lang:sh decode:true\">bundle install<\/pre>\n<p>Per installare xctool il metodo pi\u00f9 semplice \u00e8 quello di usare homebrew, il sistema di pacchetti per MacOS, se non l&#8217;avete gi\u00e0 installato trovate le info qui: <a href=\"http:\/\/brew.sh\/\">http:\/\/brew.sh\/<\/a>. Digitate quindi:<\/p>\n<pre class=\"lang:sh decode:true\">brew install xctool<\/pre>\n<h2>Configurazione e avvio<\/h2>\n<p>Una volta installate le dipendenze potete lanciare lo script, se non vengono trovati file di configurazione lo script ve ne genera uno di esempio. All&#8217;interno della cartella del progetto digitiamo quindi:<\/p>\n<pre class=\"lang:sh decode:true \">.\/bin\/xcodeci<\/pre>\n<p>Un messaggio vi informer\u00e0 della creazione del file di esempio.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11020\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-03.png\" alt=\"creare-un-conituous-integration-service-con-ruby-e-dropbox-03\" width=\"956\" height=\"80\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-03.png 956w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-03-300x25.png 300w\" sizes=\"auto, (max-width: 956px) 100vw, 956px\" \/><\/a><\/p>\n<p>Il file di configurazione si chiama xcodeci.conf.yaml e lo trovate all&#8217;interno della cartella ~\/.xcodeci<\/p>\n<p>Si tratta di un file di testo con sintassi yaml (<a href=\"http:\/\/www.yaml.org\/\" target=\"_blank\">http:\/\/www.yaml.org\/<\/a>).<\/p>\n<p>Il file di esempio mostra alcuni commenti in inglese, ma la configurazione \u00e8 davvero molto semplice, questo \u00e8 come potrebbe apparire un file corretto:<\/p>\n<pre class=\"lang:yaml decode:true \">\r\n---\r\nApp_Config:\r\n  :DROPBOX_FOLDER:    '\/Users\/ignazio\/Dropbox\/Public\/'\r\n  :DROPBOX_USER_ID:   '792862'\r\nSampleApp1:\r\n  :REPO_URL:         'git@github.com:ignazioc\/sample_repo_1.git'\r\n  :APP_NAME:         'SampleApp-1'\r\n  :TARGET_BRANCH:    'master'\r\n  :WORKSPACE:        'SampleApp 1.xcworkspace'\r\n  :SCHEME:           'SampleApp 1'\r\n<\/pre>\n<p>La prima parte raccoglie due informazioni relative al vostro mac:<\/p>\n<ul>\n<li><strong>:DROPBOX_FOLDER:<\/strong> non \u00e8 altro che il path della vostra cartella public, verr\u00e0 usata per salvare i file ipa e i manifest.<\/li>\n<li><strong>:DROPBOX_USER_ID:<\/strong> \u00c8 invece un numero che dropbox associa al vostro utente, lo script lo utilizza per generare &#8220;a mano&#8221; i link alla vostra cartella public.<\/li>\n<\/ul>\n<p>Per trovare il vostro user_id provate a condividere qualsiasi file dentro la vostra cartella public, il link che otterrete \u00e8 in questa forma:<\/p>\n<pre class=\"lang:sh decode:true \">https:\/\/dl.dropboxusercontent.com\/u\/792862\/avatar_grumpy.png<\/pre>\n<p>quel numero dopo la &#8216;u&#8217; \u00e8 il vostro user_id.<\/p>\n<p>Seguono poi uno o pi\u00f9 sezioni relative ai progetti da monitorare:<\/p>\n<ul>\n<li><strong>:REPO_URL:<\/strong> url del repository git.<\/li>\n<li><strong>:APP_NAME:<\/strong> Viene usato per generare le sotto-cartelle dove salvare i flie ipa, non usare spazi nel nome.<\/li>\n<li><strong>:TARGET_BRANCH:<\/strong> Branch da monitorare, solitamente \u00e8 master.<\/li>\n<li><strong>:WORKSPACE:<\/strong> Nome del workspace, non sono gestiti progetti senza workspace.<\/li>\n<li><strong>:SCHEME:<\/strong> Lo schema da buildare<\/li>\n<\/ul>\n<p>Quando avrete il vostro file di configurazione provate a ri-eseguire lo script, se tutto \u00e8 ok lo script eseguir\u00e0 un loop ogni 5 minuti in cui prover\u00e0 a buildare tutti i progetti inseriti nel file di configurazione.<\/p>\n<p>Alla fine di ciascuna iterazione verr\u00e0 mostrato il link (sar\u00e0 sempre lo stesso) dove trovare il report html:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11021\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-04.png\" alt=\"creare-un-conituous-integration-service-con-ruby-e-dropbox-04\" width=\"1326\" height=\"114\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-04.png 1326w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-04-300x25.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/creare-un-conituous-integration-service-con-ruby-e-dropbox-04-1024x88.png 1024w\" sizes=\"auto, (max-width: 1326px) 100vw, 1326px\" \/><\/a><\/p>\n<p>Condividete il link con i vostri beta tester e rilassatevi \ud83d\ude42<\/p>\n<h2>Alcune note sul progetto:<\/h2>\n<ul>\n<li>Per la distribuzione adhoc dovrete comunque aggiungere i device sul sito apple e configurare il progetto in modo che usi il corretto provisioning, niente miracoli per quello purtroppo \ud83d\ude42<\/li>\n<li>Lo script non supporta al momento progetti che non siano legati ad un workspace, in ogni caso vista la diffusione di cocoapods non credo sia una limitazione rilevante.<\/li>\n<li>Ogni critica e\/o suggerimento \u00e8 ben accetto, commentate qui oppure forkate il repository su github.<\/li>\n<li>Potete installare anche con un <strong>gem install xcodeci<\/strong> senza usare git e senza preoccuparvi di dove sia l&#8217;eseguibile, perch\u00e9 vi basta digitare <strong>xcodeci<\/strong> da commandline.<\/li>\n<\/ul>\n<p>Alla prossima e buona programmazione a tutti!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Per chi non sapesse cos&#8217;\u00e8 un &#8220;Continuous Integration service&#8221; (per gli amici anche &#8220;CI&#8221;) sappiate che si&#8230;<\/p>\n","protected":false},"author":53,"featured_media":11030,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[8,30],"tags":[1394,1393,1396,1395],"class_list":["post-11017","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guide-varie","category-materiale-open-source","tag-build-xcode","tag-conituous-integration-service","tag-test-ios-app","tag-versioning"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11017","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=11017"}],"version-history":[{"count":12,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11017\/revisions"}],"predecessor-version":[{"id":11034,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11017\/revisions\/11034"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/11030"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=11017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=11017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=11017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}