Evolusi CI dalam pasukan pembangunan mudah alih

Hari ini, kebanyakan produk perisian dibangunkan dalam pasukan. Syarat untuk pembangunan pasukan yang berjaya boleh diwakili dalam bentuk rajah mudah.

Evolusi CI dalam pasukan pembangunan mudah alih

Sebaik sahaja anda telah menulis kod anda, anda perlu memastikan ia:

  1. Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.
  2. Ia tidak memecahkan apa-apa, termasuk kod yang ditulis oleh rakan sekerja anda.

Jika kedua-dua syarat dipenuhi, maka anda berada di jalan menuju kejayaan. Untuk menyemak keadaan ini dengan mudah dan tidak menyimpang dari laluan yang menguntungkan, kami menghasilkan Integrasi Berterusan.

CI ialah aliran kerja di mana anda menyepadukan kod anda ke dalam keseluruhan kod produk sekerap mungkin. Dan anda bukan sahaja menyepadukan, tetapi juga sentiasa menyemak sama ada semuanya berfungsi. Memandangkan anda perlu menyemak banyak dan kerap, ia patut difikirkan tentang automasi. Anda boleh menyemak semuanya secara manual, tetapi anda tidak sepatutnya, dan inilah sebabnya.

  • Orang yang dikasihi. Satu jam kerja mana-mana pengaturcara adalah lebih mahal daripada satu jam kerja mana-mana pelayan.
  • Orang ramai membuat kesilapan. Oleh itu, situasi mungkin timbul apabila ujian dijalankan pada cawangan yang salah atau komit yang salah telah disusun untuk penguji.
  • Orang malas. Dari semasa ke semasa, apabila saya menyelesaikan tugas, pemikiran timbul: "Apa yang perlu diperiksa? Saya menulis dua baris - semuanya berfungsi! Saya fikir sesetengah daripada anda juga kadang-kadang mempunyai pemikiran sedemikian. Tetapi anda harus sentiasa menyemak.

Bagaimana Integrasi Berterusan dilaksanakan dan dibangunkan dalam pasukan pembangunan mudah alih Avito, bagaimana mereka pergi dari 0 kepada 450 binaan sehari, dan mesin binaan dipasang 200 jam sehari, kata Nikolai Nesterov (nnesterov) ialah peserta dalam semua perubahan evolusi aplikasi Android CI/CD.

Cerita ini berdasarkan contoh arahan Android, tetapi kebanyakan pendekatan juga boleh digunakan pada iOS.


Pada suatu masa dahulu, seorang bekerja dalam pasukan Android Avito. Mengikut takrifan, dia tidak memerlukan apa-apa daripada Integrasi Berterusan: tiada sesiapa untuk disepadukan.

Tetapi aplikasi itu berkembang, semakin banyak tugas baharu muncul, dan pasukan itu berkembang dengan sewajarnya. Pada satu ketika, sudah tiba masanya untuk mewujudkan proses penyepaduan kod secara lebih formal. Ia telah memutuskan untuk menggunakan aliran Git.

Evolusi CI dalam pasukan pembangunan mudah alih

Konsep aliran Git terkenal: projek mempunyai satu cawangan pembangunan biasa, dan untuk setiap ciri baharu, pembangun memotong cawangan berasingan, komited kepadanya, menolak, dan apabila mereka ingin menggabungkan kod mereka ke dalam cawangan pembangunan, buka permintaan tarik. Untuk berkongsi pengetahuan dan membincangkan pendekatan, kami memperkenalkan semakan kod, iaitu, rakan sekerja mesti menyemak dan mengesahkan kod satu sama lain.

Cek

Melihat kod dengan mata anda adalah menarik, tetapi tidak mencukupi. Oleh itu, pemeriksaan automatik sedang diperkenalkan.

  • Pertama sekali, kita semak perhimpunan ARK.
  • banyak Ujian Junit.
  • Kami menganggap liputan kod, kerana kami menjalankan ujian.

Untuk memahami cara semakan ini harus dijalankan, mari lihat proses pembangunan dalam Avito.

Ia boleh diwakili secara skematik seperti ini:

  • Seorang pembangun menulis kod pada komputer ribanya. Anda boleh menjalankan semakan penyepaduan di sini - sama ada dengan cangkuk komit, atau hanya jalankan semakan di latar belakang.
  • Selepas pembangun telah menolak kod, dia membuka permintaan tarik. Agar kodnya dimasukkan ke dalam cawangan pembangunan, perlu melalui semakan kod dan mengumpul bilangan pengesahan yang diperlukan. Anda boleh mendayakan semakan dan binaan di sini: sehingga semua binaan berjaya, permintaan tarik tidak boleh digabungkan.
  • Selepas permintaan tarik digabungkan dan kod dimasukkan dalam pembangunan, anda boleh memilih masa yang sesuai: contohnya, pada waktu malam, apabila semua pelayan bebas, dan jalankan seberapa banyak semakan yang anda suka.

Tiada siapa yang suka menjalankan imbasan pada komputer riba mereka. Apabila pembangun telah menyelesaikan ciri, dia mahu menolaknya dengan cepat dan membuka permintaan tarik. Jika pada masa ini beberapa pemeriksaan panjang dilancarkan, ini bukan sahaja tidak menyenangkan, tetapi juga melambatkan pembangunan: semasa komputer riba menyemak sesuatu, adalah mustahil untuk berfungsi secara normal.

Kami sangat suka menjalankan pemeriksaan pada waktu malam, kerana terdapat banyak masa dan pelayan, anda boleh berkeliaran. Tetapi, malangnya, apabila kod ciri mula berkembang, pembangun mempunyai lebih kurang motivasi untuk membetulkan ralat yang ditemui oleh CI. Saya secara berkala terfikir apabila saya melihat semua kesilapan yang ditemui dalam laporan pagi bahawa saya akan membetulkannya suatu hari nanti, kerana kini terdapat tugas baharu yang menarik di Jira yang baru saya mahu mulakan.

Jika semakan menyekat permintaan tarik, maka terdapat motivasi yang mencukupi, kerana sehingga binaan bertukar hijau, kod itu tidak akan masuk ke dalam pembangunan, yang bermaksud tugas itu tidak akan selesai.

Akibatnya, kami memilih strategi berikut: kami menjalankan set semakan maksimum yang mungkin pada waktu malam, dan melancarkan yang paling kritikal daripadanya dan, yang paling penting, yang terpantas atas permintaan tarik. Tetapi kami tidak berhenti di situβ€”secara selari, kami mengoptimumkan kelajuan semakan untuk memindahkannya daripada mod malam untuk menarik semakan permintaan.

Pada masa itu, semua binaan kami telah disiapkan agak cepat, jadi kami hanya memasukkan binaan ARK, ujian Junit dan pengiraan liputan kod sebagai penyekat untuk permintaan tarik. Kami menghidupkannya, memikirkannya dan meninggalkan liputan kod kerana kami berpendapat bahawa kami tidak memerlukannya.

Kami mengambil masa dua hari untuk menyediakan CI asas sepenuhnya (selepas ini anggaran masa adalah anggaran, diperlukan untuk skala).

Selepas itu, kami mula berfikir lebih jauh - adakah kami menyemak dengan betul? Adakah kita menjalankan binaan berdasarkan permintaan tarik dengan betul?

Kami memulakan binaan pada komit terakhir cawangan dari mana permintaan tarik dibuka. Tetapi ujian komit ini hanya boleh menunjukkan bahawa kod yang ditulis oleh pembangun berfungsi. Tetapi mereka tidak membuktikan bahawa dia tidak melanggar apa-apa. Sebenarnya, anda perlu menyemak keadaan cawangan yang dibangunkan selepas ciri digabungkan ke dalamnya.

Evolusi CI dalam pasukan pembangunan mudah alih

Untuk melakukan ini, kami menulis skrip bash mudah premerge.sh:

#!/usr/bin/env bash

set -e

git fetch origin develop

git merge origin/develop

Di sini semua perubahan terkini daripada pembangunan hanya ditarik ke atas dan digabungkan ke dalam cawangan semasa. Kami menambah skrip premerge.sh sebagai langkah pertama dalam semua binaan dan mula menyemak dengan tepat apa yang kami mahu, iaitu integrasi.

Ia mengambil masa tiga hari untuk menyetempatkan masalah, mencari penyelesaian dan menulis skrip ini.

Aplikasi dibangunkan, semakin banyak tugas muncul, pasukan berkembang, dan premerge.sh kadangkala mula mengecewakan kami. Membangunkan mempunyai perubahan bercanggah yang memecahkan binaan.

Contoh bagaimana ini berlaku:

Evolusi CI dalam pasukan pembangunan mudah alih

Dua pembangun secara serentak mula mengusahakan ciri A dan B. Pembangun ciri A menemui ciri yang tidak digunakan dalam projek answer() dan, seperti pengakap lelaki yang baik, membuangnya. Pada masa yang sama, pembangun ciri B menambah panggilan baharu pada fungsi ini dalam cawangannya.

Pembangun menyelesaikan kerja mereka dan membuka permintaan tarik pada masa yang sama. Binaan dilancarkan, premerge.sh menyemak kedua-dua permintaan tarik berkenaan keadaan pembangunan terkini - semua semakan berwarna hijau. Selepas itu, permintaan tarik ciri A digabungkan, permintaan tarik ciri B digabungkan... Boom! Bangun rehat kerana kod bangunkan mengandungi panggilan ke fungsi yang tidak wujud.

Evolusi CI dalam pasukan pembangunan mudah alih

Apabila ia tidak akan berkembang, ia adalah bencana tempatan. Seluruh pasukan tidak boleh mengumpul apa-apa dan menyerahkannya untuk ujian.

Kebetulan saya paling kerap bekerja pada tugas infrastruktur: analisis, rangkaian, pangkalan data. Iaitu, saya yang menulis fungsi dan kelas yang digunakan oleh pembangun lain. Disebabkan ini, saya sering mengalami situasi yang sama. Saya juga mempunyai gambar ini tergantung untuk seketika.

Evolusi CI dalam pasukan pembangunan mudah alih

Oleh kerana ini tidak sesuai dengan kami, kami mula meneroka pilihan tentang cara mencegah perkara ini.

Bagaimana untuk tidak memecahkan pembangunan

Pilihan pertama: bina semula semua permintaan tarik apabila mengemas kini pembangunan. Jika, dalam contoh kami, permintaan tarik dengan ciri A adalah yang pertama disertakan dalam pembangunan, permintaan tarik ciri B akan dibina semula dan, sewajarnya, semakan akan gagal disebabkan oleh ralat penyusunan.

Untuk memahami tempoh masa ini, pertimbangkan contoh dengan dua PR. Kami membuka dua PR: dua binaan, dua larian semakan. Selepas PR pertama digabungkan menjadi membangun, yang kedua perlu dibina semula. Secara keseluruhan, dua PR memerlukan tiga larian semakan: 2 + 1 = 3.

Pada dasarnya, tidak mengapa. Tetapi kami melihat statistik, dan situasi biasa dalam pasukan kami ialah 10 PR terbuka, dan kemudian bilangan semakan ialah jumlah kemajuan: 10 + 9 +... + 1 = 55. Iaitu, untuk menerima 10 PR, anda perlu membina semula 55 kali. Dan ini berada dalam situasi yang ideal, apabila semua semakan lulus buat kali pertama, apabila tiada siapa yang membuka permintaan tarik tambahan semasa sedozen ini sedang diproses.

Bayangkan diri anda sebagai pembangun yang perlu menjadi orang pertama yang mengklik pada butang "gabung", kerana jika jiran melakukan ini, maka anda perlu menunggu sehingga semua binaan berjalan semula... Tidak, itu tidak akan berfungsi , ia akan melambatkan pembangunan secara serius.

Cara kedua yang mungkin: kumpulkan permintaan tarik selepas semakan kod. Iaitu, anda membuka permintaan tarik, mengumpul bilangan kelulusan yang diperlukan daripada rakan sekerja, membetulkan perkara yang diperlukan, dan kemudian melancarkan binaan. Jika mereka berjaya, permintaan tarik digabungkan menjadi pembangunan. Dalam kes ini, tiada permulaan semula tambahan, tetapi maklum balas sangat perlahan. Sebagai pembangun, apabila saya membuka permintaan tarik, saya segera ingin melihat sama ada ia akan berfungsi. Sebagai contoh, jika ujian gagal, anda perlu membetulkannya dengan cepat. Dalam kes binaan tertunda, maklum balas menjadi perlahan, dan oleh itu keseluruhan pembangunan. Ini juga tidak sesuai dengan kami.

Akibatnya, hanya pilihan ketiga yang tinggal - basikal. Semua kod kami, semua sumber kami disimpan dalam repositori pada pelayan Bitbucket. Sehubungan itu, kami terpaksa membangunkan pemalam untuk Bitbucket.

Evolusi CI dalam pasukan pembangunan mudah alih

Pemalam ini mengatasi mekanisme penggabungan permintaan tarik. Permulaannya adalah standard: PR dibuka, semua perhimpunan dilancarkan, semakan kod selesai. Tetapi selepas semakan kod selesai dan pembangun memutuskan untuk mengklik pada "gabung", pemalam menyemak keadaan pembangunan yang mana semakan telah dijalankan. Jika pembangunan telah dikemas kini selepas binaan, pemalam tidak akan membenarkan permintaan tarik sedemikian digabungkan ke dalam cawangan utama. Ia hanya akan memulakan semula binaan pembangunan yang agak baru-baru ini.

Evolusi CI dalam pasukan pembangunan mudah alih

Dalam contoh kami dengan perubahan yang bercanggah, binaan sedemikian akan gagal disebabkan oleh ralat penyusunan. Sehubungan itu, pembangun ciri B perlu membetulkan kod, mulakan semula semakan, kemudian pemalam akan menggunakan permintaan tarik secara automatik.

Sebelum melaksanakan pemalam ini, kami memperoleh purata 2,7 larian semakan bagi setiap permintaan tarik. Dengan pemalam itu terdapat 3,6 pelancaran. Ini sesuai dengan kami.

Perlu diingat bahawa pemalam ini mempunyai kelemahan: ia hanya memulakan semula binaan sekali. Iaitu, masih terdapat tetingkap kecil di mana perubahan yang bercanggah boleh berkembang. Tetapi kemungkinan ini adalah rendah, dan kami membuat pertukaran ini antara bilangan permulaan dan kemungkinan kegagalan. Dalam dua tahun ia hanya menembak sekali, jadi ia mungkin tidak sia-sia.

Kami mengambil masa dua minggu untuk menulis versi pertama pemalam Bitbucket.

Cek baru

Sementara itu, pasukan kami terus berkembang. Cek baharu telah ditambah.

Kami fikir: mengapa membuat kesilapan jika ia boleh dicegah? Dan itulah sebabnya mereka melaksanakan analisis kod statik. Kami bermula dengan lint, yang disertakan dalam SDK Android. Tetapi pada masa itu dia tidak tahu cara bekerja dengan kod Kotlin sama sekali, dan kami sudah mempunyai 75% daripada aplikasi yang ditulis dalam Kotlin. Oleh itu, yang terbina dalam telah ditambahkan pada lint Android Studio menyemak.

Untuk melakukan ini, kami perlu melakukan banyak penyelewengan: ambil Android Studio, bungkusnya dalam Docker dan jalankannya pada CI dengan monitor maya, supaya ia fikir ia berjalan pada komputer riba sebenar. Tetapi ia berjaya.

Pada masa inilah juga kami mula banyak menulis ujian instrumentasi dan dilaksanakan ujian tangkapan skrin. Ini adalah apabila tangkapan skrin rujukan dijana untuk paparan kecil yang berasingan, dan ujian terdiri daripada mengambil tangkapan skrin daripada paparan dan membandingkannya dengan standard terus piksel demi piksel. Jika terdapat percanggahan, ini bermakna reka letak telah salah di suatu tempat atau ada yang salah dalam gaya.

Tetapi ujian instrumentasi dan ujian tangkapan skrin perlu dijalankan pada peranti: pada emulator atau pada peranti sebenar. Memandangkan terdapat banyak ujian dan ia dijalankan dengan kerap, keseluruhan ladang diperlukan. Memulakan ladang anda sendiri adalah terlalu intensif buruh, jadi kami menemui pilihan sedia - Firebase Test Lab.

Makmal Ujian Firebase

Ia dipilih kerana Firebase ialah produk Google, bermakna ia harus boleh dipercayai dan tidak mungkin akan mati. Harga adalah berpatutan: $5 sejam operasi peranti sebenar, 1 $ sejam operasi emulator.

Ia mengambil masa kira-kira tiga minggu untuk melaksanakan Firebase Test Lab ke dalam CI kami.

Tetapi pasukan itu terus berkembang, dan Firebase, malangnya, mula mengecewakan kami. Pada masa itu, dia tidak mempunyai sebarang SLA. Kadangkala Firebase membuatkan kami menunggu sehingga bilangan peranti yang diperlukan percuma untuk ujian dan tidak mula melaksanakannya dengan serta-merta, seperti yang kami mahu. Menunggu dalam barisan mengambil masa sehingga setengah jam, yang merupakan masa yang sangat lama. Ujian instrumentasi dijalankan pada setiap PR, kelewatan benar-benar memperlahankan pembangunan, dan kemudian bil bulanan datang dengan jumlah bulat. Secara umum, telah diputuskan untuk meninggalkan Firebase dan bekerja secara dalaman, memandangkan pasukan telah berkembang dengan cukup.

Docker + Python + bash

Kami mengambil Docker, memasukkan emulator ke dalamnya, menulis program mudah dalam Python, yang pada masa yang tepat memaparkan bilangan emulator yang diperlukan dalam versi yang diperlukan dan menghentikannya apabila perlu. Dan, sudah tentu, beberapa skrip bash - di manakah kita tanpanya?

Ia mengambil masa lima minggu untuk mencipta persekitaran ujian kami sendiri.

Akibatnya, untuk setiap permintaan tarik terdapat senarai semak penyekat gabungan yang meluas:

  • perhimpunan ARK;
  • ujian Junit;
  • Lint;
  • Semakan Android Studio;
  • Ujian instrumentasi;
  • Ujian tangkapan skrin.

Ini menghalang banyak kemungkinan kerosakan. Secara teknikal semuanya berfungsi, tetapi pemaju mengadu bahawa menunggu keputusan terlalu lama.

Berapa lama terlalu lama? Kami memuat naik data daripada Bitbucket dan TeamCity ke dalam sistem analisis dan menyedarinya purata masa menunggu 45 minit. Iaitu, pembangun, apabila membuka permintaan tarik, menunggu secara purata 45 minit untuk hasil binaan. Pada pendapat saya, ini banyak, dan anda tidak boleh bekerja seperti itu.

Sudah tentu, kami memutuskan untuk mempercepatkan semua binaan kami.

Jom percepatkan

Memandangkan binaan sering berdiri dalam baris gilir, perkara pertama yang kami lakukan ialah membeli lebih banyak perkakasan β€” pembangunan meluas adalah yang paling mudah. Binaan berhenti beratur, tetapi masa menunggu berkurangan sedikit sahaja, kerana beberapa semakan sendiri mengambil masa yang sangat lama.

Mengalih keluar semakan yang mengambil masa terlalu lama

Penyepaduan Berterusan kami boleh menangkap jenis ralat dan masalah ini.

  • Tidak akan. CI boleh menangkap ralat kompilasi apabila sesuatu tidak dibina disebabkan perubahan yang bercanggah. Seperti yang telah saya katakan, maka tiada siapa yang boleh memasang apa-apa, pembangunan terhenti, dan semua orang menjadi gugup.
  • Pepijat dalam tingkah laku. Sebagai contoh, apabila aplikasi dibina, tetapi ranap apabila anda menekan butang, atau butang tidak ditekan sama sekali. Ini buruk kerana pepijat sedemikian boleh menjangkau pengguna.
  • Pepijat dalam susun atur. Sebagai contoh, butang diklik, tetapi telah mengalihkan 10 piksel ke kiri.
  • Peningkatan hutang teknikal.

Selepas melihat senarai ini, kami menyedari bahawa hanya dua mata pertama yang kritikal. Kami mahu menangkap masalah sebegini dahulu. Pepijat dalam reka letak ditemui pada peringkat semakan reka bentuk dan boleh diperbetulkan dengan mudah kemudian. Berurusan dengan hutang teknikal memerlukan proses dan perancangan yang berasingan, jadi kami memutuskan untuk tidak mengujinya atas permintaan tarik.

Berdasarkan klasifikasi ini, kami menggoncangkan keseluruhan senarai cek. Dicoret Lint dan menangguhkan pelancarannya semalaman: hanya supaya ia akan menghasilkan laporan tentang berapa banyak masalah yang terdapat dalam projek itu. Kami bersetuju untuk bekerja secara berasingan dengan hutang teknikal, dan Pemeriksaan Android Studio telah ditinggalkan sepenuhnya. Android Studio dalam Docker untuk menjalankan pemeriksaan kelihatan menarik, tetapi menyebabkan banyak masalah dalam sokongan. Sebarang kemas kini kepada versi Android Studio bermakna perjuangan dengan pepijat yang tidak dapat difahami. Sukar juga untuk menyokong ujian tangkapan skrin, kerana perpustakaan tidak begitu stabil dan terdapat positif palsu. Ujian tangkapan skrin telah dialih keluar daripada senarai semak.

Akibatnya, kami ditinggalkan dengan:

  • perhimpunan ARK;
  • ujian Junit;
  • Ujian instrumentasi.

Cache jauh Gradle

Tanpa pemeriksaan berat, semuanya menjadi lebih baik. Tetapi tidak ada had untuk kesempurnaan!

Aplikasi kami telah dibahagikan kepada kira-kira 150 modul gradle. Cache jauh Gradle biasanya berfungsi dengan baik dalam kes ini, jadi kami memutuskan untuk mencubanya.

Cache jauh Gradle ialah perkhidmatan yang boleh membuat cache membina artifak untuk tugas individu dalam modul individu. Gradle, bukannya menyusun kod, menggunakan HTTP untuk mengetuk cache jauh dan bertanya sama ada seseorang telah melakukan tugas ini. Jika ya, ia hanya memuat turun hasilnya.

Menjalankan cache jauh Gradle adalah mudah kerana Gradle menyediakan imej Docker. Kami berjaya melakukan ini dalam masa tiga jam.

Apa yang anda perlu lakukan ialah melancarkan Docker dan menulis satu baris dalam projek itu. Tetapi walaupun ia boleh dilancarkan dengan cepat, ia akan mengambil masa yang agak lama untuk semuanya berfungsi dengan baik.

Di bawah ialah graf cache terlepas.

Evolusi CI dalam pasukan pembangunan mudah alih

Pada awalnya, peratusan kehilangan cache adalah kira-kira 65. Selepas tiga minggu, kami berjaya meningkatkan nilai ini kepada 20%. Ternyata tugas yang dikumpulkan oleh aplikasi Android mempunyai kebergantungan transitif yang aneh, yang menyebabkan Gradle terlepas cache.

Dengan menyambungkan cache, kami mempercepatkan pembinaan. Tetapi sebagai tambahan kepada pemasangan, terdapat juga ujian instrumentasi, dan mereka mengambil masa yang lama. Mungkin tidak semua ujian perlu dijalankan untuk setiap permintaan tarik. Untuk mengetahui, kami menggunakan analisis impak.

Analisis kesan

Atas permintaan tarik, kami mengumpul git diff dan mencari modul Gradle yang diubah suai.

Evolusi CI dalam pasukan pembangunan mudah alih

Adalah wajar untuk hanya menjalankan ujian instrumentasi yang menyemak modul yang diubah dan semua modul yang bergantung padanya. Tidak ada gunanya menjalankan ujian untuk modul jiran: kod di sana tidak berubah dan tiada apa yang boleh pecah.

Ujian instrumentasi tidak begitu mudah, kerana ia mesti ditempatkan dalam modul Aplikasi peringkat atas. Kami menggunakan heuristik dengan analisis bytecode untuk memahami modul yang dimiliki setiap ujian.

Menaik taraf operasi ujian instrumentasi supaya hanya menguji modul yang terlibat mengambil masa kira-kira lapan minggu.

Langkah-langkah untuk mempercepatkan pemeriksaan telah berjaya. Dari 45 minit kami naik ke kira-kira 15. Sudah menjadi perkara biasa untuk menunggu seperempat jam untuk membina.

Tetapi kini pemaju telah mula mengadu bahawa mereka tidak faham binaan mana yang sedang dilancarkan, di mana untuk melihat log, mengapa binaan berwarna merah, ujian mana yang gagal, dsb.

Evolusi CI dalam pasukan pembangunan mudah alih

Masalah dengan maklum balas memperlahankan pembangunan, jadi kami cuba memberikan maklumat yang jelas dan terperinci tentang setiap PR dan binaan yang mungkin. Kami bermula dengan ulasan dalam Bitbucket kepada PR, menunjukkan binaan mana yang gagal dan sebabnya, dan menulis mesej yang disasarkan dalam Slack. Pada akhirnya, kami mencipta papan pemuka PR untuk halaman dengan senarai semua binaan yang sedang dijalankan dan statusnya: beratur, berjalan, ranap atau selesai. Anda boleh mengklik pada binaan dan pergi ke lognya.

Evolusi CI dalam pasukan pembangunan mudah alih

Enam minggu dihabiskan untuk maklum balas terperinci.

Rancangan

Mari kita beralih kepada sejarah terkini. Setelah menyelesaikan isu maklum balas, kami mencapai tahap baharu - kami memutuskan untuk membina ladang emulator kami sendiri. Apabila terdapat banyak ujian dan emulator, ia sukar untuk dikendalikan. Akibatnya, semua emulator kami berpindah ke gugusan k8s dengan pengurusan sumber yang fleksibel.

Di samping itu, terdapat rancangan lain.

  • Kembalikan Lint (dan analisis statik lain). Kami sudah pun berusaha ke arah ini.
  • Jalankan segala-galanya pada penyekat PR ujian hujung ke hujung pada semua versi SDK.

Jadi, kami telah mengesan sejarah perkembangan Integrasi Berterusan di Avito. Sekarang saya ingin memberi nasihat dari sudut pandangan yang berpengalaman.

Π‘ΠΎΠ²Π΅Ρ‚Ρ‹

Jika saya boleh memberi hanya satu nasihat, ia adalah ini:

Sila berhati-hati dengan skrip shell!

Bash ialah alat yang sangat fleksibel dan berkuasa, ia sangat mudah dan pantas untuk menulis skrip. Tetapi anda boleh jatuh ke dalam perangkap dengannya, dan, malangnya, kami jatuh ke dalamnya.

Semuanya bermula dengan skrip mudah yang dijalankan pada mesin binaan kami:

#!/usr/bin/env bash
./gradlew assembleDebug

Tetapi, seperti yang anda tahu, segala-galanya berkembang dan menjadi lebih rumit dari masa ke masa - mari jalankan satu skrip dari yang lain, mari kita lulus beberapa parameter di sana - akhirnya kita terpaksa menulis fungsi yang menentukan pada tahap mana sarang bash kita sekarang dalam susunan untuk memasukkan petikan yang diperlukan, untuk memulakan semuanya.

Evolusi CI dalam pasukan pembangunan mudah alih

Anda boleh bayangkan kos buruh untuk pembangunan skrip tersebut. Saya menasihati anda untuk tidak jatuh ke dalam perangkap ini.

Apa yang boleh diganti?

  • Mana-mana bahasa skrip. Tulis kepada Skrip Python atau Kotlin lebih mudah kerana ia adalah pengaturcaraan, bukan skrip.
  • Atau huraikan semua logik binaan dalam bentuk Tugas gradle tersuai untuk projek anda.

Kami memutuskan untuk memilih pilihan kedua, dan kini kami memadamkan semua skrip bash secara sistematik dan menulis banyak tugas gradle tersuai.

Petua #2: Simpan infrastruktur dalam kod.

Ia adalah mudah apabila tetapan Integrasi Berterusan disimpan bukan dalam antara muka UI Jenkins atau TeamCity, dsb., tetapi dalam bentuk fail teks terus dalam repositori projek. Ini memberikan kebolehversian. Ia tidak akan sukar untuk melancarkan semula atau membina kod pada cawangan lain.

Skrip boleh disimpan dalam projek. Apa yang perlu dilakukan dengan alam sekitar?

Petua #3: Docker boleh membantu dengan persekitaran.

Ia pasti akan membantu pemaju Android; iOS belum mempunyainya, malangnya.

Ini adalah contoh fail docker mudah yang mengandungi 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 fail Docker ini (saya akan memberitahu anda rahsia, anda tidak perlu menulisnya, tetapi hanya tarik ia siap dari GitHub) dan memasang imej, anda mendapat mesin maya di mana anda boleh membina aplikasi dan menjalankan ujian Junit.

Dua sebab utama mengapa ini masuk akal ialah kebolehskalaan dan kebolehulangan. Menggunakan docker, anda boleh dengan cepat menaikkan sedozen ejen binaan yang akan mempunyai persekitaran yang sama seperti yang sebelumnya. Ini menjadikan kehidupan jurutera CI lebih mudah. Agak mudah untuk menolak android-sdk ke dalam docker, tetapi dengan emulator ia sedikit lebih sukar: anda perlu bekerja lebih keras (atau muat turun yang sudah siap dari GitHub sekali lagi).

Petua No 4: jangan lupa bahawa pemeriksaan tidak dilakukan untuk kepentingan pemeriksaan, tetapi untuk orang ramai.

Maklum balas yang cepat dan, yang paling penting, jelas adalah sangat penting untuk pembangun: apa yang rosak, apa ujian yang gagal, di mana saya boleh melihat buildlog.

Petua #5: Bersikap pragmatik apabila membangunkan Integrasi Berterusan.

Fahami dengan jelas jenis ralat yang ingin anda cegah, berapa banyak sumber, masa dan masa komputer yang anda sanggup luangkan. Cek yang mengambil masa terlalu lama boleh, sebagai contoh, ditangguhkan semalaman. Dan mereka yang menangkap kesilapan yang tidak begitu penting harus ditinggalkan sepenuhnya.

Petua #6: Gunakan alatan yang sudah siap.

Terdapat banyak syarikat sekarang yang menyediakan cloud CI.

Evolusi CI dalam pasukan pembangunan mudah alih

Ini adalah penyelesaian yang baik untuk pasukan kecil. Anda tidak perlu menyokong apa-apa, cuma bayar sedikit wang, bina aplikasi anda dan juga jalankan ujian instrumentasi.

Petua #7: Dalam pasukan yang besar, penyelesaian dalaman lebih menguntungkan.

Tetapi lambat laun, apabila pasukan berkembang, penyelesaian dalaman akan menjadi lebih menguntungkan. Terdapat satu masalah dengan keputusan ini. Terdapat undang-undang pulangan yang semakin berkurangan dalam ekonomi: dalam mana-mana projek, setiap penambahbaikan seterusnya semakin sukar dan memerlukan lebih banyak pelaburan.

Ekonomi menggambarkan seluruh kehidupan kita, termasuk Integrasi Berterusan. Saya membina jadual kos buruh untuk setiap peringkat pembangunan Integrasi Berterusan kami.

Evolusi CI dalam pasukan pembangunan mudah alih

Jelas bahawa sebarang penambahbaikan menjadi semakin sukar. Melihat graf ini, anda boleh memahami bahawa Integrasi Berterusan perlu dibangunkan selaras dengan pertumbuhan saiz pasukan. Untuk sepasukan dua orang, menghabiskan 50 hari membangunkan ladang emulator dalaman adalah idea yang biasa-biasa saja. Tetapi pada masa yang sama, untuk pasukan yang besar, tidak melakukan Integrasi Berterusan sama sekali juga merupakan idea yang tidak baik, kerana masalah integrasi, membetulkan komunikasi, dsb. ia akan mengambil lebih banyak masa.

Kami bermula dengan idea bahawa automasi diperlukan kerana orang mahal, mereka membuat kesilapan dan malas. Tetapi orang juga mengautomasikan. Oleh itu, semua masalah yang sama berlaku untuk automasi.

  • Automasi adalah mahal. Ingat jadual buruh.
  • Apabila bercakap tentang automasi, orang ramai membuat kesilapan.
  • Kadang-kadang ia sangat malas untuk mengautomasikan, kerana semuanya berfungsi dengan cara itu. Mengapa menambah baik perkara lain, mengapa semua Integrasi Berterusan ini?

Tetapi saya mempunyai statistik: ralat terperangkap dalam 20% perhimpunan. Dan ini bukan kerana pembangun kami menulis kod dengan buruk. Ini kerana pembangun yakin bahawa jika mereka membuat beberapa kesilapan, ia tidak akan berakhir dalam pembangunan, ia akan ditangkap oleh semakan automatik. Sehubungan itu, pembangun boleh menghabiskan lebih banyak masa menulis kod dan perkara yang menarik, daripada menjalankan dan menguji sesuatu secara tempatan.

Amalkan Integrasi Berterusan. Tetapi secara sederhana.

Dengan cara ini, Nikolai Nesterov bukan sahaja memberikan laporan hebat sendiri, tetapi juga ahli jawatankuasa program AppsConf dan membantu orang lain menyediakan ucapan yang bermakna untuk anda. Kesempurnaan dan kegunaan program persidangan seterusnya boleh dinilai mengikut topik dalam jadual. Dan untuk butiran, datang ke Infospace pada 22-23 April.

Sumber: www.habr.com

Tambah komen