ProHoster > blog > administrasi > Pengalaman CICD seluler: satu standar jalur cepat untuk banyak aplikasi seluler
Pengalaman CICD seluler: satu standar jalur cepat untuk banyak aplikasi seluler
Saya ingin berbicara tentang integrasi dan pengiriman berkelanjutan untuk aplikasi seluler menggunakan fastlane. Bagaimana kami menerapkan CI/CD di semua aplikasi seluler, bagaimana kami mencapainya, dan apa yang terjadi pada akhirnya.
Sudah ada cukup materi di jaringan tentang alat tersebut, yang pada awalnya sangat kurang kami miliki, jadi saya sengaja tidak akan menjelaskan alat tersebut secara detail, tetapi hanya akan merujuk pada apa yang kami miliki saat itu:
Latar belakang munculnya mobile CI/CD di perusahaan
Solusi teknis untuk meluncurkan CI/CD untuk aplikasi N
Bagian pertama lebih bersifat nostalgia masa lalu, dan bagian kedua adalah pengalaman yang bisa Anda terapkan pada diri sendiri.
Begitulah yang terjadi secara historis
Tahun 2015
Kami baru saja mulai mengembangkan aplikasi seluler, lalu kami tidak tahu apa pun tentang integrasi berkelanjutan, tentang DevOps, dan hal-hal modis lainnya. Setiap pembaruan aplikasi diluncurkan oleh pengembang sendiri dari mesinnya. Dan jika untuk Android cukup sederhana - dirakit, ditandatangani .apk dan mengunggahnya ke Konsol Pengembang Google, lalu untuk iOS, alat distribusi melalui Xcode memberi kami malam yang menyenangkan - upaya untuk mengunduh arsip sering kali berakhir dengan kesalahan dan kami harus mencoba lagi. Ternyata pengembang paling maju tidak menulis kode beberapa kali dalam sebulan, melainkan merilis aplikasinya.
Tahun 2016
Kami tumbuh dewasa, kami sudah memiliki pemikiran tentang cara membebaskan pengembang dari satu hari penuh untuk rilis, dan aplikasi kedua juga muncul, yang hanya mendorong kami lebih ke arah otomatisasi. Pada tahun yang sama, kami menginstal Jenkins untuk pertama kalinya dan menulis sekumpulan skrip menakutkan, sangat mirip dengan yang ditampilkan fastlane dalam dokumentasinya.
Sayangnya, hingga saat ini hanya pengembang kami yang mengetahui cara kerja skrip ini dan mengapa tumpukan kunci yang tak ada habisnya ini diperlukan, dan ketika terjadi kerusakan lagi, mereka mendapatkan “malam yang indah” untuk menganalisis log.
Tahun 2017
Tahun ini kita mengetahui bahwa ada yang namanya fastlane. Informasi yang ada saat ini tidak sebanyak yang ada – bagaimana memulainya, bagaimana menggunakannya. Dan alat itu sendiri masih mentah pada saat itu: kesalahan terus-menerus hanya mengecewakan kami dan sulit mempercayai otomatisasi ajaib yang mereka janjikan.
Namun, utilitas utama yang termasuk dalam inti fastlane adalah gym и pilot, kami berhasil memulainya.
Mereka telah ditingkatkan, jika hanya karena tidak semua parameter diperlukan xcodebuild, Anda perlu menunjukkan - gym akan secara mandiri memahami di mana dan apa yang ada. Dan untuk penyesuaian lebih lanjut, Anda dapat menentukan kunci yang sama seperti pada xcodebuild, hanya penamaan kuncinya yang lebih jelas.
Kali ini, berkat gym dan pemformat xcpretty bawaan, log build menjadi lebih mudah dibaca. Hal ini mulai menghemat waktu dalam memperbaiki rakitan yang rusak, dan terkadang tim rilis dapat mengatasinya sendiri.
Sayangnya, pengukuran kecepatan perakitan xcodebuild и gym Kami tidak melakukannya, tapi kami percaya pada dokumentasinya - percepatan hingga 30%.
Proses tunggal untuk semua aplikasi
Tahun 2018 dan sekarang
Pada tahun 2018, proses pembuatan dan peluncuran aplikasi sepenuhnya dipindahkan ke Jenkins, pengembang berhenti merilis dari mesin mereka, dan hanya tim rilis yang berhak merilis.
Kami sudah ingin meningkatkan peluncuran pengujian dan analisis statis, dan skrip kami semakin berkembang. Tumbuh dan berubah seiring dengan aplikasi kami. Saat itu ada sekitar 10 aplikasi, mengingat kami memiliki dua platform, itu berarti sekitar 20 skrip “hidup”.
Setiap kali kami ingin menambahkan langkah baru ke skrip, kami harus menyalin-menempelkan potongan tersebut ke semua skrip shell. Mungkin kami bisa bekerja lebih hati-hati, tetapi sering kali perubahan seperti itu berakhir dengan kesalahan ketik, yang berubah menjadi malam bagi tim rilis untuk memperbaiki skrip dan mencari tahu orang pintar mana yang menambahkan perintah ini dan apa sebenarnya fungsinya. Secara umum, tidak dapat dikatakan bahwa skrip perakitan untuk satu platform setidaknya serupa. Meskipun mereka pasti melakukan hal yang sama.
Untuk memulai proses aplikasi baru, diperlukan waktu satu hari untuk memilih versi "segar" dari skrip ini, melakukan debug, dan mengatakan bahwa "ya, berhasil".
Pada musim panas 2018, kami sekali lagi melihat ke arah jalur cepat yang masih berkembang.
Tugas #1: meringkas semua langkah skrip dan menulis ulang di Fastfile
Saat kami memulai, skrip kami tampak seperti alas kaki yang terdiri dari semua langkah dan kruk dalam satu skrip shell di Jenkins. Kami belum beralih ke jalur pipa dan divisi demi tahap.
Kami melihat apa yang kami miliki dan mengidentifikasi 4 langkah yang sesuai dengan deskripsi CI/CD kami:
build - menginstal dependensi, merakit arsip,
pengujian — menjalankan pengujian unit pengembang, menghitung cakupan,
sonar - meluncurkan semua linter dan mengirimkan laporan ke SonarQube,
deploy — mengirim artefak ke alpha (TestFlight).
Dan jika Anda tidak merincinya, menghilangkan kunci yang digunakan dalam tindakan, Anda akan mendapatkan 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
Faktanya, Fastfile pertama kami ternyata sangat buruk, mengingat beberapa kruk yang masih kami perlukan dan jumlah 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 sebagian parameter yang perlu kita tentukan: ini adalah parameter build - skema, konfigurasi, nama Profil Penyediaan, serta parameter distribusi - ID Apple dari akun pengembang, kata sandi, ID aplikasi, dan sebagainya pada. Sebagai perkiraan pertama, kami memasukkan semua kunci ini ke dalam file khusus - Gymfile, Matchfile и Appfile.
Sekarang di Jenkins Anda dapat memanggil perintah singkat yang tidak mengaburkan pandangan dan mudah dibaca oleh mata:
Apa yang kamu dapatkan? Hapus perintah untuk setiap langkah. Script sudah dibersihkan, tersusun rapi dalam file fastlane. Bersukacitalah, kami menemui para pengembang meminta mereka untuk menambahkan semua yang mereka butuhkan ke repositori mereka.
Namun kami menyadari pada waktunya bahwa kami akan menghadapi kesulitan yang sama - kami masih memiliki 20 skrip perakitan yang entah bagaimana akan mulai menjalani kehidupannya sendiri, akan lebih sulit untuk mengeditnya, karena skrip akan dipindahkan ke repositori, dan kami tidak memiliki akses ke sana. Dan, secara umum, tidak mungkin mengatasi rasa sakit kita dengan cara ini.
Tugas #2: mendapatkan satu Fastfile untuk N aplikasi
Sekarang tampaknya menyelesaikan masalah tidak terlalu sulit - atur variabelnya, dan ayo. Ya, sebenarnya, begitulah cara masalahnya diselesaikan. Tetapi pada saat kami mengacaukannya, kami tidak memiliki keahlian dalam fastlane itu sendiri, atau di Ruby, di mana fastlane ditulis, atau contoh-contoh berguna di jaringan - setiap orang yang menulis tentang fastlane kemudian dibatasi pada contoh untuk satu aplikasi untuk satu pengembang.
Fastlane dapat menangani variabel lingkungan, dan kami telah mencobanya dengan mengatur kata sandi Rantai Kunci:
ENV['KEYCHAIN_PASSWORD']
Setelah melihat skrip kami, kami mengidentifikasi bagian-bagian umum:
#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 mulai menggunakan kunci ini di file fastlane, kami harus memikirkan cara mengirimkannya ke sana. Fastlane punya solusi untuk ini: memuat variabel melalui dotenv. Dokumentasi mengatakan bahwa jika penting bagi Anda untuk memuat kunci untuk tujuan berbeda, buat beberapa file konfigurasi di direktori fastlane .env, .env.default, .env.development.
Dan kemudian kami memutuskan untuk menggunakan perpustakaan ini sedikit berbeda. Mari kita tempatkan di repositori pengembang bukan skrip fastlane dan informasi meta-nya, tetapi kunci unik aplikasi ini di dalam file .env.appName.
Dirinya sendiri Fastfile, Appfile, Matchfile и Gymfile, kami menyembunyikannya di repositori terpisah. File tambahan dengan kunci kata sandi dari layanan lain disembunyikan di sana - .env.
Anda dapat melihat contohnya di sini.
Di CI, panggilannya tidak banyak berubah; kunci konfigurasi untuk aplikasi tertentu telah ditambahkan:
Tinggalkan solusi ini untuk saat ini, meskipun Fastlane memiliki solusi untuk mengunduh Fastfile melalui tindakanimport_from_git, tetapi ini hanya berfungsi untuk Fastfile, tetapi tidak untuk file lain. Jika ingin “cantik banget”, Anda bisa menulis sendiri action.
Kumpulan serupa dibuat untuk aplikasi Android dan ReactNative, file-file tersebut berada di repositori yang sama, tetapi di cabang yang berbeda iOS, android и react_native.
Ketika tim rilis ingin menambahkan beberapa langkah baru, perubahan skrip dicatat melalui MR di git, tidak perlu lagi mencari penyebab skrip rusak, dan secara umum, sekarang Anda harus mencoba memecahkannya.
Itu sudah pasti
Sebelumnya, kami menghabiskan waktu memelihara semua skrip, memperbaruinya, dan memperbaiki semua konsekuensi pembaruan. Sangat mengecewakan ketika alasan kesalahan dan downtime dalam rilis adalah kesalahan ketik sederhana yang sangat sulit untuk dilacak dalam skrip shell yang campur aduk. Sekarang kesalahan seperti itu diminimalkan. Perubahan diluncurkan ke semua aplikasi sekaligus. Dan dibutuhkan waktu 15 menit untuk memasukkan aplikasi baru ke dalam proses - menyiapkan pipeline template di CI dan menambahkan kunci ke repositori pengembang.
Nampaknya maksud Fastfile untuk Android dan tanda tangan aplikasinya masih belum jelas, jika artikelnya menarik saya akan menulis lanjutannya. Saya akan senang melihat pertanyaan atau saran Anda “bagaimana Anda mengatasi masalah ini” di komentar atau di Telegram bashkirova.