topic branches VS CI

4 views
Skip to first unread message

Petyo Ivanov

unread,
Dec 11, 2009, 3:37:10 AM12/11/09
to Software craftsmanship Bulgaria
Мара, да споделя един въпрос, който ме притеснява дИбело.

Първо малко разяснения относно как ползваме сорс контрола.

* Рабутим с гит (който даже ще почнем да хостваме сами и да предлагаме
хостинг);
* Имаме две deployment инстанции, staging и production.
* Имаме два основни бранча, development и master.
* Обичайно пушваме в development, и от него деплойваме на staging.
* Като се наканим, мръджваме development в master, и деплойваме на
прод.
* Бъгове обичайно фиксваме в development; cherry-pick към master.

От време на време правим т. нар. topic бранчове. Които са добре да не
се настъпваме много много в dev, или пък за по-големи фийчъри. Точно
тия ми ти топик бранчове са зора. Защото се бият с другата концепция:

За да не умрем от скука (и в море от интеграционни бъгове, става
въпрос за същия проект, за който Христо разказа няколко поста по-
надолу), в началото на нашия проект направих следния setup:

Инсталирах едно integrity (за сериозните хора - това е CI за ruby +
git). направих една рейк задача която пуска всички спекове (rspec),
ако минат, пуска всички фийчъри (cucumber), и ако мине - деплойва.
Това го насочих към development бранча, и staging инстанцията.

Тънкия момент е, че тестовете говорят много с отдалечен service.
Когато работя локално, си вдигам един локален фалшименто сервиз, и
всичко минава за по-малко от минута (400+ спека, и къде 40 сценария).
ци-то горе ги пуска срещу истинския сервиз, и времето е горе долу 5-6
минути. От тук нататък на теория всичко е песен - само трябва да
внимавам да не троша тестовете, и git push ще ми деплойне по някое
време.

Скоро направих и същото за master + production, за да се пазя от
собственото си бързане.

Обаче събрано заедно topic бранчовете + ци-то не са много съвместими.
Ако отцепя и работя 1 седмица в бранч, губя цито, и удобния
деплоймънт.

Според Христо проблемата е локализирана отдавна, и има материали
написани по въпроса. Убягва ли ми нещо? Какъв е вашия setup?

Krasimir Angelov

unread,
Dec 11, 2009, 3:49:07 AM12/11/09
to software-crafst...@googlegroups.com
On Fri, 2009-12-11 at 00:37 -0800, Petyo Ivanov wrote:
> Бъгове обичайно фиксваме в development; cherry-pick към master.

И аз като вас, само дето ако съм много напред в development, фиксвам в
master и после cherry-pick в development, като преди да деплойна фикса
чакам CI да каже си мнението по новите промени в development.

В Hudson мисля че се прави билд за всеки push в remote branch. Пък и е
написан на сериозен език.

Поздрави,
К.


Hristo Deshev

unread,
Dec 11, 2009, 5:07:02 AM12/11/09
to software-crafst...@googlegroups.com
Аз само искам да кажа, че самата идея да работим в някакви бранчове противоречи на идеята за постоянно интегриране. Той бранча това му е идеята - да си "дезинтегриран". Препоръчвам следната статия по темата от Мартин Фаулър: <http://martinfowler.com/bliki/FeatureBranch.html>

Аз предпочитам да имам по-малко бранчове и да инвестирам в архитектура, която позволява да пускам/спирам фийчъри лесно. Така държим всичко на едно място и гледаме винаги да сме production-ready. Спокойно може да си работиш по някой нов фийчър, като го отделяш от останалите. Комитваш си и код и тестове, като евентуално не позволяваш на потребителя да го ползва още. Когато си готов, превключваш някоя опция и той се появява при потребителя. Да цитирам статията:

Feature Branching is a poor man's modular architecture, instead of building systems with the ability to easy swap in and out features at runtime/deploytime they couple themselves to the source control providing this mechanism through manual merging.

--Dan Bodart

Мислили ли сте какво значи всеки ваш комит да запазва системата в работещ вид и то на 100% готова за "пред чужденците"? Опитайте да го правите. Много променя отношението към работата.

Аз опитвам да работя така и реално development бранча, за който говори Петьо ми е най-важен. master бранча просто го мърджвам (Git го fast-forward-ва, защото в него не комитвам) и деплойвам. Реално ползвам master бранча само като таг, отбелязка, кога последно съм деплойнал.

Христо

Krasimir Angelov

unread,
Dec 11, 2009, 5:16:14 AM12/11/09
to software-crafst...@googlegroups.com
ОК, а тия проверки дали да показваш или не един фийчър оставяш ли ги в
кода след като всичко е готово и вече си върви на prоduction?
И ако да, не се ли пълни кода с много такива? Понеже има функционалности
които веднъж пуснати на никой не му хрумва да ги спира след това.

Или според зависи? :)

К.

Hristo Deshev

unread,
Dec 11, 2009, 5:45:42 AM12/11/09
to software-crafst...@googlegroups.com
2009/12/11 Krasimir Angelov <kra...@codingspree.net>

ОК, а тия проверки дали да показваш или не един фийчър оставяш ли ги в
кода след като всичко е готово и вече си върви на prоduction?


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

 
И ако да, не се ли пълни кода с много такива? Понеже има функционалности
които веднъж пуснати на никой не му хрумва да ги спира след това.

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

Ето ти пример. В момента работя по фийчър, който трябва при изпращане на мейл да го запомня в базата. Трябва да пазя последните 30 мейла, за да може евентуално да ги преглеждаме и по този начин да идентифицираме проблеми при изпращането. Вече имам клас, който дърпа send job от базата, прави SMTP съобщение, плъзва го към сървъра и после трие SendJob обекта. Понеже вече ми се е налагало да правя подобни неща (записвам статистики, ъпдейтвам пърформънс каунтъри, декрементирам оставащите кредити за изпращане на клиента), класът е еволюирал до следната архитектура:

Обектът знае, че има няколко send listener обекта и, когато изпрати мейл, се обажда на всеки един от тях. От тук нататък, аз просто трябва да създам нов listener обект и да го "регистрирам" така че да се подава на конструктора на класа, който праща пощата. Това мога да го направя на ръка, мога и да използвам .NET "събития". Аз използвам един dependency injection фреймуърк за .NET [1], който ми позволява просто да го конфигурирам с всички всички имплементации на даден интерфейс на едно място и да му кажа да ги събере в колекция и да я даде като конструира обекта за изпращане на поща. Ако не ползвах DI фреймуърк, щеше да трябва да си напиша и тествам отделно някой Builder обект (който помни Builder патърна от книжката, има моите поздравления, за това, че използва нещо освен гнусния Singleton :-) ).

Та, да си повторя мисълта след дългия пример: отделяйки време да направим класовете си да се грижат само за едно нещо (single responsibility principle), естествено изниква нуждата да изградим инфраструктура за конфигурация и сглобяване на по-сложни обекти от по-простите. Тази инфраструктура се изплаща при разни такива "безплатни" пускания и спирания на фийчъри.

Христо

[1] За любознателните .NET занаятчии, става дума за Ninject: <http://ninject.org/>

Nikolay Bachiyski

unread,
Dec 11, 2009, 7:25:34 AM12/11/09
to software-crafst...@googlegroups.com
2009/12/11 Petyo Ivanov <unde...@gmail.com>:

Клонове: само един клон. Друг клон само за огромни неща, като например
редизайн на административния панел. Ако нещото не е толкова огромно,
значи ще намериш начин да го вкарваш инкрементално в кода. Понякога
нови неща влизат само за администраторите на сайта (if
$feature_enabled...). Интеграционните и scaling проблемите лъсват на
секундата, никой не се отплесва по клонове, няма сливания.

Deploy: веднага, няма нужда да са минали тестовете. Едно, че нямаме и
безкрайно много тестове, но те са си съвсем отделно. Иначе се нарушава
ритъма. Ако все пак се е счупило нещо, ще се върнеш и ще си го
оправиш. Другото хубаво на deploy-а веднага е, че знаеш точно кога ще
стане. Така си правиш сметката и оставаш на линия. Ако не знам кога
точно ще се deploy-не може да ме няма, когато моят код счупи всичко.

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

Е, стават грешки, но обикновено проблемите, които създава един commit
зависят квадратично от обема му. Съответно при нас обикновено
проблемите са малки и се попрявят лесно. При един deploy на хиляда
реда код е абсурд да видиш веднага какво се е прецакало, правиш revert
и почваш да четеш, debug-ваш, мислиш и ти отиват много повече време и
нерви.

Накратко: почти никаква абстракция, проста процедура, толеранс на
някакви грешки за сметка на „бюрокрация“.

Н.

Hristo Deshev

unread,
Dec 11, 2009, 9:13:28 AM12/11/09
to software-crafst...@googlegroups.com
2009/12/11 Nikolay Bachiyski <n...@nikolay.bg>

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

Амин! Като видя комит с хиляда модифицирани файла и получавам позиви за тоалетната :-)

Христо

Николай Бачийски

unread,
Dec 14, 2009, 9:39:30 AM12/14/09
to Software craftsmanship Bulgaria
On Dec 11, 10:37 am, Petyo Ivanov <under...@gmail.com> wrote:
> ...

> Според Христо проблемата е локализирана отдавна, и има материали
> написани по въпроса. Убягва ли ми нещо? Какъв е вашия setup?

Ето още малко по темата от flickr:
http://code.flickr.com/blog/2009/12/02/flipping-out/

И те са с един клон само :-)

Н.

Stefan Kanev

unread,
Dec 14, 2009, 10:48:22 AM12/14/09
to software-crafts...@googlegroups.com
Никак не харесвам това решение, обаче. Има *някаква* логика, но ми се струва, че натоварва кода излишно. Не съм го проблам от друга страна.

2009/12/14 Николай Бачийски <n...@nikolay.bg>
Reply all
Reply to author
Forward
0 new messages