Dolap iOS Uygulaması CI/CD süreçlerimiz
Dolap teknoloji ekibi olarak yaptığımız geliştirmeleri kullanıcılarımıza en kısa sürede ulaştırmayı çok önemsiyoruz. Bazı ekiplerimiz saatlik/günlük deploy çıkarken mobil platformların doğası gereği Dolap mobil uygulamalarında haftada bir güncelleme çıkıyoruz. Bu sayede daha küçük ve güvenli paketler çıkmış oluyoruz.
Dolap mobil uygulamalarında CI/CD süreçlerinde aktif olarak Bitrise kullanıyoruz. Pull Request kontrollerinden Release işlemlerine kadar her adımda kullanmaya gayret ediyoruz. Sık paket çıkmanın getirdiği ekstra eforu release sürecimizin geliştiricide olan kısmını Bitrise üzerinden yaparak hafiflettik. Uyguladığımız pratikleri ve süreçte öğrendiklerimizi paylaşmak istedik.
Bitrise kullandığımız alanlar;
- Unit Testlerin koşulması ve Pull Request kontrolleri.
- Test için paket çıkartma ve dağıtımı.
- Release adımları.
1- Unit Testlerin koşulması ve Pull Request kontrolleri.
Dolap’ta PR açarken bazı kurallarımız var. PR sürecindeki gitgelleri azaltmak için gözden kaçabilecek durumları Danger ile kontrol ediyoruz.
Danger; PR’ın içermesi gerekenleri kontrol etmenize yarayan bir araç. Eklentilerle genişletip bir çok işlemi Danger üzerinden yapabilirsiniz. Biz Unit Testlerin sonuçlarını PR’a yorum olarak eklemek için DangerXCodeSummary eklentisiyle birlikte kullanıyoruz. Diğer eklentileri buradan inceleyebilirsiniz.
DangerXCodeSummary; Build hatalarını, uyarıları ve test sonuçlarını Danger’a iletmenizi sağlar. Daha sonra Danger dosyanızda isterseniz bunlara özel kurallar da ekleyebilirsiniz. Örneğin “warning sayısı 10 dan fazlaysa fail olsun” gibi.
Bizim Danger Swift tercih sebeplerimiz;
- Danger File’a (Kuralları yazdığınız yer) kuralların swift dili ile yazılabiliyor olması.
- Swift Lint’in direkt içinde olması (Ruby versiyonuna eklenti olarak eklemeniz gerekiyor).
- Bitrise ile entegre çalışabilmesi.
- Her PR’da Unit Testleri koşabilir olmak.
- Code review sürecimizi hızlandırıyor olması.
Danger(Ruby) ile karşılaştırdığımızda gördüğümüz tek dezavantajı Danger Swift’in Bitrise eklentisi olmadığı için PR Check işlemi ~2 dk daha uzun sürüyor.
Danger Swift ile PR’da kontrol edebileceğiniz noktalar;
- Fail olan testler, build warning-error sayıları.
- Swift Lint uyarıları.
- Eklenen, çıkartılan, değiştirilen satır sayısı.
- Açılma, güncellenme, kapanma, mergelenme tarihi.
- Durumu; open, closed, merged, locked.
- Başlık ve açıklama alanı.
- Commitler ve commit mesajları.
- Commit, comment ve review sayıları.
- Review istenen kullanıcılar ve takımları.
- Bırakılan reviewler.
- Numarası.
- Açan kişi, atanan kişi.
- Milestone
Daha fazlası için dokümantasyonuna göz atabilirsiniz.
Süreç nasıl ilerliyor
Main branchine PR açıldığında Bitrise üzerinde “MainPRCheck” workflow’u tetikleniyor ve Danger dosyamıza yazdığımız kurallar çerçevesinde kontrol ediliyor ardından çıktıları PR’a yorum olarak ekleniyor.
workflow: Bitrise üzerindeki adımların oluşturduğu akış örnek için tıklayın
Kurallarımız ve Danger dosyamız
Fail ettiren kurallarımız SwiftLint veya Testlerin fail olması, diğerleri warning olarak gözüküyor.
- Unit Testlerin başarılı olması.
- Swift Lint uyarısı olmaması.
- PR başlığı jira anahtarı ile başlamalı, 5 karakterden kısa olmamalı.
- Açıklama alanı boş olmamalı ve mutlaka jira kartının bağlantısını içermeli.
- PR 1000 değişiklikten büyük olmamalı (Redesign aşamasında olduğumuz için burayı biraz yükseltmeye karar verdik).
- PR’a milestone eklenmiş olmalı.
Örnek oluşturması açısından aktif olarak kullandığımız danger dosyasını paylaşıyorum. Kuralları ihtiyaç duydukça genişletiyoruz.
MainPRCheck workflow’u hangi adımlardan oluşuyor.
- Git repomuzu çekiyoruz.
- Cache pull yapıyoruz.
- Scripti çalıştırıyoruz.
Cache Pull yapma sebebimiz pod install yerine, diğer buildlerde cachelediğimiz pod klasörünü çekip zaman kazanıyoruz. Cachelemiyorsanız direkt pod install adımını ekleyebilirsiniz.
Eğer siz de pod klasörünü git üzerinde tutmuyorsanız burada pod klasörüne ihtiyacımız var. Danger pod klasörümüzdeki SwiftLint üzerinden lint adımını çalıştırıyor. Lint adımı sürekli fail oluyor ve aşağıdaki gibi bir hata basıyorsa Danger, SwiftLint’i gösterdiğiniz path’de bulamıyor olabilir.
❌ — Error deserializing SwiftLint JSON response (): dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: “The given data was not valid JSON.”, underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 “No value.” UserInfo={NSDebugDescription=No value.})))
Script içeriği
Yukarıdaki son adımda Danger swift ve eklentileri için gerekli olan adımları ekliyoruz. Bizim script adımı aşağıdaki gibidir.
- DangerXCodeSummary eklentisi için xcpretty ve xcpretty-json-formatter kuruyoruz.
- Testlerimizi koşuyoruz
- Danger Swift yükleyip çalıştırıyoruz.
DangerXcodeSummary Eklentisini kullanmayacaksanız scriptte sadece “Danger” kısımını kullanmanız yeterli. Projeyi build etmenize gerek yok.
Örnek Yorumlar
Unit Test Fail
2. Test için paket çıkartma ve dağıtımı
PR yeterli approve(bizim için şimdilik bir) aldıktan sonra otomatik olarak bir build tetiklenir. Paket çıktıktan sonra slack kanalına ilgili takımdaki Developer ve QA ekibi etiketlenir.
İkinci bir yol da slack’den manuel olarak paket tetiklenebilir. Test ekibimiz istedikleri branch ve workflow’dan build tetikleyebilir
Paket çıktıktan sonra aynı kanaldan duyurulur ve paket Firebase App Distribution ve Bitrise APPS & ARTIFACTS tarafına gönderilir. Bu iki adımı akışı fail etmeyecek şekilde ayarlardık ikisinden biri fail olsa bile akış devam ediyor. Bunu adımları eklerken seçebiliyorsunuz.
Test ekibi isterse Aşağıdaki mesajda gelen “Install Page” üzerinden, isterlerse Firebase App Distribution üzerinden paketi kurabilir.
Test Workflow içeriğine bakalım
- Repomuza erişmek için gerekli işlemler
- İlgili branch’i clone adımı
- Build öncesi gerekli scriptlerimizi çalıştırıyoruz.
- Önceki buildden yüklediğimiz cache’i çekiyoruz. Bu işlem paketin çıkma süresini ~4 dk kadar azalttı.
- Pod install yapıyoruz
- Cache’i pushluyoruz
- Provision dosyalarını direkt Apple’dan alıyor, bunu eskiden Bitrise’a kendimiz yüklüyorduk, yeni bir test cihazı eklediğimizde tekrar yüklememiz gerekiyordu bu işlem de ~20 dk sürüyordu.
- Archive işlemi yapıyoruz. Eskiden burada Archive için Fastlane çalıştırıyorduk. Xcode Archive ile Fastlane karşılaştırdık ve Dolap iOS projesi için Xcode Archive ~4 dk daha hızlı Archive ettiğini gördük.
- Çıkan paketi önce Firebase App Distribution’a gönderiyoruz.
- Daha sonra Bitrise APPS & ARTIFACTS kısmına gönderiyoruz.
- Slack’den ilgili kanala Build’in başarılı mı başarısız mı sonuçlandığını basıyoruz ve ilgili indirme linklerini ekliyoruz.
3. Release adımları
Dolap mobil uygulamalarında bir işi canlıya alabilmek için aşağıdaki akışı takip ediyoruz. Style check, Code Reviewleri kolaylaştırmak, Unit Testlerin koşulması gibi konulardan sonra son aşama Release.
Süreç nasıl ilerliyor
Release Branchine gelen pushla birlikte regresyon için bir test buildi tetiklenir ve Release akışımız başlar. Paket çıkınca slack kanalına duyuru düşer. Çıkan paketten regresyon yapılır. Regresyon sonunda test ekibi herhangi bir sorunla karşılaşmadıysa Slack üzerinden release işlemini başlatır.
Paket App Store Connect’e başarılı bir şekilde gönderildikten sonra aynı kanaldan bot aşağıdaki bilgilendirmeyi yapar.
Release workflow’u, test ile aynı. Archive aşamasında derlenmeleri farklı ve paket çıktıktan sonra test workflow’u Firebase’e gönderirken, release App Store Connect’e Deploy to iTunes Connect aracılığıyla gönderir ve Beta test süreci başlar.
Kapanış
Genel hatlarıyla sürecimizi anlatmaya çalıştık. Terimlerden dolayı maalesef bazı yerler Türkçe-İngilizce oldu. Okuduğunuz için teşekkürler, soru ve geribildirimlerinizi yorumlara bekliyoruz.
Teknoloji ekibimize, birlikte güzel işler çıkartacağımız takım arkadaşları arıyoruz. Buradan iletişime geçebilirsiniz.
Sürece katkılarından dolayı Kerem KESKİN ve Alper ŞENYURT’a teşekkürler.