Continuous Delivery в Яндексі. Як розігнати свій цикл розробки, використовуючи тільки Open Source рішення

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



Сьогодні ми покажемо, що Continuous Delivery — це просто і весело! А користь від нього можна отримати, вмонтувавши його навіть частково. Ми в тестуванні Яндекса вже кілька років використовуємо подібний підхід для наших бібліотек з відкритим вихідним кодом — Allure Framework або Yandex QATools. Процес простий, значно масштабується і може застосовуватися як для величезних команд з однієї людини, так і для маленьких командочок з десятків осіб. А найголовніше — весь інструментарій доступний в Open Source!

До речі, до 30 вересня можна подати заявку і вступити в нашу Школу автоматизації процесів розробки в Пітері. Навчання в ній безкоштовне і буде складатися не тільки з курсу лекцій — обов'язковим етапом стане командна робота над навчальним проектом.

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

Здається, що такий процес характерний для методу розробки «хлобысь, хлобысь і продакшен» (прибравши частину про юніт-тести), або для рекламного ролика компанії, що спеціалізується на інноваціях при розробці ПО. При цьому під ним обов'язково потрібна біжучий рядок, аналогічна підписи під каскадерськими трюками: «Небезпечно, не намагайтеся повторити це вдома!».

Як це було раніше

Історія одного розробника. Десь чув задачу про бэкапах: «Скільки вантажівок потрібно, щоб адміністратор почав робити резервні копії?». Чорний гумор, тому рішення чекаю в коментарях. Тут мова йде про процес розробки, але суть не змінюється. Розробник надсилає будь-яка зміна в основну гілку і, вважаючи, що настав час зібрати пакет для тестування і викладки, зупиняється на стабільному, на його думку, стані коду, оновлюючи гілку, з якої збираються пакети. Тепер виникає питання: «Що міститься в новому пакеті після чергової збірки?». Будь-яка відповідь на це питання може бути неправильним. Адже розробник впевнений, що змінює код лише він, тому дивитися на історію змін не потрібно. Бувало, буквально дивом, знаходили при тестуванні аномалії, які могли серйозно ускладнити життя користувачам наших сервісів. Аномаліями виявлялися неузгоджені зміни, що потрапили в гілку або від розробника з іншого проекту, який вирішив виправити баг, або зібрані «за компанію» і просто забуті. Складності очікували і тих, хто вирішив би влитися в процес розробки. В якій гілці ведеться розробка? В якій гілці стабільна версія? Як взагалі збирати пакет?

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

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

Що спільного у цих історій? Відмовки. Всі вважають, що спростити собі життя, ввівши зрозумілий процес і автоматизувавши рутину, надто складно. Крім того, всім доведеться ламати себе через коліно, щоб звикнути до нових реалій. Це не так. Ми вже зруйнували в своїх командах такий міф.

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

Інструментарій

Для повного веселощів потрібно: GitHub Flow як безпосередній процес, CI сервер. Трохи, правда? Наші бібліотеки живуть на GitHub, тому я буду користуватися його термінологією, даючи коментарі по ходу. Весь цей процес цілком можливий майже на будь-яких комбінаціях CI-серверів і популярних майданчиках для IT-проектів, на кшталт GitLab,Bitbucket. Ключове тільки одне: буде потрібно клей, званий сімейством розширень Pull Request Builders.

Сіль за 5 секунд

Форк, комміт, пуш, реквест, білд, рев'ю, мерж, реліз.

Сіль в три етапи

Всі ці смішні слова я далі вживати не буду. Хоч і дуже тягне! Той, хто їх знає і регулярно використовує, швидше за все, давно запровадив подібний процес. Ці короткі незрозумілі слівця так само легко вивчити, як і реалізувати такі основні етапи у рамках завдання на легке побудова процесу:
  1. розробник робить зміну;
  2. зміна дивляться інші;
  3. зміна потрапляє в основну гілку системи контролю версій.

Розробник робить зміна

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

На цьому етапі потрібно тільки GitHub або аналог. Перше, що потрібно зробити, — продублювати поточну майстер-гілку основного сховища в свій особистий репозиторій. Тут розробник може будувати процес кодування так, як йому подобається. Це його особистий репозиторій, і тут він повновладний господар. Кінцева мета проста — набір змін, що базується на майстер-гілці основного сховища, в будь-якій гілці особистого.
На цьому етапі появляестя і найбільша складність — привчити себе писати unit-тести на свої зміни. Найцікавіше, що складність не в тому, щоб написати ці тести, а саме привчити себе їх робити. Але якщо виробити таку звичку, вона окупить майже будь-трудовитрати на написання тестів. Почніть з малого: покривайте позитивні сценарії. Їх легко продумати, легко реалізувати у тестах. Звикнувши не боятися за поломку заявленої функціональності, легко додати негативні сценарії. Це позбавить від страху непоправно зламатися в несподіваних місцях. Зміни готові до демонстрації?

Зміни дивляться інші

З набору можливих печеньок і варіантів реалізації це самий технологічний етап. Етап не просто так називається «дивляться інші» — без слова «розробники». Автоматика!

Для початку розробнику потрібно запустити процес — запропонувати свої зміни до злиття в основну гілку проекту. Думаю, не потрібно говорити про те, що телепати зазвичай у від'їзді, тому повідомлення до кожного зміни повинні чітко відображати їх суть. Особливо сильно це відчувається, коли сам повертаєшся після перерви до роботи над проектом і виявляєш чужі зміни. Добре, якщо зрозуміло, що сталося за заголовками в історії GIT. Адже після відпустки не дуже-то хочеться, розглядаючи різницю, перетравлювати тонни змін, щоб внести маленьке виправлення. У проектах з відкритим вихідним кодом це більш ніж важливо — тут за вашою історією стежать вже сотні чоловік!



Тут у справу вступає CI-сервер. Ми використовуємо два: TeamCity & Jenkins. Який точно використовувати, ми так до кінця і не визначилися. Залежить в основному від уподобань налаштовувати нове завдання на складання. Для того щоб збірка почалася, як тільки в основний репозиторій приїхало пропозицію на злиття, буде потрібно той самий клей — одне з розширень сімейства «Pull Request Builders».

Наприклад, для Jenkins + GitHub це GitHub PRBP.
Для Jenkins + Bitbucket це Bitbucket PRBP.
Для Teamcity + Github це TeamCity.GitHub.

CI-сервер дбайливо збере запропоновану зміну, прожене тести і обов'язково повідомить про проблеми в самому реченні на злиття:



Прямо тут же варто налаштувати і статичний аналіз коду. Зараз можна автоматично знаходити величезну кількість помилок у коді! Наприклад, за допомогою SonarQube. Він зможе виміряти покриття тестами і попередити, якщо воно раптом впаде. Отримання зворотного зв'язку займає хвилини! Виправити помилки можна в тій самій гілці, з якої була пропозиція:



Не варто боятися зовсім переписати історію в цій гілці. GitHub, наприклад, швидко відновить пропозицію, а CI-сервер знову пересоберет його. У багатьох проектах з відкритим вихідним кодом таке правило окремо прописано.

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

Зміни потрапляють в основну гілку системи контролю версій

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

Ніж приємний і зручний весь цей процес? Він дуже гнучкий. Всі ці дії легко рознести на декілька каскадів. Наприклад, робити спочатку запит на злиття нестабільну гілку, в ній проводити всі важкі дії з тестування, а після них — відправляти запит на злиття в основну гілку, в рамках якого збирати пакет на відправку на бойові сервера. І приймати запит на злиття тільки після успішної викладки. Або навпаки — всі-всі тестування проводити в рамках одного запиту, працюючи і пересобирая пакети прямо на ходу, відправляючи в основну гілку вже готові до викладання зміни. Це залежить від конкретної ситуації і укорінених звичок команди.


Як тільки в основній гілці накопичилася достатня кількість змін, якими всі учасники задоволені в потрібній мірі, приходить час релізу. Зазвичай це ще одна задача на складання з ручним викликом. В GitHub, наприклад, для цього використовують команду для HuBot. Дуже зручно позначати в цей момент головне зміна тегом. Це дозволить в будь-який момент при бажанні отримати можливість зібрати потрібну версію, не згадуючи номер зміни.



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

Я теж так хочу!

Для того щоб організувати подібний процес навіть не потрібно мати власний CI-сервер. Для маленьких проектів дуже зручно використовувати www.cloudbees.com/jenkins, який дасть повноцінний Jenkins-сервер з обмеженням на кількість збірок. Почати збирати пропозиції на злиття на GitHub цілком реально використовуючи buildhive.cloudbees.com/ — у нього немає лімітів. Або travis-ci.org/, для якого треба в корінь проекту покласти невеликий конфігураційний файлик.

Якщо ж у вас під рукою свій сервер, налаштувати на ньому Jenkins або TeamCity — справа півгодини. Налаштування за замовчуванням в цих серверах перекривають 80% базових потреб, і потрібно просто додати потрібні розширення.

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

Ми навчимо!

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

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.