Saat ini, sebagian besar produk perangkat lunak dikembangkan dalam tim. Kondisi keberhasilan untuk pengembangan tim dapat disajikan dalam bentuk skema sederhana.

Setelah menulis kode, Anda harus memastikannya:
- Itu bekerja.
- Tidak merusak apa pun, termasuk kode yang ditulis rekan Anda.
Jika kedua kondisi terpenuhi, maka Anda berada di jalan menuju kesuksesan. Agar dapat dengan mudah memeriksa kondisi ini dan tidak mematikan jalur yang menguntungkan, mereka datang dengan Integrasi Berkelanjutan.
CI adalah alur kerja di mana Anda mengintegrasikan kode Anda ke dalam kode produk umum sesering mungkin. Dan tidak hanya berintegrasi, tetapi juga selalu memeriksa bahwa semuanya berfungsi. Karena Anda perlu memeriksa banyak dan sering, Anda harus berpikir tentang otomatisasi. Anda dapat memeriksa semuanya dengan traksi manual, tetapi tidak sepadan, dan itulah sebabnya.
- Orang itu mahal . Satu jam kerja dari setiap programmer lebih mahal daripada satu jam kerja dari server mana pun.
- Orang salah . Oleh karena itu, situasi dapat muncul ketika mereka menjalankan tes pada cabang yang salah atau mengumpulkan komit yang salah untuk penguji.
- Orang-orang malas . Secara berkala, ketika saya menyelesaikan tugas, saya berpikir: βTapi apa yang harus diperiksa? Saya menulis dua baris - stopudovo semuanya berfungsi! " Saya pikir untuk sebagian dari Anda, pemikiran seperti itu kadang muncul di benak Anda. Tetapi Anda selalu perlu memeriksa.
Bagaimana Integrasi Berkelanjutan diperkenalkan dan dikembangkan dalam tim pengembangan ponsel Avito, bagaimana mereka memperoleh dari 0 hingga 450 perangkat per hari, dan bahwa mesin-mesin membangun mengumpulkan 200 jam sehari, kata Nikolay Nesterov (
nnesterov ) - peserta dalam semua perubahan evolusioner aplikasi CI / CD Android .
Kisah ini dibangun berdasarkan contoh tim Android, tetapi sebagian besar pendekatan juga berlaku di iOS.
Sekali waktu, satu orang bekerja di tim Android Avito. Menurut definisi, ia tidak memerlukan apa pun dari Integrasi Berkelanjutan: tidak ada seorang pun untuk diintegrasikan dengannya.
Namun aplikasi bertambah, semakin banyak tugas baru yang muncul, masing-masing, tim bertambah. Pada titik tertentu, sudah waktunya untuk lebih formal menetapkan proses mengintegrasikan kode. Diputuskan untuk menggunakan aliran Git.

Konsep aliran Git diketahui: ada satu cabang pengembangan umum dalam proyek, dan untuk setiap fitur baru, pengembang memotong cabang terpisah, komit, dorong, dan ketika mereka ingin menyuntikkan kode mereka ke cabang pengembangan, buka permintaan tarik. Untuk berbagi pengetahuan dan mendiskusikan pendekatan, kami memperkenalkan tinjauan kode, yaitu, kolega harus memeriksa dan mengkonfirmasi kode masing-masing.
Cek
Menonton kode dengan mata Anda itu keren, tetapi tidak cukup. Karenanya, pemeriksaan otomatis diperkenalkan.
- Pertama-tama, kami memeriksa perakitan ARC .
- Banyak tes Junit .
- Kami mempertimbangkan cakupan kode , karena kami menjalankan tes.
Untuk memahami bagaimana pemeriksaan ini harus dijalankan, mari kita lihat proses pengembangan di Avito.
Secara skematis, dapat direpresentasikan sebagai berikut:
- Pengembang menulis kode di laptop-nya. Anda dapat menjalankan pemeriksaan integrasi di sini - dengan kait komit, atau hanya menjalankan pemeriksaan di latar belakang.
- Setelah pengembang menjalankan kode, ia membuka permintaan tarik. Agar kodenya masuk ke cabang pengembangan, Anda harus melalui tinjauan kode dan mengumpulkan jumlah konfirmasi yang diperlukan. Anda dapat mengaktifkan pemeriksaan dan pembuatan di sini: sampai semua bangunan berhasil, permintaan tarik tidak dapat digabungkan.
- Setelah permintaan tarik digabungkan dan kode dikembangkan, Anda dapat memilih waktu yang nyaman: misalnya, pada malam hari, ketika semua server gratis, dan mendorong pemeriksaan sesuka Anda.
Tidak ada yang suka menjalankan tes di laptop mereka. Ketika pengembang telah menyelesaikan fitur, ia ingin meluncurkannya dengan cepat dan membuka permintaan tarik. Jika pada saat itu beberapa cek lama diluncurkan, ini tidak hanya tidak terlalu menyenangkan, tetapi juga memperlambat pengembangan: saat laptop memeriksa sesuatu, tidak mungkin untuk bekerja secara normal di atasnya.
Kami sangat suka menjalankan cek di malam hari, karena ada banyak waktu dan server, Anda dapat berjalan-jalan. Namun, sayangnya, ketika kode fitur mulai dikembangkan, pengembang sudah memiliki motivasi yang jauh lebih sedikit untuk memperbaiki kesalahan yang ditemukan CI. Saya secara berkala menemukan diri saya berpikir ketika saya melihat di laporan pagi tentang semua kesalahan yang ditemukan bahwa saya akan memperbaikinya beberapa waktu kemudian, karena sekarang di Jira ada tugas baru yang keren yang saya ingin mulai lakukan.
Jika cek memblokir permintaan tarik, maka ada motivasi yang cukup, karena sampai build berubah hijau, kode tidak masuk ke pengembangan, yang berarti bahwa tugas tidak akan selesai.
Sebagai hasilnya, kami memilih strategi ini: pada malam hari kami mengendarai set maksimum mungkin pemeriksaan, dan yang paling kritis dari mereka dan, yang paling penting cepat, berjalan pada permintaan tarik. Tetapi kami tidak berhenti sampai di situ - secara paralel, kami mengoptimalkan kecepatan lulus pemeriksaan sedemikian rupa untuk memindahkannya dari mode malam ke pemeriksaan atas permintaan tarik.
Pada saat itu, semua majelis kami berjalan cukup cepat, jadi kami hanya menyertakan perakitan ARC, tes Junit dan perhitungan cakupan kode dengan pemblokir permintaan tarik. Mereka menyalakannya, memikirkannya, dan meninggalkan cakupan kode karena mereka pikir kami tidak membutuhkannya.
Kami membutuhkan dua hari untuk menyelesaikan pengaturan CI dasar (selanjutnya, perkiraan sementara adalah perkiraan, diperlukan untuk skala).Setelah itu, mereka mulai berpikir lebih jauh - apakah kita memeriksanya dengan benar? Apakah kita meluncurkan build berdasarkan permintaan tarik dengan benar?
Kami mulai membangun di komit terakhir cabang dengan permintaan tarik terbuka. Tetapi pemeriksaan terhadap komit ini hanya dapat menunjukkan bahwa kode yang ditulis pengembang berfungsi. Tetapi mereka tidak membuktikan bahwa dia tidak merusak apa pun. Bahkan, Anda perlu memeriksa status mengembangkan cabang setelah fitur telah disuntikkan ke dalamnya.

Untuk melakukan ini, kami menulis skrip bash sederhana
premerge.sh:
Di sini, semua perubahan terbaru dari pengembangan hanya ditarik dan digabung ke cabang saat ini. Kami menambahkan skrip premerge.sh sebagai langkah pertama dari semua build dan mulai memeriksa apa yang kami inginkan, yaitu
integrasi .
Butuh tiga hari untuk melokalisasi masalah, menemukan solusi, dan menulis skrip ini.Aplikasi dikembangkan, semakin banyak tugas muncul, tim tumbuh, dan muncul. Kadang-kadang kami mulai mengecewakan kami. Dalam mengembangkan menembus perubahan yang bertentangan yang merusak majelis.
Contoh bagaimana ini terjadi:

Dua pengembang secara bersamaan mulai menggergaji fitur A dan B. Pengembang fitur A menemukan fungsi
answer()
digunakan dalam proyek dan, seperti scout yang baik, menghilangkannya. Pada saat yang sama, pengembang fitur B menambahkan panggilan baru ke fungsi ini di cabangnya.
Pengembang menyelesaikan pekerjaan dan pada saat yang sama permintaan tarik terbuka. Build build, premerge.sh memeriksa kedua permintaan tarik untuk status pengembangan baru - semua cek berwarna hijau. Setelah itu fitur permintaan tarik A digabung, fitur permintaan tarik B digabung ... Boom! Mengembangkan istirahat karena dalam mengembangkan kode ada panggilan ke fungsi yang tidak ada.

Ketika tidak akan berkembang, ini adalah
bencana lokal . Seluruh tim tidak dapat mengumpulkan dan memberikan apa pun untuk pengujian.
Kebetulan saya paling sering terlibat dalam tugas infrastruktur: analitik, jaringan, basis data. Artinya, saya menulis fungsi dan kelas yang digunakan pengembang lain. Karena ini, saya sangat sering masuk ke situasi seperti itu. Saya bahkan punya gambar seperti itu pada satu waktu.

Karena ini tidak cocok untuk kami, kami mulai mencari tahu cara mencegahnya.
Bagaimana tidak putus berkembang
Opsi pertama:
membangun kembali semua permintaan tarik ketika peningkatan dikembangkan. Jika dalam contoh kami permintaan tarik dengan fitur A pertama kali dikembangkan, permintaan tarik fitur B akan dibangun kembali, dan, karenanya, pemeriksaan akan gagal karena kesalahan kompilasi.
Untuk memahami berapa lama, pertimbangkan sebuah contoh dengan dua PR. Kami membuka dua PR: dua build, dua peluncuran uji. Setelah PR pertama dituangkan ke dalam pengembangan, yang kedua harus dibangun kembali. Secara total, dua peluncuran cek PR mengambil tiga PR: 2 + 1 = 3.
Pada prinsipnya, itu normal. Tapi kami melihat statistik, dan situasi khas di tim kami adalah 10 PR terbuka, dan kemudian jumlah cek adalah jumlah perkembangan: 10 + 9 + ... + 1 = 55. Artinya, untuk menerima 10 PR, Anda harus membangun kembali 55 kali. Dan ini dalam situasi yang ideal, ketika semua cek lulus pertama kali, ketika tidak ada yang membuka permintaan tarik tambahan saat sepuluh ini sedang diproses.
Bayangkan diri Anda seorang pengembang yang perlu punya waktu untuk menekan tombol "gabungkan" terlebih dahulu, karena jika ini dilakukan oleh tetangga, Anda harus menunggu sampai semua majelis melewati lagi ... Tidak, itu tidak akan berhasil, itu akan memperlambat pembangunan secara serius.
Cara kedua yang mungkin:
untuk mengumpulkan permintaan tarik setelah peninjauan kode. Artinya, buka permintaan tarik, kumpulkan jumlah pembaruan yang diperlukan dari kolega, perbaiki apa yang Anda butuhkan, lalu jalankan build. Jika mereka berhasil, tarik permintaan bergabung dengan mengembangkan. Dalam hal ini, tidak ada restart lagi, tetapi umpan baliknya banyak melambat. Sebagai pengembang, ketika saya membuka permintaan tarik, saya langsung ingin melihat apakah dia mau. Misalnya, jika tes macet, Anda harus memperbaikinya dengan cepat. Dalam kasus pembangunan yang tertunda, umpan balik melambat, yang berarti seluruh pengembangan. Ini juga tidak cocok untuk kita.
Akibatnya, hanya opsi ketiga yang tersisa - untuk
berputar . Semua kode kami, semua sumber kami disimpan di repositori di server Bitbucket. Karenanya, kami harus mengembangkan plugin untuk Bitbucket.

Plugin ini menimpa mekanisme gabungan permintaan tarik. Awal adalah standar: PR terbuka, semua majelis mulai, ulasan kode melewati. Tetapi setelah peninjauan kode telah berlalu, dan pengembang memutuskan untuk mengklik "gabung", plugin memeriksa untuk melihat kondisi apa yang terjadi pada pemeriksaan pengembangan. Jika, setelah membangun, mengembangkan pembaruan yang berhasil, plugin tidak akan memungkinkan Anda untuk menggabungkan permintaan tarikan seperti itu ke cabang utama. Ini hanya akan memulai kembali pembangunan relatif terhadap pengembangan segar.

Dalam contoh kami dengan perubahan yang bertentangan, build tersebut akan gagal karena kesalahan kompilasi. Dengan demikian, pengembang fitur B harus memperbaiki kode, memulai kembali pemeriksaan, kemudian plugin akan secara otomatis menerapkan permintaan tarik.
Sebelum menerapkan plugin ini, kami memiliki rata-rata 2,7 tes berjalan per permintaan tarik. Dengan plugin tersebut ada 3,6 peluncuran. Itu cocok untuk kita.
Perlu dicatat bahwa plugin ini memiliki kekurangan: plugin ini hanya me-restart build sekali saja. Bagaimanapun, itu adalah jendela kecil tetap melalui mana perubahan yang saling bertentangan dapat berkembang. Tetapi probabilitas ini tidak tinggi, dan kami membuat kompromi antara jumlah awal dan probabilitas kegagalan ini. Selama dua tahun, tembakannya hanya sekali, karena itu, mungkin tidak sia-sia.
Kami butuh dua minggu untuk menulis versi pertama plugin untuk Bitbucket.Cek Baru
Sementara itu, tim kami terus berkembang. Cek baru ditambahkan.
Kami berpikir: mengapa memperbaiki kesalahan jika bisa dicegah? Maka mereka memperkenalkan
analisis kode statis . Kami mulai dengan serat, yang termasuk dalam Android SDK. Tetapi pada saat itu dia sama sekali tidak tahu cara bekerja dengan kode Kotlin, dan kami sudah memiliki 75% aplikasi yang ditulis dalam Kotlin. Oleh karena itu,
pemeriksaan Android Studio bawaan ditambahkan ke serat
.Untuk melakukan ini, saya harus sangat sesat: mengambil Android Studio, kemas di Docker dan jalankan di CI dengan monitor virtual sehingga berpikir bahwa itu berjalan pada laptop sungguhan. Tapi itu berhasil.
Juga pada saat ini, kami mulai menulis banyak
tes instrumentasi dan mengimplementasikan
pengujian tangkapan layar . Ini adalah ketika tangkapan layar referensi dihasilkan untuk tampilan kecil yang terpisah, dan pengujiannya adalah tangkapan layar diambil dari tampilan dan dibandingkan secara langsung dengan piksel referensi demi piksel. Jika ada perbedaan, itu berarti bahwa tata letak telah pergi ke suatu tempat atau ada sesuatu yang salah dalam gaya.
Tetapi tes instrumentasi dan uji tangkapan layar harus dijalankan pada perangkat: pada emulator atau pada perangkat nyata. Mengingat ada banyak tes dan mereka sering mengejar, Anda memerlukan seluruh peternakan. Untuk memulai pertanian Anda sendiri terlalu melelahkan, jadi kami menemukan opsi yang sudah jadi - Firebase Test Lab.
Laboratorium uji Firebase
Itu dipilih karena Firebase adalah produk Google, yaitu, itu harus dapat diandalkan dan tidak akan pernah mati. Harga terjangkau: $ 5 per jam untuk perangkat nyata, $ 1 per jam untuk emulator.
Butuh sekitar tiga minggu untuk menerapkan Firebase Test Lab di CI kami.Tetapi tim terus tumbuh, dan Firebase, sayangnya, mulai mengecewakan kami. Pada saat itu, dia tidak memiliki SLA. Terkadang Firebase membuat kami menunggu hingga jumlah perangkat yang diperlukan untuk pengujian menjadi gratis, dan tidak segera mulai menjalankannya, seperti yang kami inginkan. Menunggu dalam antrean memakan waktu hingga setengah jam, dan ini adalah waktu yang sangat lama. Tes instrumentasi berjalan di setiap PR, keterlambatan sangat memperlambat pengembangan, dan kemudian tagihan bulanan datang dengan jumlah bulat. Secara umum, diputuskan untuk meninggalkan Firebase dan melihat sendiri, karena tim sudah cukup berkembang.
Docker + python + bash
Kami membawa buruh pelabuhan, memasukkan emulator ke dalamnya, menulis program Python sederhana yang pada waktu yang tepat meningkatkan jumlah emulator yang tepat dalam versi yang tepat dan menghentikannya jika perlu. Dan, tentu saja, beberapa skrip bash - di mana tanpa itu?
Butuh lima minggu untuk menciptakan lingkungan pengujian kami sendiri.Akibatnya, setiap permintaan tarik memiliki daftar cek yang luas dan menghalangi digabung:
- Majelis ARC;
- Tes Junit
- Lint;
- Android Studio memeriksa;
- Tes instrumentasi;
- Tes tangkapan layar.
Ini mencegah banyak kemungkinan kerusakan. Secara teknis, semuanya bekerja, tetapi pengembang mengeluh bahwa menunggu hasil terlalu lama.
Terlalu lama berapa? Kami mengunggah data dari Bitbucket dan TeamCity ke sistem analisis dan menyadari bahwa
waktu tunggu rata -
rata adalah 45 menit . Artinya, pengembang, membuka permintaan tarik, rata-rata mengharapkan hasil pembangunan 45 menit. Menurut pendapat saya, ini banyak, dan Anda tidak bisa bekerja seperti itu.
Tentu saja, kami memutuskan untuk mempercepat semua bangunan kami.
Mempercepat
Melihat bahwa sering membangun sejalan, hal pertama yang kami
beli adalah besi - pengembangan luas adalah yang paling sederhana. Bangun berhenti berdiri dalam antrean, tetapi waktu tunggu berkurang hanya sedikit, karena beberapa cek sendiri mengejar untuk waktu yang sangat lama.
Kami menghapus cek terlalu lama
Integrasi Berkelanjutan kami dapat menangkap jenis kesalahan dan masalah ini.
- Tidak akan . CI dapat menangkap kesalahan kompilasi ketika, karena perubahan yang bertentangan, sesuatu tidak terjadi. Seperti yang saya katakan, maka tidak ada yang bisa mengumpulkan apa pun, perkembangan meningkat, dan semua orang menjadi gugup.
- Bug dalam perilaku . Misalnya, ketika aplikasi dibangun, tetapi ketika Anda mengklik tombol itu crash, atau tombol tidak ditekan sama sekali. Ini buruk karena bug semacam itu dapat menjangkau pengguna.
- Bug dalam tata letak . Misalnya, tombol ditekan, tetapi dipindahkan 10 piksel ke kiri.
- Peningkatan utang teknis .
Melihat daftar ini, kami menyadari bahwa hanya dua poin pertama yang kritis. Kami ingin menangkap masalah seperti itu terlebih dahulu. Bug dalam tata letak terdeteksi pada tahap tinjauan desain dan kemudian diperbaiki dengan mudah. Bekerja dengan hutang teknis membutuhkan proses dan perencanaan yang terpisah, jadi kami memutuskan untuk tidak memeriksa permintaan tarik.
Berdasarkan klasifikasi ini, kami mengguncang seluruh daftar cek.
Coret Lint dan tunda peluncurannya untuk malam ini: hanya supaya memberikan laporan tentang berapa banyak masalah yang ada dalam proyek. Kami sepakat untuk bekerja secara terpisah dengan hutang teknis, tetapi
sepenuhnya menolak cek Android Studio . Studio Android Docker untuk meluncurkan inspeksi terdengar menarik, tetapi hal itu membawa banyak masalah dalam dukungan. Setiap pembaruan ke versi Android Studio adalah perjuangan melawan bug yang tidak jelas. Juga sulit untuk mempertahankan tes tangkapan layar, karena perpustakaan tidak bekerja dengan sangat stabil, ada kesalahan positif.
Tes tangkapan layar dihapus dari daftar cek .
Akibatnya, kami telah meninggalkan:
- Majelis ARC;
- Tes Junit
- Tes instrumentasi.
Cache jarak jauh gradle
Tanpa cek berat, segalanya menjadi lebih baik. Tetapi tidak ada batasan untuk kesempurnaan!
Aplikasi kami telah dipecah menjadi sekitar 150 modul gradle. Biasanya, dalam hal ini, cache jarak jauh Gradle berfungsi dengan baik, dan kami memutuskan untuk mencobanya.
Cache jarak jauh gradle adalah layanan yang dapat membuat cache membangun artefak untuk tugas-tugas individu dalam modul terpisah. Gradle, alih-alih benar-benar menyusun kode, mengetuk cache jarak jauh melalui HTTP dan menanyakan apakah seseorang telah melakukan tugas ini. Jika demikian, cukup unduh hasilnya.
Memulai cache jarak jauh Gradle mudah karena Gradle menyediakan gambar Docker. Kami berhasil melakukan ini dalam tiga jam.Yang diperlukan hanyalah meluncurkan Docker dan mendaftarkan satu baris dalam proyek. Tetapi meskipun Anda bisa memulainya dengan cepat sehingga semuanya bekerja dengan baik, itu akan memakan banyak waktu.
Di bawah ini adalah grafik cache yang hilang.

Pada awalnya, persentase kesalahan melewati cache adalah sekitar 65. Tiga minggu kemudian, kami berhasil membawa nilai ini menjadi 20%. Ternyata tugas yang dikumpulkan aplikasi Android memiliki dependensi transitif yang aneh, karena Gradle melewatkan cache.
Dengan menghubungkan cache, kami sangat mempercepat perakitan. Namun terlepas dari perakitan, tes instrumentasi masih mengejar, dan mereka mengejar untuk waktu yang lama. Mungkin tidak semua tes perlu dikejar untuk setiap permintaan tarik. Untuk mengetahuinya, kami menggunakan analisis dampak.
Analisis dampak
Berdasarkan permintaan, kami membangun git diff dan menemukan modul Gradle yang dimodifikasi.

Masuk akal untuk menjalankan hanya tes instrumentasi yang menguji modul yang dimodifikasi dan semua modul yang bergantung padanya. Tidak ada gunanya menjalankan tes untuk modul tetangga: kode tidak berubah di sana, dan tidak ada yang dapat merusak.
Tes instrumentasi tidak begitu sederhana, karena harus ditempatkan di modul Aplikasi tingkat atas. Kami menerapkan heuristik analisis bytecode untuk memahami modul mana masing-masing tes milik.
Butuh sekitar delapan minggu untuk meningkatkan tes instrumentasi untuk menguji hanya modul yang terlibat.Tindakan percepatan verifikasi telah berhasil. Dari 45 menit kami mencapai sekitar 15. Seperempat jam untuk menunggu build sudah normal.
Tetapi sekarang para pengembang telah mulai mengeluh bahwa tidak jelas bagi mereka yang membangun sedang diluncurkan, di mana log akan melihat, mengapa build itu merah, tes mana yang jatuh, dll.

Masalah umpan balik memperlambat pengembangan, jadi kami mencoba memberikan informasi yang paling dimengerti dan terperinci tentang setiap PR dan pengembangan. Kami mulai dengan komentar pada Bitbucket untuk PR, yang menunjukkan bangunan mana yang jatuh dan mengapa, menulis pesan yang ditargetkan di Slack. Pada akhirnya, mereka membuat dasbor untuk halaman PR dengan daftar semua build yang sedang berjalan dan statusnya: sejalan, dimulai, macet, atau berakhir. Anda dapat mengklik build dan membuka log-nya.
Enam minggu dihabiskan untuk umpan balik terperinci.Paket
Kami lolos ke riwayat terbaru. Setelah menyelesaikan pertanyaan tentang umpan balik, kami pergi ke tingkat yang baru - kami memutuskan untuk membangun pertanian emulator kami sendiri. Ketika ada banyak tes dan emulator, mereka sulit untuk dikelola. Akibatnya, semua emulator kami pindah ke cluster K8 dengan manajemen sumber daya yang fleksibel.
Selain itu, ada rencana lain.
- Return Lint (dan analisis statis lainnya). Kami sudah bekerja ke arah ini.
- Jalankan semua tes ujung ke ujung pada pemblokir PR pada semua versi SDK.
Jadi, kami menelusuri sejarah perkembangan Integrasi Berkelanjutan di Avito. Sekarang saya ingin memberikan saran dari sudut pandang yang berpengalaman.
Kiat
Jika saya hanya bisa memberikan satu saran, ini adalah ini:
Harap berhati-hati dengan skrip shell!
Bash adalah alat yang sangat fleksibel dan kuat, sangat nyaman dan cepat untuk menulis skrip di atasnya. Tapi bersamanya Anda bisa jatuh ke dalam perangkap, dan kami, sayangnya, jatuh ke dalamnya.
Semuanya dimulai dengan skrip sederhana yang berjalan di mesin build kami:
Tapi, seperti yang Anda tahu, semuanya berkembang dan semakin rumit dari waktu ke waktu - mari kita jalankan satu skrip dari yang lain, mari kita berikan beberapa parameter di sana - pada akhirnya saya harus menulis fungsi yang menentukan tingkat bash bersarang seperti apa kita saat ini untuk mengganti tanda kutip yang diperlukan, sehingga semuanya dimulai.

Anda bisa membayangkan kerja keras yang terlibat dalam mengembangkan skrip tersebut. Saya menyarankan Anda untuk tidak jatuh ke dalam perangkap ini.
Apa yang bisa diganti?
- Bahasa scripting apa pun. Menulis dengan Skrip Python atau Kotlin lebih nyaman karena merupakan pemrograman, bukan skrip.
- Atau jelaskan semua logika build dalam bentuk tugas Gradle khusus untuk proyek Anda.
Kami memutuskan untuk memilih opsi kedua, dan sekarang kami secara sistematis menghapus semua skrip bash dan menulis banyak shuffles gradle khusus.
Kiat # 2: simpan infrastruktur Anda dalam kode.Akan lebih mudah bila konfigurasi Integrasi Berkelanjutan disimpan bukan di antarmuka Jenkins atau TeamCity UI, dll., Tetapi sebagai file teks langsung di repositori proyek. Ini memberikan kemampuan versi. Tidak akan sulit untuk memutar kembali atau mengumpulkan kode di cabang lain.
Skrip dapat disimpan dalam proyek. Dan apa yang harus dilakukan dengan lingkungan?
Kiat # 3: Docker dapat membantu dengan lingkungan.Sayangnya itu pasti akan membantu pengembang Android, iOS belum.
Ini adalah contoh file buruh pelabuhan sederhana yang berisi jdk dan android-sdk:
FROM openjdk:8 ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" \ ANDROID_HOME="/usr/local/android-sdk" \ ANDROID_VERSION=26 \ ANDROID_BUILD_TOOLS_VERSION=26.0.2 # Download Android SDK RUN mkdir "$ANDROID_HOME" .android \ && cd "$ANDROID_HOME" \ && curl -o sdk.zip $SDK_URL \ && unzip sdk.zip \ && rm sdk.zip \ && yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses # Install Android Build Tool and Libraries RUN $ANDROID_HOME/tools/bin/sdkmanager --update RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \ "platforms;android-${ANDROID_VERSION}" \ "platform-tools" RUN mkdir /application WORKDIR /application
Setelah menulis file buruh pelabuhan ini (saya akan memberi tahu Anda sebuah rahasia, Anda tidak dapat menulisnya, tetapi menariknya dari GitHub) dan mengumpulkan gambar, Anda mendapatkan mesin virtual tempat Anda dapat membangun aplikasi dan menjalankan tes Junit.
Dua argumen utama mengapa ini masuk akal adalah skalabilitas dan pengulangan. Dengan menggunakan buruh pelabuhan, Anda dapat dengan cepat mengumpulkan selusin agen bangunan yang akan memiliki lingkungan yang persis sama dengan yang lama. Ini membuat hidup lebih mudah bagi insinyur CI. Mendorong android-sdk ke buruh pelabuhan cukup sederhana, dengan emulator sedikit lebih rumit: Anda harus sedikit berolahraga (baik, atau unduh yang sudah selesai dari GitHub).
Kiat nomor 4: jangan lupa bahwa cek dilakukan bukan untuk kepentingan cek, tetapi untuk orang-orang.Umpan balik yang cepat dan, yang paling penting, jelas adalah sangat penting bagi pengembang: apa yang mereka langgar, tes apa yang gagal, di mana log pembangunan.
Kiat # 5: Bersikap pragmatis dengan Integrasi Berkelanjutan.Pahami dengan jelas jenis kesalahan apa yang ingin Anda cegah, seberapa banyak Anda bersedia menghabiskan sumber daya, waktu, waktu komputer. Cek yang terlalu lama dapat, misalnya, dijadwal ulang semalam. Dan mereka yang menangkap kesalahan yang tidak terlalu penting harus sepenuhnya ditinggalkan.
Kiat nomor 6: gunakan alat yang sudah jadi.Sekarang ada banyak perusahaan yang menyediakan cloud CI.

Untuk tim kecil, ini jalan keluar yang bagus. Anda tidak perlu memelihara apa pun, cukup membayar sejumlah uang, kumpulkan aplikasi Anda dan bahkan uji coba instrumentasi.
Kiat # 7: dalam tim besar, solusi internal lebih menguntungkan.Namun cepat atau lambat, dengan pertumbuhan tim akan menjadi solusi in-house yang lebih menguntungkan. Ada satu hal dengan keputusan ini. Di bidang ekonomi, ada hukum pengembalian yang semakin menurun: dalam proyek apa pun, setiap peningkatan selanjutnya akan semakin sulit, membutuhkan semakin banyak investasi.
Ekonomi menggambarkan seluruh hidup kita, termasuk Integrasi Berkelanjutan. Saya membuat jadwal kerja untuk setiap tahap pengembangan Integrasi Berkelanjutan kami.

Dapat dilihat bahwa setiap perbaikan diberikan semakin sulit. Melihat grafik ini, kita dapat memahami bahwa pengembangan Integrasi Berkelanjutan harus konsisten dengan pertumbuhan ukuran tim. Untuk tim yang terdiri dari dua orang, menghabiskan 50 hari mengembangkan pertanian emulator internal adalah ide yang biasa-biasa saja. Tetapi pada saat yang sama, bagi tim besar untuk tidak melakukan Integrasi Berkelanjutan sama sekali juga merupakan ide yang buruk, karena masalah integrasi, memperbaiki komunikasi, dll. itu akan membutuhkan lebih banyak waktu.
Kami mulai dengan fakta bahwa otomatisasi diperlukan karena orang mahal, mereka keliru dan malas. Tetapi orang-orang juga mengotomatisasi. Oleh karena itu, semua masalah yang sama ini berlaku untuk otomasi.
- Otomatis itu mahal. Ingat jadwal kerja.
- Dalam otomatisasi, orang membuat kesalahan.
- Otomasi terkadang sangat malas, karena semuanya berjalan seperti itu. Kenapa lagi membaik, mengapa semua Integrasi Terus-Menerus ini?
Tapi saya punya statistik: di 20% dari kesalahan majelis tertangkap. Dan ini bukan karena pengembang kami menulis kode dengan buruk. Ini karena pengembang yakin bahwa jika mereka membuat kesalahan, itu tidak akan berkembang, itu akan ditangkap oleh cek otomatis. Dengan demikian, pengembang dapat menghabiskan lebih banyak waktu menulis kode dan hal-hal menarik, daripada mengejar dan memeriksa sesuatu secara lokal.Terlibat dalam Integrasi Berkelanjutan. Namun dalam jumlah sedang., , AppsConf . . 22-23 .