Прочитав пару тижнів назад у пана К. (в «Мамкіному Архітекторі») допис із закликом писати в коментарі, хто чим користувався. І там хто про шо — від
make до Jenkins. Воно й дійсно різниця не завжди очевидна, бо і те, й інше може виконувати приблизно ту саму роботу, а саме: запускати якісь скрипти, що викликають тули, туди-сюди перекладають файли, качають щось з інтернетів тощо.Раніше я вже казав, що люблю, коли можна повністю зібрати й запустити проєкт однією командою, проте, так було не завжди. Користувався я й TeamCity, і Jenkins і ще бозна-чим. Коли GitHub Actions зʼявилися, я одразу на них перестрибнув через їхню (нібіто) простоту. Тож білд-система в мене щось компілювала базово, а потім вже Actions хоп-хоп файли кудись з теки у теку поклали, заархівували або викликали скрипт для інсталятора й оце все. Іншими словами, побудова проєкту була розмазана між білд-системою і CI.
Це незручно з низки причин.
По-перше, CI-ні скрипти дуже важко запускати локально: на вашому CI-сервері є власне оточення, нерідко доволі крихке 😆 гг, а також є купа додаткових штук для якоїсь там безпеки та ізоляції (щоб не вийшло, що дві джоби якось конфліктують) — це все важко, та й не сильно треба повторити локально. І якщо частину важливої роботи робить саме CI, то в якийсь момент може виявитися, що ніхто не знає, як той проєкт взагалі зібрати без нього. Небезпечна залежність, ще й потенційно «вузьке місце».
По-друге, якщо щось піде не так на CI, а щось раз у раз йде не так, то полагодити це стає значно складніше. Навіть діагностувати не завжди легко, особливо якщо локально важко запустити. Підтримкою неперервної інтеграції найчастіше займається окрема команда, доступи до всього є тільки в них, специфіку й нюанси оточення розуміють тільки вони — інша залежність і вузьке місце ланцюжка.
Тобто є сенс якомога більше речей виводити на рівень нижче (що корелює з загальним розумінням і практиками) — у білд-систему. Чи можна було б наробити 🐈 Actions для виклику окремо компілятора, окремо компонувальника, окремо тулів для підписування бінарів ключем? Та можна, але чомусь ніхто так не робить. Беручи це до уваги, стає очевидним, що інші задачі також краще виконувати на рівні білд-системи: встановлювати залежності, пакувати документацію, збирати інсталятори тощо.
А чи є сенс іти ще на рівень нижче — у саму програму? Мабуть можна й без білд-системи обходитися, але тут вже треба оцінювати складність і вартість. Наразі не маю для цього хороших прикладів використання на думці.
Урешті в тому проєкті ми досягли відносного успіху. Головна частина нашої джоби на CI мала отакий вигляд:
- name: Create package
run: qbs build config:release profile:github-${{ matrix.os }}-ci qbs.architecture:${{ env.QBS_ARCH }} -p megaapp-${{ matrix.os }}-installer
Буквально одна команда, яка все збирає і пакує. Але необхідні залежності вже були в оточенні (компілятор + Conan + Qt). А зараз з Xmake навіть це не обовʼязково, бо він вміє все сам стягувати.
Розумію, що в декого «поцікавіше» ситуації бувають, коли локально в принципі важко щось запустити, бо треба мільйон контейнерів підняти в кластері. Можу хіба що поспівчувати, бо це дійсно складно без належної організації процесів 🙂 Утім навіть у таких умовах можна зробити зручно, я певен.