Saya sedang mengerjakan proyek open-source yang dipimpin oleh penelitian yang sangat besar, dengan sekelompok kontributor reguler lainnya. Karena proyek ini sekarang cukup besar, sebuah konsorsium (terdiri dari dua karyawan penuh waktu dan beberapa anggota) bertugas menjaga proyek, integrasi berkelanjutan (CI), dll. Mereka hanya tidak punya waktu untuk integrasi eksternal kontribusi sekalipun.
Proyek ini terdiri dari kerangka kerja "inti", dari sekitar setengah juta baris kode, sekelompok "plugin" yang dikelola oleh konsorsium, dan beberapa plugin eksternal, yang sebagian besar kami miliki bahkan tidak sadar.
Saat ini, CI kami membangun inti, dan plugin yang dikelola.
Salah satu masalah besar yang kita hadapi adalah sebagian besar kontributor (dan terutama kontributor sekali-sekali) tidak membangun 90% dari plugin yang dikelola, jadi ketika mereka mengusulkan perubahan refactor di inti (yang hari ini terjadi secara cukup teratur), mereka memeriksa kode yang dikompilasi pada mesin mereka sebelum membuat permintaan tarik pada GitHub.
Kode berfungsi, mereka senang, dan kemudian CI selesai membangun dan masalah mulai: kompilasi gagal dalam plugin yang dikelola konsorsium, bahwa kontributor tidak membangun di mesinnya.
Plugin itu mungkin memiliki ketergantungan pada pustaka pihak ketiga, seperti CUDA misalnya, dan pengguna tidak mau, tidak tahu bagaimana caranya, atau tidak bisa karena alasan perangkat keras, kompilasi plugin yang rusak itu.
Jadi - baik PR tetap aeternam iklan di limbo tidak pernah-to-be-digabung PR - Atau kontributor greps variabel yang diganti nama di sumber plugin rusak, perubahan kode, dorongan pada nya / cabang nya, menunggu CI untuk menyelesaikan kompilasi, biasanya mendapat lebih banyak kesalahan, dan mengulangi prosesnya sampai CI senang - Atau salah satu dari dua permanen yang sudah terlalu padat dalam konsorsium memberikan bantuan dan mencoba memperbaiki PR pada mesin mereka.
Tidak satu pun dari opsi-opsi itu yang layak, tetapi kami hanya tidak tahu bagaimana melakukannya secara berbeda. Pernahkah Anda dihadapkan pada situasi yang serupa dengan proyek Anda? Dan jika demikian, bagaimana Anda menangani masalah ini? Apakah ada solusi yang tidak saya lihat di sini?
sumber
Jawaban:
Pengembangan yang digerakkan oleh CI baik-baik saja! Ini jauh lebih baik daripada tidak menjalankan tes dan termasuk kode yang rusak! Namun, ada beberapa hal untuk mempermudah ini pada semua orang yang terlibat:
Tetapkan harapan: Memiliki dokumentasi kontribusi yang menjelaskan bahwa CI sering menemukan masalah tambahan, dan bahwa ini harus diperbaiki sebelum penggabungan. Mungkin jelaskan bahwa perubahan lokal yang lebih kecil cenderung bekerja dengan baik - jadi memecah perubahan besar menjadi banyak PR bisa masuk akal.
Dorong pengujian lokal: Memudahkan mengatur lingkungan pengujian untuk sistem Anda. Sebuah skrip yang memverifikasi bahwa semua dependensi telah diinstal? Wadah Docker yang siap digunakan? Gambar mesin virtual? Apakah pelari ujian Anda memiliki mekanisme yang memungkinkan diprioritaskannya tes yang lebih penting?
Jelaskan bagaimana menggunakan CI untuk diri mereka sendiri: Bagian dari frustrasi adalah bahwa umpan balik ini hanya datang setelah mengirimkan PR. Jika kontributor mengatur CI untuk repositori mereka sendiri, mereka akan mendapatkan umpan balik lebih awal - dan menghasilkan lebih sedikit pemberitahuan CI untuk orang lain.
Selesaikan semua PR, jika : Jika sesuatu tidak dapat digabungkan karena rusak, dan jika tidak ada kemajuan untuk menyelesaikan masalah, tutup saja. PR terbuka yang terabaikan ini hanya mengacaukan segalanya, dan umpan balik apa pun lebih baik daripada hanya mengabaikan masalah. Dimungkinkan untuk mengutarakan ini dengan sangat baik, dan membuatnya jelas bahwa tentu saja Anda akan senang untuk bergabung ketika masalah diperbaiki. (lihat juga: Seni Penutup oleh Jessie Frazelle , Praktik Terbaik untuk Pemelihara: Belajar mengatakan tidak )
Juga pertimbangkan untuk membuat PR yang ditinggalkan ini dapat ditemukan sehingga orang lain dapat mengambilnya. Ini bahkan mungkin merupakan tugas yang baik untuk kontributor baru, jika masalah yang tersisa lebih mekanis dan tidak perlu akrab dengan sistem.
Untuk perspektif jangka panjang, perubahan itu tampaknya merusak fungsionalitas yang tidak terkait sehingga seringkali dapat berarti bahwa desain Anda saat ini agak bermasalah. Misalnya, apakah antarmuka plugin dengan benar merangkum internal Anda? C ++ membuatnya mudah untuk secara tidak sengaja membocorkan detail implementasi, tetapi juga memungkinkan untuk membuat abstraksi yang kuat yang sangat sulit untuk disalahgunakan. Anda tidak dapat mengubahnya dalam semalam, tetapi Anda dapat menggembalakan evolusi jangka panjang dari perangkat lunak menuju arsitektur yang kurang rapuh.
sumber
Membangun model plugin yang berkelanjutan mengharuskan kerangka kerja inti Anda mengekspos antarmuka yang stabil yang dapat diandalkan oleh plugin. Aturan utamanya adalah Anda dapat memperkenalkan antarmuka baru dari waktu ke waktu tetapi Anda tidak pernah dapat memodifikasi antarmuka yang sudah diterbitkan. Jika Anda mengikuti aturan ini, Anda bisa menolak pelaksanaan kerangka kerja inti semua yang Anda inginkan tanpa takut melanggar plugin, baik itu yang dikelola oleh konsorsium atau eksternal.
Dari apa yang Anda jelaskan, sepertinya Anda tidak memiliki antarmuka yang terdefinisi dengan baik, dan itu membuatnya sulit untuk mengetahui apakah perubahan akan merusak plugin. Berusahalah mendefinisikan antarmuka ini dan membuatnya eksplisit dalam basis kode Anda, sehingga kontributor akan tahu apa yang tidak boleh mereka modifikasi.
sumber
Sejujurnya, saya tidak berpikir Anda bisa menangani ini dengan cara yang lebih baik - jika perubahan mengakibatkan rusaknya bagian proyek Anda , CI seharusnya gagal.
Apakah proyek Anda memiliki
contributing.md
atau sesuatu yang serupa untuk membantu kontributor baru dan sesekali mempersiapkan kontribusi mereka? Apakah Anda memiliki daftar yang jelas, plugin mana yang merupakan bagian dari inti dan perlu tetap kompatibel?Jika sulit untuk membangun semuanya di atas mesin karena ketergantungan dll Anda dapat berpikir tentang membuat gambar buruh pelabuhan yang siap pakai sebagai lingkungan pembangun yang digunakan oleh kontributor Anda.
sumber
Jadi saya pikir di sinilah gaya longgar proyek open source dapat jatuh; sebagian besar proyek yang dikelola secara terpusat mewaspadai refactoring inti, terutama ketika melintasi batas API. Jika mereka melakukan refactor terhadap batas API, biasanya merupakan "big bang" di mana semua perubahan dijadwalkan sekaligus dengan peningkatan ke versi utama API, dan API lama dipertahankan.
Saya akan mengusulkan aturan "semua perubahan API harus direncanakan terlebih dahulu": jika seorang PR masuk yang membuat perubahan yang tidak kompatibel ke belakang ke API, dari seseorang yang belum pernah berhubungan dengan pengelola untuk menyetujui pendekatan mereka sebelumnya, itu hanya akan ditutup dan pengirim menyerahkan pada aturan.
Anda juga akan membutuhkan versi eksplisit dari plugin API. Ini memungkinkan Anda untuk mengembangkan v2 sementara semua plugin v1 terus membangun dan bekerja.
Saya juga akan mempertanyakan lebih banyak mengapa begitu banyak inti refactoring dan perubahan API sedang dibuat. Apakah mereka benar-benar perlu atau hanya orang yang memaksakan selera pribadi mereka pada proyek?
sumber
Kedengarannya seperti proses CI harus lebih ketat, lebih komprehensif dan lebih terlihat oleh kontributor sebelum mereka menaikkan PR. Sebagai contoh, BitBucket memiliki fitur jalur pipa yang memungkinkan ini, di mana Anda memberikannya file yang menentukan dalam kode proses pembangunan CI, dan jika gagal, cabang dicegah dari digabung.
Terlepas dari teknologinya, menyediakan pemuatan otomatis ketika kontributor mendorong ke cabang akan memberi mereka umpan balik yang lebih cepat dari apa yang harus diwaspadai yang harus diperhatikan ketika melakukan perubahan dan akan mengarah pada PR yang tidak perlu memperbaiki setelah fakta.
Masalah desain akan baik untuk diperbaiki, tetapi ortogonal untuk masalah ini.
sumber
Solusi Anda sederhana: turunkan penghalang kontribusi .
Cara paling sederhana untuk (1) mempercepat siklus edit-kompilasi-uji dan (2) perbedaan lingkungan yang halus adalah menyediakan server-server pembangun :
Dan kemudian buka server pembangun itu untuk kontributor. Mereka harus dapat login jarak jauh di gambar Docker baru, dan mengedit-kompilasi-uji jarak jauh pada mesin ini.
Kemudian:
Secara umum, build server dapat dibagikan di beberapa kontributor, namun ketika perangkat keras khusus terlibat, kontributor harus menggunakan perangkat tersebut sendiri.
Sumber: mengerjakan perangkat lunak menggunakan FPGA, mengingat harga beast, dan beragam model yang kami butuhkan, Anda tidak menemukan setiap model FPGA diinstal pada mesin setiap pengembang.
sumber
Jika berkontribusi pada inti tanpa mengubah kontrak apa pun dapat merusak perangkat lunak dependen, ini menunjukkan bahwa:
Salah satu masalah seharusnya mudah dipecahkan, tetapi Anda menyebutkan tim inti mungkin tidak memiliki kapasitas untuk melakukannya. Salah satu opsi adalah meminta bantuan komunitas dalam menangani masalah ini.
sumber
Sepertinya tidak ada orang lain yang mengangkat ini sebagai solusi potensial.
Saat mengembangkan inti, dorong pengembang untuk menjalankan tes kompatibilitas ini. Jika gagal, jangan check-in.
Ini tidak akan 100% memastikan kompatibilitas tetapi akan menangkap lebih banyak masalah dan lebih awal.
Manfaat kedua adalah bahwa rekaman ini dapat menyoroti antarmuka mana yang aktif digunakan, dan fitur apa yang sedang aktif digunakan.
sumber
Saya mengalami kesulitan memahami situasinya: CI hanya membangun satu cabang?
Apakah ada alasan Anda tidak dapat membangun lebih dari satu cabang dengan CI?
Solusi paling sederhana untuk masalah ini adalah dengan memungkinkan kontributor untuk menjalankan pembangunan CI pada cabang fitur-nya .
Maka Anda hanya perlu membangun CI yang sukses di cabang fitur agar permintaan tarik cabang itu dapat diterima.
sumber