Mobil CICD deneyimi: birçok mobil uygulama için tek hızlı geçiş standardı

Mobil CICD deneyimi: birçok mobil uygulama için tek hızlı geçiş standardı
Fastlane kullanan mobil uygulamalar için sürekli entegrasyon ve dağıtımdan bahsetmek istiyorum. CI/CD'yi tüm mobil uygulamalara nasıl uyguluyoruz, bu noktaya nasıl geldik ve sonunda ne oldu?

Araçla ilgili ağda zaten yeterli miktarda malzeme var ve başlangıçta bu kadar eksiktik, bu yüzden aracı kasıtlı olarak ayrıntılı olarak açıklamayacağım, yalnızca o zaman sahip olduklarımıza atıfta bulunacağım:

Makale iki bölümden oluşuyor:

  • Şirkette mobil CI/CD'nin ortaya çıkışının arka planı
  • N uygulamaları için CI/CD'nin kullanıma sunulmasına yönelik teknik çözüm

İlk bölüm daha çok eski günlere duyulan nostalji, ikincisi ise kendinize uygulayabileceğiniz bir deneyim.

Tarihsel olarak böyle oldu

2015 yılı

Mobil uygulamalar geliştirmeye yeni başladık, o zaman sürekli entegrasyon, DevOps ve diğer moda şeyler hakkında hiçbir şey bilmiyorduk. Her uygulama güncellemesi geliştiricinin kendisi tarafından kendi makinesinden kullanıma sunuldu. Ve eğer Android için oldukça basitse - bir araya getirilmiş, imzalanmış .apk ve bunu Google Geliştirici Konsolu'na yükledim, ardından iOS için Xcode aracılığıyla dağıtım aracı bize harika akşamlar bıraktı - arşivi indirme girişimleri çoğu zaman hatalarla sonuçlandı ve yeniden denemek zorunda kaldık. En gelişmiş geliştiricinin ayda birkaç kez kod yazmadığı, bunun yerine uygulamayı yayınladığı ortaya çıktı.

2016 yılı

Büyüdük, geliştiricileri bir sürüm için bütün bir günden nasıl kurtaracağımıza dair düşüncelerimiz vardı ve ikinci bir uygulama da ortaya çıktı, bu da bizi otomasyona daha da itti. Aynı yıl, Jenkins'i ilk kez kurduk ve fastlane'in belgelerinde gösterdiğine çok benzeyen bir sürü korkutucu senaryo yazdık.

$ xcodebuild clean archive -archivePath build/MyApp 
    -scheme MyApp

$ xcodebuild -exportArchive 
                        -exportFormat ipa 
                        -archivePath "build/MyApp.xcarchive" 
                        -exportPath "build/MyApp.ipa" 
                        -exportProvisioningProfile "ProvisioningProfileName"

$ cd /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/

$ ./altool —upload-app 
-f {abs path to your project}/build/{release scheme}.ipa  
-u "[email protected]" 
-p "PASS_APPLE_ID"

Ne yazık ki şimdiye kadar yalnızca geliştiricilerimiz bu komut dosyalarının nasıl çalıştığını ve bu sonsuz anahtar yığınına neden ihtiyaç duyulduğunu biliyordu ve bir şeyler tekrar bozulduğunda, günlükleri analiz etmek için "muhteşem akşamlar" yaşadılar.

2017 yılı

Bu yıl fastlane diye bir şeyin olduğunu öğrendik. Şimdi olduğu kadar fazla bilgi yoktu; nasıl başlanacağı, nasıl kullanılacağı. Ve aracın kendisi o zamanlar hala kabaydı: sürekli hatalar bizi yalnızca hayal kırıklığına uğrattı ve vaat ettikleri büyülü otomasyona inanmak zordu.

Ancak fastlane çekirdeğinde yer alan ana yardımcı programlar şunlardır: gym и pilot, bunu başlatmayı başardık.

Senaryolarımız biraz geliştirildi.

$ fastlane gym  —-workspace "Example.xcworkspace" 
                --scheme "AppName" 
                —-buildlog_path "/tmp" 
                -—clean

Sadece gerekli tüm parametreler olmadığı için iyileştirildiler. xcodebuildşunu belirtmeniz gerekir: gym nerede ve neyin yattığını bağımsız olarak anlayacaktır. Daha fazla ince ayar yapmak için de aynı tuşları belirtebilirsiniz. xcodebuild, yalnızca tuşların adları daha açıktır.

Bu sefer gym ve yerleşik xcpretty biçimlendirici sayesinde derleme günlükleri çok daha okunaklı hale geldi. Bu, bozuk düzeneklerin onarılmasında zaman kazanmaya başladı ve bazen sürüm ekibi bunu kendi başına çözebiliyordu.

Ne yazık ki montaj hızı ölçümleri xcodebuild и gym Biz yapmadık ama belgelere güveneceğiz - %30'a kadar hızlanma.

Tüm uygulamalar için tek süreç

Yıl 2018 ve günümüz

2018 yılına gelindiğinde, uygulamaları oluşturma ve kullanıma sunma süreci tamamen Jenkins'e taşındı, geliştiriciler makinelerinden yayınlamayı bıraktı ve yalnızca sürüm ekibi yayınlama hakkına sahipti.

Zaten testlerin ve statik analizlerin başlatılmasını iyileştirmek istiyorduk ve komut dosyalarımız büyüdükçe büyüdü. Uygulamalarımızla birlikte büyüdük ve değiştik. O dönemde 10'a yakın uygulama vardı, iki platformumuz olduğunu düşünürsek bu 20'ye yakın "canlı" script demek.

Betiğe her yeni adım eklemek istediğimizde, parçaları tüm kabuk betiklerine kopyalayıp yapıştırmak zorunda kalıyorduk. Belki daha dikkatli çalışabilirdik, ancak çoğu zaman bu tür değişiklikler yazım hatalarıyla sonuçlandı ve bu, sürüm ekibinin komut dosyalarını düzeltmesi ve bu komutu hangi akıllı adamın eklediğini ve gerçekte ne yaptığını öğrenmesi için akşamlara dönüştü. Genel olarak, bir platform için montaj komut dosyalarının en azından bir şekilde benzer olduğu söylenemez. Kesinlikle aynı şeyi yapmalarına rağmen.

Yeni bir uygulama için süreç başlatmak için bu scriptlerin “taze” versiyonunu seçmek, hatalarını ayıklamak ve “evet, çalışıyor” demek için bir gün harcamak gerekiyordu.

2018 yazında hâlâ gelişmekte olan fastlane'a bir kez daha baktık.

Görev #1: Tüm komut dosyası adımlarını özetleyin ve bunları Fastfile'da yeniden yazın

Başladığımızda senaryolarımız, Jenkins'te tek bir kabuk senaryosunda tüm basamaklardan ve koltuk değneklerinden oluşan bir ayak örtüsüne benziyordu. Henüz boru hattına ve aşama aşama bölünmeye geçmedik.

Elimizdekilere baktık ve CI/CD'mizin tanımına uyan 4 adım belirledik:

  • derleme - bağımlılıkları yükleme, arşivi birleştirme,
  • test — geliştirici birim testlerinin çalıştırılması, kapsamın hesaplanması,
  • sonar - tüm linterleri başlatır ve raporları SonarQube'a gönderir,
  • dağıtma — alfaya (TestFlight) bir yapıt gönderme.

Eğer ayrıntılara girmezseniz ve eylemlerde kullanılan tuşları atlarsanız şu Fastfile'ı elde edersiniz:

default_platform(:ios)

platform :ios do
  before_all do
    unlock
  end

  desc "Build stage"
  lane :build do
    match
    prepare_build
    gym
  end

  desc "Prepare build stage: carthage and cocoapods"
  lane :prepare_build do
    pathCartfile = ""
    Dir.chdir("..") do
      pathCartfile = File.join(Dir.pwd, "/Cartfile")
    end
    if File.exist?(pathCartfile)
      carthage
    end
    pathPodfile = ""
    Dir.chdir("..") do
      pathPodfile = File.join(Dir.pwd, "/Podfile")
    end
    if File.exist?(pathPodfile)
      cocoapods
    end
  end

  desc "Test stage"
  lane :test do
    scan
    xcov
  end

  desc "Sonar stage (after run test!)"
  lane :run_sonar do
    slather
    lizard
    swiftlint
    sonar
  end

  desc "Deploy to testflight stage"
  lane :deploy do
    pilot
  end

  desc "Unlock keychain"
  private_lane :unlock do
    pass = ENV['KEYCHAIN_PASSWORD']
    unlock_keychain(
      password: pass
    )
  end
end

Aslında, hâlâ ihtiyaç duyduğumuz bazı koltuk değnekleri ve değiştirdiğimiz parametrelerin sayısı göz önüne alındığında, ilk Fastfile'ımızın korkunç olduğu ortaya çıktı:

lane :build do
carthage(
  command: "update",
  use_binaries: false,
  platform: "ios",
  cache_builds: true)
cocoapods(
  clean: true,
    podfile: "./Podfile",
    use_bundle_exec: false)

gym(
  workspace: "MyApp.xcworkspace",
  configuration: "Release",
  scheme: "MyApp",
  clean: true,
  output_directory: "/build",
  output_name: "my-app.ipa")
end 

lane :deploy do
 pilot(
  username: "[email protected]",
  app_identifier: "com.example.app",
  dev_portal_team_id: "TEAM_ID_NUMBER_DEV",
  team_id: "ITS_TEAM_ID")
end

Yukarıdaki örnekte, belirtmemiz gereken parametrelerin yalnızca bir kısmı: bunlar derleme parametreleridir - şema, yapılandırma, Provizyon Profili adlarının yanı sıra dağıtım parametreleri - geliştirici hesabının Apple kimliği, parola, uygulama kimliği vb. Açık. İlk yaklaşım olarak tüm bu anahtarları özel dosyalara koyuyoruz - Gymfile, Matchfile и Appfile.

Artık Jenkins'te görünümü bulanıklaştırmayan ve gözle kolayca okunabilen kısa komutları arayabilirsiniz:

# fastlane ios <lane_name>

$ fastlane ios build
$ fastlane ios test
$ fastlane ios run_sonar
$ fastlane ios deploy

Yaşasın, biz harikayız

Ne aldın? Her adım için komutları temizleyin. Fastlane dosyalarında düzgün bir şekilde düzenlenmiş, temizlenmiş komut dosyaları. Sevinerek geliştiricilere koştuk ve onlardan ihtiyaç duydukları her şeyi depolarına eklemelerini istedik.

Ancak zamanla aynı zorluklarla karşılaşacağımızı fark ettik - hala öyle ya da böyle kendi hayatlarını yaşamaya başlayacak 20 montaj komut dosyamız olacaktı, komut dosyaları depolara taşınacağından bunları düzenlemek daha zor olacaktı. ve oraya erişimimiz yoktu. Ve genel olarak acımızı bu şekilde çözmek mümkün olmayacaktır.

Mobil CICD deneyimi: birçok mobil uygulama için tek hızlı geçiş standardı

Görev #2: N uygulama için tek bir Fastfile edinin

Artık sorunu çözmek o kadar da zor değil gibi görünüyor - değişkenleri ayarlayın ve başlayalım. Evet aslında sorun bu şekilde çözüldü. Ancak işi batırdığımız anda ne fastlane konusunda, ne fastlane'in yazıldığı Ruby konusunda uzmanlığımız vardı, ne de ağdaki faydalı örnekler - fastlane hakkında yazan herkes o zamanlar bir uygulama için bir örnekle sınırlıydı. bir geliştirici.

Fastlane ortam değişkenlerini işleyebilir ve bunu Anahtar Zinciri şifresini ayarlayarak zaten denedik:

ENV['KEYCHAIN_PASSWORD']

Senaryolarımıza baktıktan sonra ortak kısımları belirledik:

#for build, test and deploy
APPLICATION_SCHEME_NAME=appScheme
APPLICATION_PROJECT_NAME=app.xcodeproj
APPLICATION_WORKSPACE_NAME=app.xcworkspace
APPLICATION_NAME=appName

OUTPUT_IPA_NAME=appName.ipa

#app info
APP_BUNDLE_IDENTIFIER=com.example.appName
[email protected]
TEAM_ID=ABCD1234
FASTLANE_ITC_TEAM_ID=123456789

Şimdi bu anahtarları fastlane dosyalarında kullanmaya başlamak için onları oraya nasıl teslim edeceğimizi bulmamız gerekiyordu. Fastlane'in bunun için bir çözümü var: değişkenleri dotenv aracılığıyla yükleme. Belgeler, anahtarları farklı amaçlarla yüklemeniz sizin için önemliyse, fastlane dizininde birkaç yapılandırma dosyası oluşturmanız gerektiğini söylüyor .env, .env.default, .env.development.

Sonra bu kütüphaneyi biraz farklı kullanmaya karar verdik. Geliştiricilerin deposuna fastlane komut dosyalarını ve meta bilgilerini değil, dosyadaki bu uygulamanın benzersiz anahtarlarını yerleştirelim. .env.appName.

Сами Fastfile, Appfile, Matchfile и Gymfile, onu ayrı bir depoya sakladık. Diğer hizmetlere ait şifre anahtarlarını içeren ek bir dosya orada gizlenmişti - .env.
Bir örnek görebilirsiniz burada.

Mobil CICD deneyimi: birçok mobil uygulama için tek hızlı geçiş standardı

CI'da çağrı pek değişmedi; belirli bir uygulama için bir yapılandırma anahtarı eklendi:

# fastlane ios <lane_name> --env appName

$ fastlane ios build --env appName
$ fastlane ios test --env appName
$ fastlane ios run_sonar --env appName
$ fastlane ios deploy --env appName

Komutları çalıştırmadan önce depomuza scriptleri yüklüyoruz. Pek hoş görünmüyor:

git clone [email protected]/FastlaneCICD.git fastlane_temp

cp ./fastlane_temp/fastlane/* ./fastlane/
cp ./fastlane_temp/fastlane/.env fastlane/.env

Fastlane'in Fastfile'ı indirmek için bir çözümü olmasına rağmen şimdilik bu çözümü bıraktım. aksiyon import_from_git, ancak yalnızca Fastfile için çalışır, ancak diğer dosyalar için çalışmaz. Eğer “gerçekten güzel” olmak istiyorsanız, kendinizinkini yazabilirsiniz. action.

Android uygulamaları ve ReactNative için de benzer bir set yapıldı, dosyalar aynı depoda ancak farklı dallarda iOS, android и react_native.

Sürüm ekibi yeni bir adım eklemek istediğinde, komut dosyasındaki değişiklikler git'teki MR aracılığıyla kaydedilir, artık bozuk komut dosyalarının suçlularını aramaya gerek yoktur ve genel olarak artık onu kırmaya çalışmanız gerekir.

Artık bu kesin

Daha önce tüm komut dosyalarının bakımını yapmak, güncellemek ve güncellemelerin tüm sonuçlarını düzeltmek için zaman harcıyorduk. Sürümlerdeki hataların ve aksama sürelerinin nedenlerinin, kabuk komut dosyalarının karmakarışıklığında takip edilmesi çok zor olan basit yazım hataları olması çok hayal kırıklığı yarattı. Artık bu tür hatalar minimuma indirildi. Değişiklikler aynı anda tüm uygulamalara aktarılır. Ve yeni bir uygulamayı sürece dahil etmek 15 dakika sürer; CI'da bir şablon hattı kurmak ve anahtarları geliştiricinin deposuna eklemek.

Android için Fastfile ve uygulama imzası ile ilgili nokta açıklanamıyor gibi görünüyor, makale ilginçse devamını yazacağım. Yorumlarda veya Telegram'da "bu sorunu nasıl çözersiniz" soru veya önerilerinizi görmekten mutluluk duyacağım Başkirova.

Kaynak: habr.com

Yorum ekle