Monorepositori: tolong

gambar


Terjemahan artikel disiapkan untuk siswa kursus Praktek dan Alat DevOps dalam proyek pendidikan OTUS .




Anda harus memilih repositori mono, karena perilaku yang dipromosikannya dalam tim Anda adalah transparansi dan tanggung jawab bersama, terutama dengan pertumbuhan tim. Bagaimanapun, Anda harus berinvestasi dalam alat, tetapi itu selalu lebih baik ketika perilaku default adalah perilaku yang ingin Anda lihat dalam perintah Anda.


Mengapa kita membicarakan ini?


Matt Klein menulis sebuah artikel, "Monorepos: Tolong jangan!" (komentar penerjemah: terjemahan pada hub "Monorepositories: tolong jangan" ). Saya suka Matt, saya pikir dia sangat cerdas, dan Anda harus membaca sudut pandangnya. Dia awalnya mentweet jajak pendapat:


gambar


Terjemahan:
Pada hari Tahun Baru ini, saya akan berdebat tentang betapa konyolnya monorepositori itu. 2019 mulai tanpa disadari. Dalam semangat ini, saya menawarkan Anda survei. Siapa fanatik besar itu? Pendukung:
- Monorepositori
- Karat
- Survei yang salah / baik itu dan itu


Jawaban saya adalah: "Saya benar-benar adalah orang-orang ini." Daripada berbicara tentang obat Rust macam apa, mari kita cari tahu mengapa saya pikir dia salah tentang repositori tunggal. Sedikit tentang dirimu. Saya adalah CTO Perangkat Lunak Chef. Kami memiliki sekitar 100 insinyur, basis kode sekitar 11-12 tahun, dan 4 produk utama. Bagian dari kode ini ada dalam polyrepository (posisi awal saya), bagian dalam monorepositori (posisi saya saat ini).


Sebelum saya mulai: setiap argumen yang saya bawa ke sini akan diterapkan pada kedua jenis repositori. Menurut pendapat saya, tidak ada alasan teknis mengapa Anda harus memilih satu atau jenis repositori lainnya. Anda dapat membuat pendekatan apa pun berhasil. Saya senang membicarakan ini, tetapi saya tidak tertarik pada alasan teknis buatan mengapa yang satu lebih unggul dari yang lain.


Saya setuju dengan bagian pertama dari sudut pandang Matt:


Karena dalam skala besar, monorepositori akan menyelesaikan semua masalah yang sama yang dipecahkan oleh polyrepository, tetapi pada saat yang sama memprovokasi Anda untuk koherensi yang kuat dari kode Anda dan membutuhkan upaya luar biasa untuk meningkatkan skalabilitas sistem kontrol versi Anda.


Anda harus menyelesaikan masalah yang sama, terlepas dari apakah Anda memilih repositori mono atau repositori. Bagaimana Anda merilis rilis? Apa pendekatan Anda terhadap pembaruan? Kompatibel dengan belakang? Ketergantungan lintas proyek? Gaya arsitektur apa yang dapat diterima? Bagaimana Anda mengelola infrastruktur bangunan dan pengujian Anda? Daftar ini tidak ada habisnya. Dan Anda akan menyelesaikan semuanya saat Anda tumbuh. Tidak ada keju gratis.


Saya pikir argumen Matt mirip dengan pandangan yang dibagikan oleh banyak insinyur (dan manajer) yang saya hormati. Ini terjadi dari sudut pandang insinyur yang mengerjakan komponen, atau tim yang mengerjakan komponen. Anda mendengar hal-hal seperti:


  • Basis kode rumit - saya tidak perlu semua sampah ini.
  • Ini lebih sulit untuk diuji karena saya harus memeriksa semua sampah yang tidak saya butuhkan.
  • Lebih sulit untuk bekerja dengan ketergantungan eksternal.
  • Saya membutuhkan sistem kontrol versi virtual saya sendiri.

Tentu saja, semua poin ini masuk akal. Ini terjadi dalam kedua kasus - dalam repositori saya memiliki barang-barang saya sendiri, selain yang dibutuhkan untuk perakitan ... Saya mungkin perlu barang lain juga. Karena itu, saya "hanya" membuat alat yang memeriksa seluruh proyek. Atau apakah saya membuat repositori mono palsu dengan submodul. Kita bisa berjalan sepanjang hari di sekitar ini. Tapi saya pikir argumen Matt melewatkan alasan utama, yang saya cukup banyak berpihak pada monorepositori:


Ini memancing komunikasi dan menunjukkan masalah.


Ketika kami berbagi repositori, kami secara de facto menciptakan masalah koordinasi dan transparansi. Ini sesuai dengan cara kita berpikir tentang tim (terutama cara masing-masing peserta memikirkannya): kita bertanggung jawab atas komponen tertentu. Kami bekerja dalam isolasi relatif. Batas-batas ditetapkan pada tim saya dan komponen yang sedang kami kerjakan.


Dengan kompleksitas arsitekturnya, satu tim tidak bisa lagi mengelolanya sendiri. Sangat sedikit insinyur yang menyimpan seluruh sistem di kepala mereka. Misalkan Anda mengontrol komponen umum A, yang digunakan oleh perintah B, C, dan D. Tim A refactores, meningkatkan API, dan juga mengubah implementasi internal. Akibatnya, perubahan mundur tidak kompatibel. Apa saran yang akan Anda berikan?


  • Temukan semua tempat di mana API lama digunakan.
  • Apakah ada tempat di mana API baru tidak dapat digunakan?
  • Bisakah Anda memperbaiki dan menguji komponen lain untuk memastikan mereka tidak rusak?
  • Bisakah tim ini memeriksa perubahan Anda sekarang?

Harap dicatat bahwa pertanyaan-pertanyaan ini tidak tergantung pada jenis repositori. Anda perlu menemukan tim B, C, dan D. Anda perlu berbicara dengan mereka, mencari tahu waktu, memahami prioritas mereka. Setidaknya kami harap Anda melakukannya.


Tidak ada yang benar-benar ingin melakukan ini. Ini jauh lebih tidak menyenangkan daripada hanya memperbaiki API sialan. Semua ini manusia dan bingung. Di repositori, Anda bisa membuat perubahan, memberikan ulasan kepada mereka yang mengerjakan komponen ini (mungkin bukan B, C atau D), dan melanjutkan. Tim B, C, dan D bisa tetap menggunakan versi mereka saat ini. Mereka akan diperbarui ketika mereka menyadari kejeniusan Anda!


Dalam repositori tunggal, tanggung jawab digeser secara default. Tim A mengganti komponennya dan, jika tidak hati-hati, segera memecahkan B, C dan D. Ini menyebabkan B, C dan D muncul di pintu A, bertanya-tanya mengapa tim A merusak perakitan. Ini mengajarkan A bahwa mereka tidak dapat melewati daftar saya di atas. Mereka harus berbicara tentang apa yang akan mereka lakukan. Bisakah B, C, dan D bergerak? Bagaimana jika B dan C bisa, tetapi D terkait erat dengan efek samping dari algoritma lama?


Maka kita perlu berbicara tentang bagaimana kita keluar dari situasi ini:


  1. Dukungan untuk beberapa API internal, sedangkan algoritma lama akan ditandai usang sampai D dapat berhenti menggunakannya.
  2. Dukungan untuk beberapa versi rilis, satu dengan antarmuka lama, satu dengan yang baru.
  3. Tertunda rilis perubahan ke A sampai B, C, dan D dapat menerimanya.

Misalkan kita memilih 1, beberapa API. Dalam hal ini, kami memiliki dua potong kode. Tua dan baru. Cukup berguna dalam beberapa situasi. Kami mengembalikan kode lama kembali, tandainya sudah usang dan menyepakati jadwal untuk penghapusan dengan perintah D. Ini pada dasarnya identik untuk poli dan untuk monorepositori.


Untuk merilis beberapa versi, kami membutuhkan cabang. Sekarang kami memiliki dua komponen - A1 dan A2. Tim B dan C menggunakan A2, dan D menggunakan A1. Kami membutuhkan setiap komponen untuk siap dirilis, karena sebelum D dapat melanjutkan, pembaruan keamanan dan perbaikan bug lainnya mungkin diperlukan. Dalam repositori, kita bisa menyembunyikannya di cabang berumur panjang yang terasa enak. Dalam mono-repositori, kami memaksakan kode dalam modul baru. Tim D masih harus melakukan perubahan pada komponen "lama". Semua orang dapat melihat biaya yang kami bayarkan di sini - kami sekarang memiliki kode dua kali lebih banyak, dan perbaikan bug apa pun yang berlaku untuk A1 dan A2 harus diterapkan pada keduanya. Dengan pendekatan menggunakan cabang dalam repositori, ini tersembunyi di balik cherry-pick. Kami menganggap biaya lebih murah karena tidak ada duplikasi. Dari sudut pandang praktis, biayanya sama: Anda akan membuat, melepaskan, dan memelihara dua basis kode, yang pada dasarnya identik, hingga Anda dapat menghapus salah satunya. Perbedaannya adalah bahwa dalam monorepositori, nyeri ini langsung dan terlihat. Ini bahkan lebih buruk dan bagus.


Akhirnya, kami sampai pada poin ketiga. Lepaskan penundaan. Mungkin saja perubahan yang dilakukan oleh A akan meningkatkan kehidupan tim A. Ini penting, tetapi tidak mendesak. Bisakah kita bertahan? Dalam repositori, kami mendorong ini untuk mengkonsolidasikan artefak. Tentu saja, kita berbicara tentang tim ini D. Tetaplah pada versi lama sampai Anda menyusul! Ini membuat game pengecut. Tim A terus bekerja pada komponennya, mengabaikan fakta bahwa Tim D menggunakan versi yang semakin usang (ini adalah masalah bagi Tim D, mereka bodoh). Sementara itu, tim D berbicara buruk tentang sikap ceroboh Tim A terhadap stabilitas kode, jika mereka membicarakannya sama sekali. Bulan berlalu. Akhirnya, tim D memutuskan untuk melihat opsi peningkatan, tetapi hanya ada lebih banyak perubahan pada A. Tim A hampir tidak ingat kapan dan bagaimana mereka melanggar D. Memperbarui lebih menyakitkan dan akan lebih lama. Yang mengirimkannya lebih jauh ke tumpukan prioritas. Sampai hari itu, sampai kita memiliki masalah keamanan di A, yang memaksa kita untuk membuat cabang. Tim A harus kembali ke masa lalu, menemukan momen ketika D stabil, memperbaiki masalah di sana dan membuatnya siap untuk dirilis. Ini adalah pilihan de facto yang dibuat orang, dan sejauh ini yang terburuk. Ini sepertinya baik untuk tim A dan D, selama kita bisa mengabaikan satu sama lain.


Dalam monorepositori, yang ketiga benar-benar bukan pilihan. Anda dipaksa untuk menghadapi situasi dengan salah satu dari dua cara. Anda perlu melihat biaya memiliki dua cabang rilis. Pelajari cara melindungi diri dari pembaruan yang merusak kompatibilitas. Tetapi yang utama: Anda tidak bisa menghindari percakapan yang sulit.


Dalam pengalaman saya, ketika tim menjadi besar, tidak mungkin lagi mengingat seluruh sistem, dan ini adalah bagian terpenting. Anda harus meningkatkan visibilitas peluang di sistem. Anda harus bekerja secara aktif untuk membuat tim mengalihkan pandangan dari komponen mereka dan melihat karya tim dan konsumen lain.


Ya, Anda bisa membuat alat yang akan mencoba menyelesaikan masalah polrepositori. Tetapi pengalaman saya dalam mengajar pengiriman terus menerus dan otomatisasi di perusahaan besar memberi tahu saya hal berikut: perilaku default tanpa menggunakan alat tambahan adalah perilaku yang Anda harapkan untuk dilihat. Perilaku default repositori adalah isolasi, itulah intinya. Perilaku default mono-repositori adalah tanggung jawab dan transparansi bersama, itulah intinya. Dalam kedua kasus, saya akan membuat alat yang akan melicinkan sudut tajam. Sebagai pemimpin, saya akan memilih repositori mono setiap saat, karena instrumen harus memperkuat budaya yang saya inginkan, dan budaya berasal dari keputusan kecil dan pekerjaan sehari-hari tim.

Source: https://habr.com/ru/post/id453958/


All Articles