Continuous Integration як практика, а не Jenkins. Андрій Олександров

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Обговоримо чому CI-інструменти та CI – це зовсім про різне.

Який біль CI покликане вирішити, звідки виникла ідея, які останні підтвердження що воно працює, як зрозуміти, що у вас є саме практика, а не просто встановлений Jenkins.

Думка зробити доповідь про Continuous Integration з'явилася ще рік тому, коли я ходив співбесід шукав роботу. Поспілкувався з 10-15 компаніями, з них лише одна змогла зрозуміло відповісти, що таке CI і пояснити, як вони зрозуміли, що у них цього немає. Інші ж несли незрозумілу нісенітницю про Jenkins 🙂 Ну ось у нас є Jenkins, він робить збірки, CI! За доповідь постараюся пояснити, що ж таке Continuous Integration насправді і чому Jenkins і подібні інструменти мають дуже слабке до цього ставлення.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

І так, що зазвичай спадає на думку при слові CI? Більшості людей спаде на думку Jenkins, Gitlab CI, Travis тощо.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Навіть якщо ми загуглимо, нам видасть ці інструменти.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Якщо питати знайомі, то відразу після перерахування інструментів, вам розкажуть що CI це коли у вас в Pull Request на коміт відбувається збирання та прогін тестів.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Continuous Integration це не про інструменти, не про збирання з тестами у гілці! Continuous Integration - це практика дуже частої інтеграції нового коду і для її застосування зовсім не обов'язково городити Jenkins-и, GitLab-и і т.п.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Перш ніж ми розберемося як виглядає повноцінний CI, давайте спочатку поринемо в контекст людей, які це вигадали, і відчуємо той біль, який вони намагалися вирішити.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

А вирішували вони біль спільної роботи у команді!

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Давайте подивимося на прикладах, з якими труднощами стикаються розробники командної розробки. Ось у нас є проект, master-гілка в git і два розробники.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

І пішли вони працювати, як усі давно звикли. Взяли завдання у жирі, завели feature branch, пишуть код.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Один закінчив фічу швидше та смержив у майстер.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Другому знадобилося більше часу, він смержів пізніше і отримав конфлікт. Тепер замість того, щоб писати потрібні бізнесу фічі, розробник витрачає свій час і сили на вирішення конфліктів.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Чим складніше поєднати свою фічу із спільним майстром, Тим більше часу ми на це витрачаємо. І це ще досить простий приклад показав. Це приклад, де розробників всього 2. А уявіть, якщо 10 чи 15, чи 100 осіб у компанії пишуть в один репозиторій. Ви збожеволієте всі ці конфлікти вирішувати.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Є трохи інший випадок. У нас є майстер та кілька розробників, які щось роблять.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Вони створили гілочкою.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Один смержився, все добре, здав завдання.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Другий розробник тим часом здав своє завдання. Допустимо, він віддав її на ревину. Багато компаній є практика – ревью. З одного боку, це практика – хороша та корисна, з іншого боку, це нас багато в чому десь гальмує. Не будемо в це занурюватися, але чудовий приклад, до чого може привести крива історія з ревью. Ви віддали pull request на реву. Розробнику більше нема чого робити. Що він починає робити? Він починає брати інші завдання.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

За цей час другий розробник ще щось поробив.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Перший виконав третє завдання.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

І через якийсь тривалий час його ревью випробували, і він намагається смердитися. І що відбувається? Він ловить дуже багато конфліктів. Чому? Тому що, поки його pull request висів на рев'ю, в коді вже багато чого змінилося.

Окрім історії з конфліктами, є історія з комунікаціями. Поки у вас гілочка висить на реву, поки вона чогось чекає, поки ви довго пиляєте фічу, ви перестаєте відстежувати, що ще в кодовій базі вашого сервісу змінюється. Можливо те, що зараз ви намагаєтеся вирішити, це вже вирішили вчора і можна взяти і якийсь метод перевикористовувати. Але ви цього не побачите, тому що ви працюєте завжди із застарілою гілкою. І ця застаріла гілка завжди призводить до того, що вам доведеться вирішувати мерж-конфлікт.

Виходить, що якщо ми працюємо командою, тобто не одна людина в репозиторії колупається, а людина 5-10, то чим довше ми не додаємо свій код у майстер, тим більше ми страждаємо від того, що на зрештою потрібно що- щось смержити. І чим більше у нас конфліктів, і чим із старішою версією ми працюємо, тим більше у нас проблем.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Спільно щось робити – боляче! Ми один одному завжди заважаємо.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

На цю проблему звернули увагу 20 років тому. Першу згадку про практику Continuous Integration я знайшов у екстремальному програмуванні.

Екстремальне програмування – це перший agile framework. Сторінка з'явилася 96-го року. І була ідея використовувати якісь практики програмування, планування та іншого, щоб розробка була якомога гнучкішою, щоб ми могли швидше реагувати на якісь зміни, вимоги від наших клієнтів. І вони 24 роки тому почали з цим стикатися, що якщо ти робиш щось дуже довго і осторонь, то ти витрачаєш на це більше часу, бо маєш конфлікти.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Зараз ми розберемо словосполучення Continuous Integration за окремими словами. Якщо переводити в лоб, то виходить безперервна інтеграція. Але наскільки вона безперервна не дуже зрозуміла, вона дуже перервна. Але скільки її integration теж не дуже очевидно.

І тому я наводжу вам зараз цитати із екстремального програмування. І ми обидва слова розберемо окремо.

Integration — Як я вже сказав, ми прагнемо того, щоб кожен інженер працював із найактуальнішою версією коду, щоб він свій код прагнув додавати якнайчастіше в загальну гілочку, щоб це були маленькі гілочки. Тому що якщо вони великі, то можемо легко на тиждень застрягти з мерж-конфліктами. Особливе, якщо ми маємо довгий цикл розробки типу waterfall, де розробник пішов на місяць пиляти якусь величезну фічу. І він на етапі інтеграції застрягне дуже надовго.

Integration – це коли ми беремо свою гілочку та інтегруємо її із майстром, ми її мержемо. Є ультимативний варіант, коли ми transbase developer, де ми прагнемо до того, що ми відразу в майстер пишемо без зайвих гілочок.

Загалом, integration - це взяти свій код і дотягнути його до майстер.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Що тут мається на увазі під словом "continuous", що називається безперервністю? Практика передбачає, що розробник прагне інтегрувати свій код якнайшвидше. Це його мета при виконанні будь-якого завдання - зробити так, щоб його код з'явився в майстрі якнайшвидше. В ідеальному світі розробники це робитимуть кожні кілька годин. Т. е. ти береш маленьке завдання, мержиш її в майстер. Все чудово. Ти цього прагнеш. І робити це треба безперервно. Як тільки ти щось зробив, ти одразу це вганяєш у майстер.

І розробник, який щось робить, відповідальний за те, що він зробив, щоб це працювало і нічого не зламало. Ось тут зазвичай і вилазить історія із тестами. Ми хочемо прогнати якісь тести на наш коміт, на наш мерж, щоби переконатися, що це працює. І тут вам можуть допомогти Jenkins.

Але з історіями: а давайте зміни будуть дрібними, а давайте завдання будуть дрібними, а давайте ми завдання зробимо і відразу ж спробуємо якось вмержити її в майстер - ось тут ніякі Jenkins не допоможуть. Тому що Jenkins вам допоможуть лише запустити тести.

Ви можете обійтися без них. Це вам анітрохи не завадить. Тому що мета практики – це мерзнеться якнайчастіше, щоб не витрачати величезну кількість часу на якісь конфлікти в майбутньому.

Уявімо, що у нас 2020 рік чомусь без інтернету. І ми локально працюємо. Ми не маємо Jenkins. Це нормально. Ви досі можете взяти та зробити локальну гілочку. Ви у ній написали якийсь код. Зробили завдання за 3-4 години. Перейшли на майстер, зробили git pull, вмержили туди свою гілку. Готово. Якщо ви робите це часто – вітаю, у вас є Continuous Integration!

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Які в світі є пруфи на тему того, що на це варто витрачати сили? Тому що загалом це складно. Якщо ви спробуєте так попрацювати, то ви зрозумієте, що у вас зараз зачепиться якесь планування, вам доведеться більше часу приділяти декомпозування завдань. Тому що якщо ви робитимете man…, то ви смердитися не зможете швидко і, відповідно, потрапите в просак. Практики вже не буде.

І це буде дорого. Працювати відразу з завтрашнього дня по Continuous Integration не вдасться. Ви всі будете дуже довго звикати, дуже довго привчатиметеся декомпозувати завдання, дуже довго привчатиметеся переробляти практику ревью, якщо вона у вас є. Тому що наша мета, щоб воно смердилося сьогодні. А якщо ви ревю робите протягом трьох днів, то у вас проблеми і Continuous Integration у вас не виходить.

Але якісь у нас є актуальні пруфи зараз, які нам кажуть, що інвестувати в цю практику має сенс?

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Перше, що мені спало на думку – це State of DevOps. Це дослідження, яке хлопці проводять уже 7 років. зараз вони це роблять як незалежна організація, але під Google.

І їх дослідження в 2018-му році показало кореляцію між компаніями, які намагаються використовувати короткоживучі гілочки, які інтегруються швидко, інтегруються часто, мають більш красиві показники продуктивності IT.

Що це за показники? Це 4 метрики, які вони знімають з усіх компаній у своїх опитувальниках: deployment frequency, lead time for changes, time to restore service, change failure rate.

І, по-перше, є ось ця кореляція, ми знаємо, що компанії, які часто мерзнуться, у них ці метрики сильно кращі. І вони мають розбиття компаній на кілька категорій: це повільні компанії, які виробляють щось повільно, medium performer, high performer і еліта. Еліта - це Netflix, Amazon, які супершустрые, все роблять швидко, красиво та якісно.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Друга історія, що сталася буквально місяць тому. У Technology Radar з'явилася чудова нотатка про Gitflow. Gitflow відрізняється від решти тим, що його гілки живуть довго. Є релізні гілки, які довго живуть, фічі branches, які теж довго живуть. Ця практика в Technology Radar перемістилася до HOLD. Чому? Тому що люди стикаються із болем інтеграції.

Якщо в тебе гілка живе дуже довго, вона встреває, протухає, ми починаємо витрачати більше часу на те, щоб внести до неї якусь зміну.

І нещодавно автор Gitflow сказав, що якщо ви прагнете Continuous Integration, якщо ви прагнете того, що ви хочете котитися якнайчастіше, то Gitflow – це погана ідея. Він окремо в статтю дописав, що якщо у вас бекенд, де ви можете до цього прагне, то Gitflow вам зайвий, тому що Gitflow вас уповільнить, Gitflow вам створить проблеми з інтеграцією.

Це не означає, що Gitflow є поганим і їм не треба користуватися. Він для інших випадків. Наприклад, коли вам потрібно підтримувати кілька версій сервісу, програми, тобто де вам потрібно сапортувати протягом якогось тривалого часу.

Але якщо ви поспілкуєтеся з людьми, які такі сервіси підтримують, то ви почуєте багато болю про те, що ця версія була 3.2, яка була 4 місяці тому, а до неї не потрапив цей фікс і тепер, щоб її внести, потрібно внести купу змін . І ось вони знову застрягли, і ось вони тиждень колупаються для того, щоб взяти і смержити якусь нову фічу.

Як Олександр Ковальов правильно зауважив у чаті, кореляція – це не одно причинно-наслідкового зв'язку. Це так. Т. е. якийсь прямий зв'язок, що якщо у вас Continuous Integration, то всі метрики будуть шикарними, ні. Але є позитивна кореляція, якщо одне, то, швидше за все, інше теж. Не факт, але швидше за все. Це лише кореляція.

Continuous Integration як практика, а не Jenkins. Андрій Олександров

Начебто ми вже щось робимо, начебто ми вже мерзнемося, але як зрозуміти, що Continuous Integration у нас все-таки є, що мерзнемось досить часто?

Jez Humble – автор Handbook, Accelerate, сайту Continuous Delivery та книжки «Continuous Delivery». Він пропонує такий тест:

  • Код інженера потрапляє у майстер щодня.
  • На кожен коміт ви запускаєте unit-тести.
  • Білд у майстрі впав, його полагодили приблизно за 10 хвилин.

Він пропонує використовувати такий тест, щоб переконатися, що практика у вас є.

Останнє я знаходжу трохи спірним. Т. е. якщо ви можете полагодити за 10 хвилин, значить, у вас є Continuous Integration, звучить трохи дивно, на мій погляд, але в цьому є сенс. Чому? Тому що, якщо ви мерщі часто, це означає, що зміни у вас маленькі. Якщо маленька зміна до того, що у вас зламалася збірка майстра, то ви зможете знайти приклад швидко, тому що зміна маленька. Ось у вас був маленький мерж, у ньому змінилося 20-30 рядків. І, відповідно, ви можете швидко зрозуміти, в чому була причина, тому що зміни крихітні, у вас дуже маленька область пошуку проблеми.

І навіть якщо у нас після релізу розвалюється prod, то якщо у нас є практика Continuous Integration, нам дуже простіше діяти, бо зміни крихітні. Так, це торкнеться планування. Це буде боляче. І, напевно, найскладніше в цій практиці - це звикнути розбивати завдання, тобто як зробити так, щоб узяти щось і зробити це за кілька годин і при цьому пройти реву, якщо воно у вас є. Рев'ю – це окремий біль.

Unit-тести - це просто помічник, який вам допомагає зрозуміти - чи ваша інтеграція пройшла успішно, чи точно нічого не зламалося. На мою думку, це теж не зовсім обов'язковий пункт, бо сенс практики не в цьому.

Це коротко про Continuous Integration. Це все, що є у цій практиці. Я готовий до питань.

Коротко тільки ще раз підсумую:

  • Continuous Integration – це не Jenkins, це не Gitlab.
  • Це не інструмент, це практика про те, що ми якнайчастіше мержемо наш код у майстер.
  • Робимо ми це для того, щоб уникнути величезного болю, який виникає з мержами в майбутньому, тобто ми відчуваємо маленький біль зараз, щоб не відчувати більшого в майбутньому. У цьому вся сенс.
  • Збоку проходить комунікація через код, але я цього дуже рідко бачу, але для цього вона теж замислювалася.

Питання

Що робити з недекомпозуванням завданнями?

Декомпозувати. В чому проблема? Можете навести приклад, що є завдання, і вона не декомпозується?

Є такі завдання, які неможливо декомпозувати від слова «зовсім», наприклад, ті, які вимагають дуже глибокої експертизи і які реально можуть вирішуватись протягом місяця до якогось зручного результату.

Якщо я правильно тебе зрозумів, тобто якесь велике і складне завдання, результат якого буде видно лише через місяць?

Так все вірно. Так, оцінити результат можна буде не раніше, ніж за місяць.

Добре. Загалом це не проблема. Чому? Тому що в даному випадку, коли ми говоримо про гілочки, ми не говоримо про гілочку з фічею. Фічі бувають великими та складними. Вони можуть зачіпати велику кількість компонентів. І, можливо, ми їх не можемо зробити в одній гілочці повністю. Це нормально. Нам потрібно лише розбити цю історію. Якщо фіча не готова до кінця, це не означає, що якісь шматки її коду не можна мержить. Ти додав, скажімо, міграцію і всередині фічі є якісь етапи. У тебе, скажімо, є етап – зробити міграцію, додати новий метод. І ти ці речі вже можеш мержити щодня.

Добре. Який тоді сенс?

Який сенс мерти маленькі штуки щодня?

Так.

Якщо вони в тебе щось зламали, ти це бачиш одразу. У тебе маленький шматочок, що щось зламав, тобі простіше це виправити. Сенс у тому, що смержити маленький шматочок зараз набагато простіше, ніж смержити щось велике за кілька тижнів. І третій сенс у тому, що в тебе інші інженери працюватимуть із актуальною версією коду. Вони бачитимуть, що тут якісь міграції додалися, а тут з'явився якийсь метод, який вони також, можливо, захочуть використати. У тебе всі бачитимуть, що у тебе в коді відбувається. Саме заради цих трьох речей практика робиться.

Дякую, питання закрите!

(Олег Сорока) Можна я додам? Ти все правильно сказав, хочу лише одну фразу додати.

Так.

При Continuous Integration код мерехтить у загальну гілку не тоді, коли фіча повністю готова, а тоді, коли перестав ламатися білд. І ви сміливо комітете в майстер скільки хочете щодня. Другий аспект – якщо ви не можете з якоїсь причини розбити місячне завдання на завдання хоча б три дні, я мовчу про три години, значить, у вас є величезна проблема. І той факт, що у вас немає Continuous Integration – це найменша з цих проблем. Це означає, що у вас проблеми з архітектурою та інженерні практики на нулі. Тому що навіть якщо це дослідження, то в будь-якому випадку його треба оформляти у вигляді гіпотез або циклу.

Ми говорили про чотири метрики, які відрізняють успішні компанії від відстаючих. До цих 4 метриків ще дожити треба. Якщо у вас середнє завдання робиться місяць, то я сконцентрувався б спочатку на цій метриці. Опустив її спочатку до 4-х днів. І після цього почав думати про Continuous.

Я правильно зрозумів тебе, що ти думаєш, що в цілому вкладатися в інженерні практики, якщо в тебе будь-яке завдання робиться місяць, сенсу ще немає?

Ти маєш Continuous Integration. І там є така тема, що ти за 10 хвилин або фіксуєш виправлення чи відкочуєш. Уяви, ти його викотив. Причому, у тебе навіть continuous deployment, ти його викотив на prod і тільки потім помітив, що щось пішло не так. І тобі його треба відкотити, а в тебе вже міграція бази даних відбулася. У тебе вже схема бази даних версії наступної, більше того, ще якийсь бекап пройшов, ще туди і дані записалися.

І яка в тебе є альтернатива? Якщо ти відкочуєш назад код, він вже не може працювати з цією базою даних оновленою.

База рухається лише вперед, так.

У людей, які мають погану інженерну практику, швидше за все, вони товсту книгу про … теж не читали. З бекапом що робити? Якщо ти відновлюєшся з бекапу, то значить, ти втрачаєш дані, які за цей момент напрацювалися. Наприклад, працювали три години з новою версією бази даних, туди користувачі зареєструвалися. Ти відмовляєшся на старий бекап, тому що з новою версією схема не працює, відповідно, цих користувачів ти втратив. А вони незадоволені, вони сваряться.

Для того щоб оволодіти всім спектром практик, що підтримують Continuous Integration і Continuous Delivery, мало навчитися писати просто …. По-перше, їх може стати дуже багато, це буде непрактично. Плюс там є купа інших практик типу Scientific. Є така практика, GitHub її популяризував одночасно. Це коли в тебе одночасно виконується і старий, і новий код. Це коли ти робиш недороблену фічу, але вона може повертати якесь значення: або як функцію або як Rest API. Ти і новий код виконуєш, і старий код виконуєш, і порівнюєш різницю між ними. І якщо різниця є, то цю подію логуєш. Таким чином ти знаєш, що в тебе нова фіча готова викочуватися поверх старої, якщо в тебе протягом певного часу не було розходження між цими двома.

Таких практик є сотні. Я запропонував би почати з transbase development. Вона не 100% на Continuous Integration, але практики одні й ті самі, одне без іншого погано живе.

Ти transbase development навів як приклад, де можна подивитися практики, чи ти пропонуєш людям почати використовувати transbase debelopment?

Подивитися, тому що використовувати вони не зможуть. Для того, щоб їх використовувати, потрібно багато чого почитати. І коли питання у людини: «Що робити з фічею, яка займає місяць, то це означає, що вона не читала про transbase develoopment». Я б і не радив поки що. Я порадив би сконцентруватися виключно на темі, як правильно архітектурно розбивати великі завдання на дрібніші. У цьому й суть декомпозиції.

Декомпозиція – це один із інструментів архітектора. Ми спочатку робимо аналіз, потім декомпозицію, потім синтез, потім інтеграцію. І в нас у такий спосіб усе складається. І до Continuous Integration треба ще зрости через декомпозицію. Запитання на першому етапі виникають, а ми вже про четвертий етап говоримо, тобто чим частіше робити інтеграцію, тим краще. Її ще рано робити, непогано б спочатку попиляти свій моноліт.

Потрібно скількись стрілочок та квадратиків намалювати на якійсь схемі. Ти не можеш сказати, що зараз я покажу архітектурну схему нової програми та показати один квадратик, усередині якого зелена кнопка на програму. У будь-якому випадку більше буде квадратиків та стрілочок. На будь-якій схемі, яку я бачив, їх було більше одного. І декомпозиція навіть на рівні графічної вистави вже виробляється. Тож квадратики можна робити незалежними. Якщо ні, то маю великі запитання до архітектора.

Є питання з чату: «Якщо рев'ю обов'язково і йде довго, десь день і більше?».

У вас є проблеми з практикою. Не повинно йти ревю день і більше. Це та сама історія до попереднього питання, тільки трохи пом'якше. Якщо реву йде день, значить, швидше за все, це рев'ю йде якась дуже велика зміна. Виходить, його треба робити менше. У transbase development, який Олег порекомендував, є така історія, яка називається continuous review. Її ідея в тому, що ми робимо настільки маленький pull request навмисно, тому що ми прагнемо мерзить постійно і потроху. І тому pull request змінює одну абстракцію чи 10 рядків. Завдяки цьому реву у нас займає кілька хвилин.

Якщо ревью займає день і більше, то щось не так. По-перше, можливо, у вас якісь проблеми з архітектурою. Або це великий шматок коду, на 1 рядків, наприклад. Або у вас настільки складна архітектура, що людина не може її зрозуміти. Це проблема трохи збоку, але її теж доведеться вирішувати. Можливо, взагалі не потрібно реву. Над цим теж треба подумати. Рев'ю - це та штука, яка вас гальмує. Вона дає свої плюси загалом, але потрібно зрозуміти, навіщо ви це робите. Це для вас спосіб швидко передати інфу, це для вас спосіб встановити всередині якісь стандарти чи що? Навіщо вам це? Тому що ревью треба робити або дуже швидким, або взагалі скасувати. Це як transbase deveploment – ​​історія є дуже красива, але тільки для зрілих guys.

З приводу 4 метрик, я б рекомендував все ж таки їх зняти, щоб зрозуміти, до чого це призводить. Подивитися у циферках, подивитися картинку, наскільки все погано.

(Дмитро) Я готовий розпочати дискусію з цього приводу з тобою. Циферки та метрики – це все класно, практики – це класно. Але треба зрозуміти – чи це потрібно бізнесу. Є бізнеси, яким така швидкість зміни не потрібна. Я знаю компанії, в яких не можна проводити зміни раз на 15 хвилин. І не тому, що вони такі погані. Це такий життєвий цикл. І щоб робити фічу branches, фічу toggle, потрібні глибокі знання.

Це складно. Якщо ви захочете почитати історію про фічу докладніше, то дуже рекомендую https://trunkbaseddevelopment.com/. І є чудова стаття Мартіна Фаулера про фічі toggle: про те, які бувають типи, життєві цикли і т. д. Фіча toggle - це складно.

І ти все-таки не відповів на запитання: Jenkins потрібен чи не потрібен?

Jenkins не потрібний ні в якому разі насправді. Якщо серйозно, то інструменти: Jenkins, Gitlab принесуть вам зручність. Ви бачитимете, що збірка зібралася чи не зібралася. Вони можуть допомогти, але практику вони вам не поставлять. Вони вам можуть лише дати кружечок – Ок, не Ок. І те, якщо ви ще тести пишіть, тому що якщо немає тестів, це майже безглуздо. Тому потрібен, тому що це зручніше, але в цілому можна і без нього жити, не багато втратите.

Т. е. якщо у вас є практики, то означає, що він вам не потрібний?

Все вірно. Рекомендую тест Jez Humble. Там маю двояке ставлення до останнього пункту. Але в цілому, якщо у вас є три речі, ви мержіте постійно, ви запускаєте тести на комміти в майстрі, швидко лагодите білд у майстрі, то, можливо, вам більше нічого і не треба.

Поки ми чекаємо на запитання від учасників, у мене є питання. Ми зараз говорили про продуктовий код. А чи ти використовував для інфраструктурного коду. Це такий самий код, у нього такі ж принципи і такий же життєвий цикл, чи там інші життєві цикли та принципи? Зазвичай, коли всі говорять про Continuous Integration і Development, всі забувають, що є ще інфраструктурний код. І останнім часом його дедалі більше. І чи слід туди приносити всі ці правила?

Навіть не те, щоб слідувати, це буде здорово, тому що це так само спростить життя. Як тільки ми працюємо з кодом, не зі скриптами bash, а у нас є нормальний код.

Стоп-стоп, скрипт на bash – це також код. Не треба чіпати моє старе кохання.

Добре, я не топтатиму твої спогади. У мене до bash особиста ворожість. Він ламається негарно і страшно весь час. І ламається часто непередбачувано, тож я його недолюблюю. Але добре, припустимо, у вас є код bash. Можливо, я справді не розуміюсь і там є нормальні фреймворки для тестування. Я просто не в темі. І ми отримуємо ті самі плюси.

Як тільки ми працюємо з інфраструктурою як з кодом, ми отримуємо ті самі проблеми як розробники. Кілька місяців тому я зіштовхнувся із ситуацією, що колега мені надіслав pull request на 1 000 рядків на bash. І ти зависаєш на реву на 4 години. Проблеми виникають ті самі. Це все ще код. І все ще спільна робота. Ми застряємо з pull request і застряємо з тим, що ми розрулюємо ті самі мерж-конфлікти того самого bash, наприклад.

Я зараз дуже активно всю цю річ дивлюся на максимально красивому програмуванні інфри. Я зараз втягнув інфраструктуру Pulumi. Це програмування у чистому вигляді. Там це ще більш симпатично, тому що у мене є всі можливості мови програмування, тобто я тими самими іфами на рівному місці зробив гарні toggle і все добре. Т. е. моя зміна є вже в майстрі. Його вже всі бачать. Інші інженери про нього знають. Воно вже на щось вплинуло. Але при цьому воно увімкнулося не для всіх інфраструктур. Воно увімкнулося для моїх тестових стендів, наприклад. Тому відповідаючи на твоє запитання ще раз, треба. Воно нам, як інженерам, які працюють з кодом, так само спрощує життя.

Якщо в кого ще питання?

У мене є питання. Я хочу продовжити дискусію із Олегом. В цілому я думаю, що ти маєш рацію, що якщо завдання у тебе робиться місяць, то у тебе проблема з архітектурою, у тебе проблема з аналізом, декомпозицією, плануванням і т.д. жити по Continuous Integration, то ти почнеш виправляти біль із плануванням, тому що ти нікуди більше від цього не дінешся.

(Олег) Так, все так. За трудомісткістю ця практика можна порівняти з будь-якою іншою серйозною практикою, що змінює культуру. Найважче у подоланні – це звички, особливо погані звички. І якщо для того, щоб впровадити цю практику, потрібна серйозна зміна звичок оточуючих: developers, керівництва, production-менеджера, то на вас чекають сюрпризи.

Які можуть бути сюрпризи? Припустимо, ви вирішили, що частіше робитимете інтеграцію. І на інтеграції у вас зав'язані якісь ще речі, скажімо, артефакти. А у вашій компанії, наприклад, є політика, що кожен артефакт має бути певним чином врахований у якійсь системі складування артефактів. І це займає якусь кількість часу. Людині потрібно поставити галочку, що він, як реліз-менеджер опитував цей артефакт на готовність для викладки в production. Якщо це займає 5-10-15 хвилин, але при цьому ви робите викладку раз на тиждень, то раз на тиждень витратити півгодини - це невеликий податок.

Якщо ви Continuous Integration робите 10 разів на день, то 10 разів потрібно помножити на 30 хвилин. І це перевищує кількість робочого дня цього реліз-менеджера. Він просто втомлюється це робити. Є постійні витрати на якісь практики. І все.

І вам потрібно або скасовувати це правило, щоб ви більше не займаєтеся такою фігнею, тобто ви не привласнюєте вручну ступінь на відповідність чогось чомусь. Ви повністю і покладаєтеся на якийсь автоматизований набір тестів готовності.

І якщо вам потрібно від когось пруф, щоб головний підписав, і ви не лізете у production без того, що Вася не сказав, що він дозволяє і т. д. – все це нісенітниця встає на шляху практик. Бо якщо є пов'язані у вигляді податку якісь активності, то все у 100 разів збільшується. Тому зсув буде найчастіше сприйнятий не всіма радісно. Тому що звички людей важко виправляти.

Коли людина робить звичну роботу, вона робить її, практично не замислюючись. У неї когнітивне навантаження дорівнює нулю. Він просто фігачить за готовим, у нього в голові вже є чек-лист, він тисячу разів це робив. І як тільки ти приходиш і кажеш йому: «Давай скасуємо цю практику і з понеділка запровадимо нову» для нього це стає потужним когнітивним навантаженням. Причому вона для всіх одразу настає.

Тому найпростіше, щоправда, це розкіш не всі можуть дозволити, але я роблю завжди саме так, це таке. Якщо стартує новий проект, то зазвичай відразу цей проект впихаються всі невипробувані практики. Поки що проект молодий, ми особливо нічим не ризикуємо. Prod ще немає, розвалити нема чого. Тому як тренування можна використовувати. Такий підхід працює. Але не всі компанії мають можливість розпочати такі проекти часто. Хоча це теж трохи дивно, тому що зараз суцільний digital transformation, всі повинні експерименти запускати, щоб наздогнати конкурентів.

Тут ти впираєшся в те, що в тебе має бути спочатку розуміння того, що потрібно робити. Світ не ідеальний, prod також не ідеальний.

Так, ці речі взаємопов'язані.

У бізнесу теж не завжди є розуміння, що їм треба йти ось туди.

Є ситуація, за якої взагалі жодні зміни неможливі. Це ситуація, коли на команду йде більший тиск. Команда досить підгоріла вже. Вона не має жодного запасного часу на жодні експерименти. Вони з ранку до вечора пиляють фічі. А керівництву фіч все мало й мало. Потрібно дедалі більше. У такій ситуації взагалі жодні зміни неможливі. Команді можуть тільки сказати, що завтра робитимемо так само, як і вчора, просто потрібно зробити фіч трохи більше. Жодні переходи на жодні практики в цьому сенсі неможливі. Це класична ситуація, коли колись сокиру заточувати, треба дерева рубати, тому рубають тупою сокирою. Тут простих порад немає.

(Дмитро) Я зачитаю уточнення з чату: «Але потрібне велике покриття тестами на різних рівнях. Скільки часу на тести приділяється? Якось дорого, багато часу забирає».

(Олег) Це класична помилка. Тестів має бути достатньо для того, щоб у вас було впевненість. Continuous Integration - це не така штука, де спочатку 100% тестів йде і тільки потім починаєте цю практику застосовувати. Continuous Integration знижує на вас когнітивне навантаження за рахунок того, що кожна зі змін, яку ви бачите очима, настільки очевидна, що ви розумієте – зламає воно щось чи ні, навіть і без тестів. Ви в голові можете швидко протестувати, тому що маленькі зміни. Навіть якщо у вас тільки ручні випробувачі, їм теж простіше. Ви викотили і сказали: "Подивися, нічого не зламалося?". Вони перевірили і сказали: Ні, нічого не зламалося. Тому що тестувальник знає, куди дивитися. У вас один коміт пов'язаний із одним фрагментом коду. І це експлоїться конкретною поведінкою.

Тут ти, звісно, ​​прикрасив.

(Дмитро) Тут я не погоджуся. Є практика – розробка через тестування, яка від цього врятує.

(Олег) Ось я до цього ще не дійшов. Перша ілюзія – це те, що потрібно писати саме 100% тестів або взагалі не потрібно займатися Continuous Integration. Це не правда. Це дві паралельні практики. І вони безпосередньо не залежать. Ваше покриття тестами має бути оптимальним. Оптимальним – це означає, що ви самі впевнені в тому, що та якість майстра, в якому залишився після комміту ваш майстер, дозволяє вам з упевненістю натиснути кнопку Deploy увечері в п'ятницю в п'яному вигляді. Як ви цього прагнете? Через реву, через покриття, через хороший моніторинг.

Хороший моніторинг – не відрізняється від тестів. Якщо ви тести запускаєте один раз на pre prod, то вони один раз перевіряють всі ваші сценарії користувача і все. А якщо ви їх у нескінченному циклі запускаєте, то це ваша система моніторингу, яка нескінченно все тестує – впало або не впало. У цьому випадку різниця лише в одноразовості чи багаторазовості. Дуже хороший набір тестів …, які нескінченно запускаються, це моніторинг. І правильний моніторинг і має бути таким.

І тому як саме ви досягнете цього стану, коли ви в п'ятницю ввечері задеплоєтеся і йдете додому, це інше питання. Можливо, ви просто сміливий відморозок.

Давай назад трохи повернемося до Continuous Integration. Ми трохи в іншу складну практику втекли.

І друга ілюзія, що MVP, кажуть, треба швидко робити, тож там тести взагалі не потрібні. Не зовсім так. Справа в тому, що коли ви в MVP пишіть user story, то розробляти її можна або на кулі, тобто почув, що є якась user story і одразу кодувати її побіг, або працювати по TDD. І з TDD, як свідчить практика, виходить не довше, т. е. тести – це побічний ефект. Практика TDD не в тому, щоб тестувати. Незважаючи на те, що називається Test Driven Development, там взагалі не йдеться про тести. Це також, швидше, архітектурний підхід. Це підхід як писати саме те, що потрібно, і не писати те, що не потрібно. Ця практика з фокусування уваги на наступну ітерацію вашого розвитку думки щодо створення архітектури додатка.

Тому цих ілюзій не так просто позбутися. MVP та тести не суперечать один одному. Навіть, швидше, навпаки, якщо ви MVP робите на практиці TDD, то ви це зробите краще і швидше, ніж якщо взагалі без практики, а на кулі.

Це дуже неочевидна та складна думка. Коли ти чуєш, що тепер я писатиму ще тести і при цьому я щось зроблю швидше, воно звучить абсолютно неадекватно.

(Дмитро) Тут багато хто, коли називають MVP, це народу ліньки писати щось нормальне. І це все-таки різні речі. Не треба MVP перетворювати на якусь погану штуку, яка не працює.

Так-так, ти маєш рацію.

А потім раптово MVP у prod.

Назавжди.

А TDD звучить дуже незвично, коли слухаєш, що ти пишеш тести і начебто робиш більше роботи. Це звучить дуже дивно, але насправді це так виходить швидше та симпатичніше. Коли ти пишеш тест, то вже в голові ти багато думаєш про те, який код і як буде викликатись, а також яку поведінку ми від нього очікуємо. Ти не просто кажеш, що я написав якусь функцію і вона щось робить. Ти спочатку подумав, що в неї ось такі умови, вона так буде викликатися. Ти це покриваєш тестами і з цього ти розумієш, як у тебе виглядатимуть інтерфейси всередині твого коду. Це дуже впливає на архітектуру. У тебе код автоматично стає модульнішим, тому що ти спочатку намагаєшся зрозуміти, як ти його тестуватимеш, а тільки потім його пишеш.

У мене з TDD вийшло так, що я в якийсь момент наймав ментора з Ruby, коли я ще був програмістом на Ruby. І він каже: «Давай ти робитимеш по TDD». Я й думаю: «Млинець, зараз щось ще писати додатково». І ми з ним домовилися, що я буду протягом двох тижнів весь робочий код на Python писати по TDD. За два тижні я зрозумів, що назад я вже не хочу. За два тижні, намагаючись скрізь це застосовувати, ти розумієш, наскільки тобі стало простіше навіть просто думати. Але це неочевидно, тому я всім рекомендую, що якщо у вас є відчуття, що TDD – це складно, довго і зайве, спробуйте дотримуватися цього всього два тижні. Мені двох вистачило для цього.

(Дмитро) Ми можемо цю думку розгорнути з погляду експлуатації інфраструктури. Перед тим, як ми щось нове запускаємо, ми робимо моніторинг, а потім запускаємо. У цьому випадку моніторинг стає нормальним тестуванням. І є технологія через моніторинг. Але майже всі кажуть, що це довго, мені ліньки, я зробив чернетку тимчасову. Якщо ми зробили нормально моніторинг, ми розуміємо стан системи CI. А у CI системі багато моніторингу. Ми розуміємо стан системи, ми розуміємо, що вона має всередині. І під час розробки ми якраз робимо систему, щоб вона дійшла до потрібного стану.

Ці практики відомі давно. Ми роки 4 тому це обговорювали. Але за 4 роки майже нічого не змінилося.

Але цій ноті офіційну дискусію пропоную закінчувати.

Відео (вставлений як медіаелемент, але чомусь не працює):

https://youtu.be/zZ3qXVN3Oic

Джерело: habr.com

Додати коментар або відгук