Как пасти (с)котов. Часть 2: Git
Продолжаю изливать потоки знаний о разработке. Теперь про репозитории и релизы.
Первая часть тут. Продолжение тут. Как нанимать тут.
Git
Для начала расскажу почему именно Git.
Дело в том что Линус Торвальдс совершил не одну единственную революцию в своей карьере. Про создание Линукса в курсе все айтиштики, но была еще одна, куда менее заметная — он создал Git.
И на сегодняшний день git победил всех своих конкурентов. Раньше были всякие cvs, svn, mercurial, bazaar — все они по большому счету отошли в прошлое, уступив место git.
CVS и Subversion (SVN) я последний раз использовал в 2007м, Mercurial — в 2012м.
Вообщем, шансы на то что вы будете иметь дело с чем-то отличающимся от Git в 2023м году — в районе нуля.
Его величество «репозиторий»
Если в кратце — это такое хранилище исходного кода, туда все ваши разработчики заливают изменения, доработки и правки:
git push
Некоторые товарищи через git ведут работу над документацией, статьями и даже книгами — вот до чего прогресс дошел.
Но тут у нас все же про разработку.
Из репозитория же эти изменения забираются и сопоставляются с локальной копией:
git pull
Из репозитория код выгружается в CI-систему, для автоматической сборки и развертывания на стендах.
в CI системе также формируется релизная сборка.
Проще говоря локально ручками никто готовый проект не собирает. Если вы конечно не е#нутые и не работаете в одиночку.
Думаю из описанного становится очевидно что репозиторий это и точка отказа и первая цель для взлома и утечек — вообщем наверное самое важное звено при совместной разработке.
Поэтому его надо защищать и внимательно настраивать доступ и права. И конечно не забывать про бекапы. Никогда не забывать про бекапы.
Ветки и релизы
Первое с чем вы столкнетесь при создании репозитория это ветки (branches). Общий смысл ветки — создать сквозной срез всего репозитория.
Коммиты (изменения) добавляются последовательно в конкретную ветку с названием.
набор исходного кода в определенном именованном срезе репозитория.
Существует много разных схем ведения веток и создания релизов, с разной степенью применимости. Ниже я расскажу про свою, которую применяю в своих проектах по заказной разработке много лет.
Отдельно про Git Flow
Все случаи применения этой модели для командной разработки, что я видел заканчивались очень большим п#здецом проблемами:
- сильное разъежание версий между продуктовой сборкой и текущей;
- проблемы со сведением изменений, частая утеря правок;
- куча «мертвого груза» в репозитории: персональных или feature-веток, которые были брошены.
В основном из-за отсутствия самоконтроля, git flow — в первую очередь для умных, затем для стабильных: когда есть более-менее стабильная кодовая база и нет кранчей и гонок за релизом.
Поэтому в реалиях стартапа или заказной разработки — «git flow» очень быстро станет проблемой:
Не будете же вы в самом деле проводить ревью каждого коммита через pull-request -> accept -> merge ?
Это имеет смысл когда вы уже давно сделали продукт, он стабилен и продается. А теперь вся ваша работа это делать мелкие правки и лежать на пляже стричь купоны.
Моя схема
Я делаю четкую и однозначную разбивку на текущую версию, которая находится в разработке и завершенные релизные версии:
В ветки с релизными версиями идут коммиты с исправлениями ошибок, найденных за время эксплуатации, которые затем переносятся в текущую версию (если там актуальны).
Текущая разработка происходит в ветке develop, релизные же ветки именуются по дате релиза: release_02.10.22
Релизная ветка создается из «замороженного» develop в день завершения спринта и подтверждения от тестировщиков что все работает.
Посмотрите на схему выше — красивая?
Они все красивые, пока на картинке.
В реальности чтобы вести номерные версии нужен changelog (список изменений) — это такой отдельный документ со списком изменений в каждой версии. Выглядит примерно вот так.
Без ченжлога, понять отличия между версиями — проблематично, специально вести ченжлог в реалиях стартапа или заказной разработки — затратно.
Даже с использованием п#здюлей мотивации и автоматических средств.
Второй важный момент это метки сборки:
информация о версии, дате сборки, коммите, ветке и так далее. Все это генерируется во время релизной сборки и зашивается в приложение.
Чтобы затем показать пользователю что-то такое:
Конечно в 1991м году все было сильно проще, но номер сборки был уже тогда (см. последние три цифры в номере версии).
Возвращаемся к нашим мирским проблемам:
в условиях стартапа или заказной разработки может не быть времени для всей этой суеты с метками, особенно если приложение не одно а представляет собой набор сервисов.
Вот тут и приходят на помощь даты в названии релизного бранча:
Сам собранный бинарник, архив или набор скриптов — смотря на чем вы разрабатываете, будут иметь дату создания совпадающую с датой релиза.
Потому что создание релизной ветки из develop и релизная сборка происходят обычно в один день.
Соответственно у вас всегда будет возможность найти концы — исходники той версии что работает в продакшне.
To be continued..
В следующей части расскажу про тестирование и качество ПО. Думаю у многих случится разрыв жоп устоявшихся взглядов на этот непростой процесс.