Pengalaman CICD mudah alih: satu standard lorong cepat untuk banyak aplikasi mudah alih

Pengalaman CICD mudah alih: satu standard lorong cepat untuk banyak aplikasi mudah alih
Saya ingin bercakap tentang penyepaduan dan penghantaran berterusan untuk apl mudah alih menggunakan fastlane. Bagaimana kami melaksanakan CI/CD pada semua aplikasi mudah alih, cara kami sampai di sana dan apa yang berlaku pada akhirnya.

Sudah ada bahan yang mencukupi pada rangkaian pada alat, yang kami kekurangan pada mulanya, jadi saya sengaja tidak menerangkan alat itu secara terperinci, tetapi hanya akan merujuk kepada apa yang kami ada pada masa itu:

Artikel terdiri daripada dua bahagian:

  • Latar belakang kemunculan CI/CD mudah alih dalam syarikat
  • Penyelesaian teknikal untuk melancarkan CI/CD untuk aplikasi N

Bahagian pertama adalah lebih banyak nostalgia untuk zaman dahulu, dan yang kedua adalah pengalaman yang boleh anda terapkan untuk diri sendiri.

Ini adalah bagaimana ia berlaku dalam sejarah

Tahun 2015

Kami baru sahaja mula membangunkan aplikasi mudah alih, kemudian kami tidak tahu apa-apa tentang penyepaduan berterusan, tentang DevOps dan perkara lain yang bergaya. Setiap kemas kini aplikasi telah dilancarkan oleh pembangun sendiri daripada mesinnya. Dan jika untuk Android ia agak mudah - dipasang, ditandatangani .apk dan memuat naiknya ke Konsol Pembangun Google, kemudian untuk iOS alat pengedaran pada masa itu melalui Xcode memberi kami malam yang hebat - percubaan untuk memuat turun arkib sering berakhir dengan ralat dan kami terpaksa mencuba lagi. Ternyata pembangun yang paling maju tidak menulis kod beberapa kali sebulan, sebaliknya mengeluarkan aplikasi.

Tahun 2016

Kami membesar, kami sudah memikirkan cara membebaskan pembangun sepanjang hari untuk keluaran, dan aplikasi kedua juga muncul, yang hanya mendorong kami lebih ke arah automasi. Pada tahun yang sama, kami memasang Jenkins buat kali pertama dan menulis sekumpulan skrip menakutkan, sangat serupa dengan yang ditunjukkan oleh fastlane dalam dokumentasinya.

$ 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"

Malangnya, sehingga kini hanya pembangun kami yang tahu cara skrip ini berfungsi dan mengapa timbunan kunci yang tidak berkesudahan ini diperlukan, dan apabila sesuatu rosak lagi, mereka mendapat "malam yang indah" untuk menganalisis log.

Tahun 2017

Tahun ini kami mengetahui bahawa terdapat perkara seperti lorong cepat. Tidak banyak maklumat seperti sekarang - bagaimana untuk memulakannya, cara menggunakannya. Dan alat itu sendiri masih mentah pada masa itu: kesilapan berterusan hanya mengecewakan kami dan sukar untuk mempercayai automasi ajaib yang mereka janjikan.

Walau bagaimanapun, utiliti utama yang termasuk dalam teras lorong cepat ialah gym ΠΈ pilot, kami berjaya memulakannya.

Skrip kami telah dipertingkatkan sedikit.

$ fastlane gym  β€”-workspace "Example.xcworkspace" 
                --scheme "AppName" 
                β€”-buildlog_path "/tmp" 
                -β€”clean

Mereka telah diperbaiki, jika hanya kerana tidak semua parameter yang diperlukan untuk xcodebuild, anda perlu menunjukkan - gym secara bebas akan memahami di mana dan apa yang terletak. Dan untuk penalaan lebih halus, anda boleh menentukan kekunci yang sama seperti dalam xcodebuild, hanya penamaan kekunci yang lebih jelas.

Kali ini, terima kasih kepada gim dan pemformat xcpretty terbina dalam, log binaan menjadi lebih mudah dibaca. Ini mula menjimatkan masa untuk membaiki perhimpunan yang rosak, dan kadangkala pasukan pelepas boleh memikirkannya sendiri.

Malangnya, pengukuran kelajuan pemasangan xcodebuild ΠΈ gym Kami tidak melakukannya, tetapi kami akan mempercayai dokumentasi - sehingga 30% kelajuan.

Proses tunggal untuk semua permohonan

Tahun 2018 dan sekarang

Menjelang 2018, proses membina dan melancarkan aplikasi dipindahkan sepenuhnya ke Jenkins, pembangun berhenti mengeluarkan daripada mesin mereka dan hanya pasukan keluaran yang berhak untuk mengeluarkannya.

Kami sudah mahu menambah baik pelancaran ujian dan analisis statik, dan skrip kami berkembang dan berkembang. Berkembang dan berubah bersama-sama dengan aplikasi kami. Pada masa itu terdapat kira-kira 10 aplikasi Memandangkan kami mempunyai dua platform, itu kira-kira 20 skrip "hidup".

Setiap kali kami ingin menambah langkah baharu pada skrip, kami perlu menyalin-tampal kepingan itu ke dalam semua skrip shell. Mungkin kita boleh bekerja dengan lebih berhati-hati, tetapi selalunya perubahan sedemikian berakhir dengan kesilapan menaip, yang bertukar menjadi malam untuk pasukan keluaran membetulkan skrip dan mengetahui lelaki pintar yang menambahkan arahan ini dan apa yang sebenarnya dilakukannya. Secara umum, tidak boleh dikatakan bahawa skrip untuk pemasangan untuk satu platform adalah sekurang-kurangnya agak serupa. Walaupun mereka pasti melakukan perkara yang sama.

Untuk memulakan proses untuk aplikasi baharu, anda perlu meluangkan masa sehari untuk memilih versi "segar" skrip ini, nyahpepijat dan mengatakan bahawa "ya, ia berfungsi."

Pada musim panas 2018, kami sekali lagi melihat ke arah laluan cepat yang masih membangun.

Tugasan #1: ringkaskan semua langkah skrip dan tulis semula dalam Fastfile

Apabila kami mula, skrip kami kelihatan seperti alas kaki yang terdiri daripada semua langkah dan tongkat dalam satu skrip cangkerang dalam Jenkins. Kami masih belum beralih kepada saluran paip dan pembahagian mengikut peringkat.

Kami melihat apa yang kami ada dan mengenal pasti 4 langkah yang sesuai dengan perihalan CI/CD kami:

  • bina - memasang kebergantungan, memasang arkib,
  • ujian β€” menjalankan ujian unit pembangun, mengira liputan,
  • sonar - melancarkan semua linter dan menghantar laporan kepada SonarQube,
  • gunakan β€” menghantar artifak kepada alfa (TestFlight).

Dan jika anda tidak pergi ke butiran, meninggalkan kunci yang digunakan dalam tindakan, anda akan mendapat Fastfile ini:

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

Sebenarnya, Fastfile pertama kami ternyata sangat besar, memandangkan beberapa tongkat yang masih kami perlukan dan bilangan parameter yang kami gantikan:

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

Dalam contoh di atas, hanya sebahagian daripada parameter yang perlu kami nyatakan: ini ialah parameter binaan - skema, konfigurasi, nama Profil Peruntukan serta parameter pengedaran - ID Apple akaun pembangun, kata laluan, ID aplikasi dan sebagainya. pada. Sebagai anggaran pertama, kami meletakkan semua kunci ini dalam fail khas - Gymfile, Matchfile ΠΈ Appfile.

Kini dalam Jenkins anda boleh memanggil arahan pendek yang tidak mengaburkan pandangan dan mudah dibaca oleh mata:

# fastlane ios <lane_name>

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

Hore, kami hebat

Apa yang kamu dapat? Kosongkan arahan untuk setiap langkah. Skrip yang dibersihkan, disusun kemas dalam fail fastlane. Dengan gembira, kami berlari ke pembangun meminta mereka menambahkan semua yang mereka perlukan pada repositori mereka.

Tetapi kami sedar pada masanya bahawa kami akan menghadapi kesukaran yang sama - kami masih akan mempunyai 20 skrip pemasangan yang satu cara atau yang lain akan mula menjalani kehidupan mereka sendiri, ia akan menjadi lebih sukar untuk mengeditnya, kerana skrip akan berpindah ke repositori, dan kami tidak mempunyai akses ke sana. Dan, secara umum, tidak mungkin untuk menyelesaikan kesakitan kita dengan cara ini.

Pengalaman CICD mudah alih: satu standard lorong cepat untuk banyak aplikasi mudah alih

Tugasan #2: dapatkan satu Fastfile untuk N aplikasi

Sekarang nampaknya menyelesaikan masalah itu tidak begitu sukar - tetapkan pembolehubah, dan mari kita pergi. Ya, sebenarnya, itulah cara masalah itu diselesaikan. Tetapi pada masa ini apabila kami mengacaukannya, kami tidak mempunyai kepakaran dalam fastlane itu sendiri, mahupun dalam Ruby, di mana fastlane ditulis, mahupun contoh berguna pada rangkaian - setiap orang yang menulis tentang fastlane kemudiannya terhad kepada contoh untuk satu aplikasi untuk satu pemaju.

Fastlane boleh mengendalikan pembolehubah persekitaran, dan kami telah mencuba ini dengan menetapkan kata laluan Rantai Kunci:

ENV['KEYCHAIN_PASSWORD']

Selepas melihat skrip kami, kami mengenal pasti bahagian biasa:

#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

Sekarang, untuk mula menggunakan kunci ini dalam fail fastlane, kami perlu memikirkan cara untuk menghantarnya ke sana. Fastlane mempunyai penyelesaian untuk ini: memuatkan pembolehubah melalui dotenv. Dokumentasi mengatakan bahawa jika penting untuk anda memuatkan kunci untuk tujuan yang berbeza, buat beberapa fail konfigurasi dalam direktori fastlane .env, .env.default, .env.development.

Dan kemudian kami memutuskan untuk menggunakan perpustakaan ini sedikit berbeza. Mari letakkan dalam repositori pembangun bukan skrip fastlane dan maklumat metanya, tetapi kunci unik aplikasi ini dalam fail .env.appName.

Sendiri Fastfile, Appfile, Matchfile ΠΈ Gymfile, kami menyembunyikannya dalam repositori berasingan. Fail tambahan dengan kunci kata laluan daripada perkhidmatan lain telah disembunyikan di sana - .env.
Anda boleh lihat contoh di sini.

Pengalaman CICD mudah alih: satu standard lorong cepat untuk banyak aplikasi mudah alih

Pada CI, panggilan tidak banyak berubah, kunci konfigurasi untuk aplikasi tertentu telah ditambahkan:

# 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

Sebelum menjalankan arahan, kami memuatkan repositori kami dengan skrip. Tidak kelihatan begitu baik:

git clone [email protected]/FastlaneCICD.git fastlane_temp

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

Meninggalkan penyelesaian ini buat masa ini, walaupun Fastlane mempunyai penyelesaian untuk memuat turun Fastfile melalui tindakan import_from_git, tetapi ia hanya berfungsi untuk Fastfile, tetapi bukan untuk fail lain. Jika anda mahu "benar-benar cantik", anda boleh menulis sendiri action.

Set serupa dibuat untuk aplikasi Android dan ReactNative, fail berada dalam repositori yang sama, tetapi dalam cawangan yang berbeza iOS, android ΠΈ react_native.

Apabila pasukan keluaran ingin menambah beberapa langkah baharu, perubahan dalam skrip direkodkan melalui MR dalam git, tidak perlu lagi mencari punca skrip yang rosak, dan secara amnya, kini anda perlu cuba memecahkannya.

Sekarang itu yang pasti

Sebelum ini, kami meluangkan masa untuk mengekalkan semua skrip, mengemas kininya dan membetulkan semua akibat daripada kemas kini. Amat mengecewakan apabila sebab ralat dan masa henti dalam keluaran adalah kesilapan menaip mudah yang sangat sukar untuk dijejaki dalam kekusutan skrip shell. Sekarang ralat sedemikian dikurangkan kepada minimum. Perubahan dilancarkan kepada semua aplikasi sekaligus. Dan ia mengambil masa 15 minit untuk memasukkan aplikasi baharu ke dalam proses - sediakan saluran paip templat pada CI dan tambahkan kunci pada repositori pembangun.

Nampaknya perkara dengan Fastfile untuk Android dan tandatangan aplikasi masih tidak dapat dijelaskan jika artikel itu menarik, saya akan menulis sambungan. Saya akan gembira untuk melihat soalan atau cadangan anda "bagaimana anda akan menyelesaikan masalah ini" dalam komen atau di Telegram bashkirova.

Sumber: www.habr.com

Tambah komen