Как да постигнем непрекъсната интеграция правилно

Тайната за предаване с пълна дроселна клапа не е свързана с вашите инструменти

От Nathaniel Tetteh за Unsplash. Така постигате непрекъсната интеграция.

Аз съм в бизнеса за разработка на софтуер от много години насам. Животът в Берлин също ми помага да поддържам връзка с огромна стартираща общност.

Обичам да говоря с хора от различни компании, за да видя как изглеждат процесите им и каква е тяхната култура по отношение на екипи, практики на кодиране и стандарти за качество.

Когато става дума за дискусия за непрекъсната интеграция, има модел, който забелязвам по-често, отколкото не. Не е рядкост, че разработчиците говорят за това, сякаш става въпрос само за Дженкинс, или Травис или какъвто и да е инструмент, който използват.

Очевидно в много среди непрекъснатата интеграция просто означава да имате инструмент, който проверява най-новата ви фиксация и става червен или зелен като дърво Xmas в зависимост от резултата от тестовете.

Не съм съгласен

Има основни практики и процеси, които са пред всеки инструмент, който бихте могли да използвате и които са основата на непрекъснатата интеграция.

Без тях CI просто не е възможно.

В тази публикация изброявам някои от тях. Мисля, че те са добра отправна точка за постигане на истинска непрекъсната интеграция.

Ако сте в екип, който се бори за доставката или не можете да координирате усилията си за кодиране с тези на вашите колеги, тогава тази публикация е за вас.

Без функции клонове

Когато екипите се сблъскват със задачата да разработят нова функция, често срещана грешка, която правят е да отворят клона на функциите в своето хранилище и да започнат да хвърлят много комити вътре в него.

Идеята е да се изолират от ограниченията в процеса на разработване за целия проект, докато функцията бъде завършена и може да бъде обединена обратно в главния.

Представяне на работния процес на Feature Branch

Мисълта, която стои зад тази практика, е повече или по-малко „ако директно работим върху master и master е свързан с цикъла на освобождаване, ще пуснем функция с половин резерв или нещо, което все още не работи. Още по-лошото е, че можем да счупим нещо, защото не сме изпробвали напълно кода си “.

Въпреки че тази практика може да звучи консервативно и ориентирана към безопасността, е точно обратното.

По-често, не, вие се оказвате с нарушена версия веднага след като обедините обратно своя функция. Единствените ви възможности в този момент са: а) възстановяване на ангажимента или б) горещо поправяне на съобщението.

Ако нямате късмет, и двете могат да бъдат скъпи и податливи на грешки.

Ако процесът на пускането ви не е достатъчно автоматизиран, възстановяването на такъв голям ангажимент може да ви струва ръчно прехвърляне на структурата на вашата база данни, например. И какво ще направите, ако деструктивно промените данните си?

Горещото фиксиране също не е по-малко рисковано. За да сведете до минимум прекъсването на потребителското изпитване, трябва да освободите патч възможно най-скоро. И всички знаем, че напрежението във времето изобщо не се разбира с добре обмисленото развитие. Рискът е да добавите грешки отгоре на бъгове и да влошите ситуацията извън приемливата граница.

Защо клоновете с функции не работят

Причината, поради която клоновете на функциите не работят е проста: не получавате непрекъсната обратна връзка, докато се развивате.

Когато вие и вашият екип не предоставите на своя заинтересован участник възможност да валидира непрекъснато работата си, вие губите контакт с реалността.

Няма начин да утвърдите напредъка си в развитието, освен да оставяте на потребителя си непрекъснато да се регистрира.

Има голяма заблуда, за която попадат много разработчици в този случай. Вярва се, че ако тестват кода си достатъчно или чрез писане на тестове или ръчно щракване наоколо, те могат да бъдат сигурни, че това, което току-що са разработили, просто ще работи ™.

Това е грешка и трябва да се избягва на всяка цена.

Доколкото вие, като разработчик, можете да се опитате да мислите като вашите потребители, просто не сте. Моделите на използване ще бъдат пренебрегвани и не се прилагат. Поведенията няма да се предвиждат, отваряйки вратата за подъл бъг. Делата или дълбоките процеси няма да бъдат разкрити.

С други думи, вашият софтуер в най-добрия случай няма да приложи това, което е реалността. Или ще бъде обикновен счупен и няма да работи просто, в най-лошия случай И в двата случая ще изглежда неправилно в очите на потребителя.

Въпреки че моделът Feature Branch може да звучи консервативно и ориентиран към безопасността, е точно обратното.

Използвайте превключватели на функции

Първата, лесна стъпка за постигане на добро ниво на CI е използването на функция превключватели.

Превключване на функция е флаг за конфигурация в приложението ви, който може да включва и изключва определена функция.

Тази техника е безумно лесна за изпълнение. Във вашата кодова база изглежда повече или по-малко така.

Предимствата на използването на функция превключване са следните:

  • можете да изключите функция в производството, без да се налага да пускате отново. Това е полезно, когато се съобщава за критичен бъг и искате да попречите на потребителите да имат достъп до счупената функция;
  • можете да активирате функцията в канарска среда и да я пуснете в производството. Това позволява на потребителите на ранен етап да тестват функцията и екипът за разработка да събира полезна обратна връзка преди официалното издание;
  • можете да активирате функцията в затворена среда и да позволите например на Product Manager да провери състоянието на техниката, дори ако функцията все още не е завършена.

Има още едно предимство, което се отключва, когато започнете да използвате превключватели на функции.

Тъй като функцията ви може да бъде изключена в производството, докато не бъде завършена и стабилна, сега можете да започнете да обединявате поръчки директно във вашия основен клон.

Малки ангажименти, директно за овладяване

Има няколко валидни причини да обедините вашите ангажименти директно в master след този модел.

Моделът за сливане на „скачащи рибки“.

Кой направи това?

Първата причина е, че получавате по-чиста история на вашия код. Вие точно знаете кой какво направи. Това помага много, когато други разработчици се нуждаят от пояснения за конкретна част от кода.

С клоновете на функциите, всички команди се разбиват в един, преди да се обединят, така че информацията е загубена и само един разработчик ще поеме цялата (git) вина.

Лесни сливания, по-малко конфликти, по-безопасни реверти

Колкото по-голям е клонът от функции, толкова по-голяма е вероятността да имате конфликти за сливане.

Конфликтите за сливане могат да бъдат много болезнени, тъй като решаването им е чисто ръчен и изключително податлив на грешки процес.

На всичкото отгоре, когато сте изправени пред конфликт за сливане, вероятно трябва да преработите малко логиката на приложението си. Обикновено това се прави в движение, докато се освобождава. Оставям ви да си представите какъв би могъл да бъде качественият резултат от кодирането, докато мозъкът ви е в средата на друга задача.

Виждах много пъти разработчици да казват „Не знам какво се е случило. Разреших някои конфликти и се обърках по време на ребаза “. Може би git има някои грешки, но силно се съмнявам, че може да се обърка по време на ребаза.

По-малките ангажименти ви позволяват да сте на сигурна страна и да избягвате сложни отстъпки. Конфликтите са минимални и тривиални, защото повърхностното разширение на промяната също е твърде.

По-малките ангажименти също са по-лесни за възстановяване поради психологически фактор. Когато работите с големи функционални клонове, потъналите в пристрастия разходи се борят срещу вашата рационална преценка. Не сте склонни или дори се страхувате да върнете такова количество код.

„По-добре да опитате да го поправите. Поправката ще бъде минимална в сравнение с количеството код. Няма нужда да връщате всичко след цялата работа, която свършихме “- Звучат ли ви тези думи?

В крайна сметка малките ангажименти трябва да са достатъчно малки, за да може един член на екипа да слее нещо в master поне веднъж на ден.

Оптимизирайте за паралелно развитие

Именно тук софтуерният дизайн наистина среща непрекъсната интеграция.

Дори и да работят върху изолирани клонове на функции, членовете на екипа могат да се блокират един друг, ако не разделят достатъчно внимателно разработването на функция.

Иронично е, че ние проектираме нашия софтуер да бъде отделен, а модулите ни да са независими един от друг, докато инженерството на нашия процес на развитие оставя много да се желае.

Ето как изглежда типичното разпределение във времето на задачи за разработка за една функция.

Гайбруш винаги трябва да чака Елейн да свърши задачата си, в противен случай той не може да започне да работи над него. Стан е заседнал, докато LeChuck и Elaine доставят своите части и LeChuck в крайна сметка остава само с една задача.

За съжаление няма сребърен куршум, който да се справи с развитието на функция, така че всеки член на екипа да може да работи паралелно върху някаква задача.

Това, което определено помага тук, е да разгледаме функцията от гледна точка на софтуерния дизайн и да се опитаме да разберем къде са линиите на рязане. По принцип говоря за търсене на интерфейси, преди да започнете да разработвате общи части.

Полезно евристично например е, че ако двама разработчици трябва да работят в две съседни области, да кажем компонент на фронта и неговия резервен колега, те могат да се договорят предварително за интерфейса, който ще използват за поставяне на двете части в комуникация.

Вместо това друг екип би могъл да приложи „кой пристига пръв решава правилото за интерфейс“, при което двама или повече разработчици започват да работят независимо и първият, който стигне до определението на точка за контакт, ще го уточни.

Все още нещата могат да се променят, когато другите пристигнат там и видят, че дефиницията не отговаря напълно на техния случай на употреба. Но поне никой не е блокиран междувременно и необходимостта от подобряване на интерфейса най-вероятно ще разпали здравословен разговор между членовете на екипа, както и интересни прозрения в дизайна на функцията.

заключение

Непрекъснатата интеграция не е свързана с вашия инструмент.

Непрекъснатата интеграция е свързана с начина, по който проектирате процеса на разработка.

Необходимо е време и усилия, за да работи безпроблемно.

Това включва разбиране и прилагане на различни стратегии за синхронизация не само на членовете на екипа, но на всеки човек, участващ в разработването на функция.

Проверката на вашия ангажимент за проверка на тръбопровода за автоматична тест е просто череша на върха.