Как стать автором
Обновить

Комментарии 21

Использую git flow с минимальной модификацией (master=develop, production). Всегда merge --no-ff и тег, соответствующий фиче, ребейз в ветку — иногда и без фанатизма: считаю, что достоверность истории важна и имеет практическую ценность, а линейность мастера — чистая вкусовщина.
НЛО прилетело и опубликовало эту надпись здесь
Используем feature baranches и создание релизных веток от мастера при выкате

В базе у нас тоже git-flow, но слегка модифицированный. Добавили еще release ветку по принципу hotfix, но только от develop — для стабилизации. И еще support ветки, которые начинаются с какого-то тега в master, куда мы через cherry-pick переносим какие-то единичные критичные фиксы в минорный релиз прошлой мажорной версии.
Вокруг этого постепенно был написан скрипт который автоматизирует создание и завершение hotfix/release веток, проставляет версии, тэги, сливает, заливает, защищает, и т.п. Делает много рутинной работы. Наш начальник уже сам как-то пару релизов делал: gf -y -i 123 -a finish -b hotfix — закончить hotfix под тикетом 123, собрать локально и залить в репозиторий не переспрашивая.
Дополнительно к этому в gitlab используем защищенные ветки: develop, master, support, release, hotfix — только основная команда может в них мержить, аутсорс поставляет merge request'ы, которые мы проверяем и заливаем, если все хорошо на ревью. Плюс у нас еще есть custom hooks которые смотрят, чтобы ветки аккуратно назывались, например, feature/prjid-123-abc-def-xyz и в каждом коммите была ссылка на тикет типа PRJID-123.


Несмотря на все это есть еще простор для автоматизаций.


Как только доберемся до автоматического выкатывания пререлизной версии на тестовое окружение, то появится еще долгоживущие ветки типа pre-release.

Поделитесь рецептом скрипта?

Особенно интересует:
проставляет версии, тэги, сливает, заливает, защищает,
и
custom hooks которые смотрят, чтобы ветки аккуратно назывались, например, feature/prjid-123-abc-def-xyz и в каждом коммите была ссылка на тикет типа PRJID-123.

Выложить скрипт просто так не могу: собственность компании. Я поговорю с шефом по поводу открытия кода на гитхабе, но там нет ничего особенного и сверхъестественного, так собрание мини-хаков и гит-трюков.


У нас jira + java + maven + gitlab. Приведу пока описание без кода, что было сделано.


  1. Скрипт в целом параметризован с помощью getopts. Он вызывает процедуры в порядке, необходимом для получения состояния в соответствии с правилами git-flow.
  2. Версии. Тут мы пользуемся функциональностью maven versions:set/commit и help:evaluate для project.version. Потом можно просто использовать git tag -m "$ticket" -m 'Release 1.2' $version. Аналогично для веток.
  3. Слияние работает только если нет конфликтов. Чтобы избежать очевидных конфликтов как то начало релиза 1.2.0-SNAPSHOT и переход к 2.0.0-SNAPSHOT в разработке. Очевидно, что при слиянии веток у нас будут конфликты в pom.xml. Можно автоматически слить ветки используя стратегию ours. Тогда конфликты проигнорируются при последующих слияниях.
  4. Jira. У нее есть Rest API которое можно дернуть, чтобы залогиниться и получить заголовок по номеру задачи. Этой функциональностью мы пользуемся, чтобы при автоматических операциях проставить например, PRJ-1234 Hotfix 1.2.3
  5. Gitlab. У него также есть Rest API. Им мы пользуемся для того, чтобы защитить ветку в начале разработки. Например release/1.2. Скрипт вызывает функцию типа gitlab_api release/1.2 protect.
  6. custom hooks. Тут написан простой рецепт на ruby — я вообще начинал с примеров. Там есть конфигурация, какой идентификатор проекта и что проверять. Скрипт просто собирает регулярное выражение с возможными названиями веток и проверяет подходит ли присланная ветка под шаблон. Наряду с этим скрипт смотрит, чтобы в каждом присланном коммите был тикет типа PRJ-\d+, пустая вторая строка и первая строчка не слишком длинная. Единственный трюк был — получить список именно новых коммитов.
  7. idempotent. Где возможно старался сделать скрипт идемпотентным, чтобы можно было запускать подряд несколько раз, если слияние не удалось из-за конфликтов и пришлось их вручную разруливать (rerere тут не получилось заставить работать). Например, sed для того, чтобы обновить <tag>release-1.2.3</tag> на <tag>release-1.2.4</tag>.

Если компания даст добро, то переработаю скрипты и выложу на гитхаб. У нас заняла чуть больше года разработка этого скрипта. Писалось все в фоне и по мере необходимости.


Загвоздка тут, все это написано под конкретно наши нужды. Выделить общую часть будет сложно. Есть уже git-flow для bash, который уже многое делает, но нам нужны еще дополнительные фунуции и шаги

Бывают случаи, когда критический баг в релизе обнаруживается уже на проде. Например, новая версия не держит высоких нагрузок. Или на прод по недосмотру попало то, что не должно было. Или обнаружилась уязвимость. В этом случае релиз с прода откатывается на предыдущую версию. А тем временем от мастера уже стартовала куча новых веток, которые тянут с собой изменения, попавшие в новый релиз. Это может быть не прод, а пре-прод (не просто же так пре-прод нужен, да?) и из-за одной сломанной фичи приходится задерживать весь релиз. Иногда задержка может длиться несколько дней, ибо выпилить фичу уже сложно, а починить не понятно как. Поэтому есть хорошее правило: заливать в мастер только тот код, который проверен на проде и признан стабильным. И только после этого от него можно начинать ветки.

Что мешает откатиться на предыдущую версию-то? Хоть по тегу, хоть тупо по sha?

Откатиться — ничего не мешает. А вот reverse-merge всех веток — проблема.

А зачем? Есть production-ветка (как бы она ни называлась), на каждый релиз ставится тег, если обнаружились проблемы — просто выкладываем предыдущую версию.

Вариант, когда критическая проблема обнаружилась не через 0-1-2 дня — это аварийная ситуация. Тут простого решения нет. Я бы бросил все силы на hotfix.

Затем, чтобы спокойно решить проблему, не останавливая деплой других фич, а не чинить не готовую к релизу фичу впопыхах. У нас последовательность такая:


  1. Решили выложить релиз.
  2. Собрали готовые к релизу фичи в отдельной ветке.
  3. Протестировали, что всё работает.
  4. Если фичи конфликтуют — чиним прямо в релизной ветке или собираем новый релиз без некоторых из фич.
  5. Тестируем релиз на реальных данных.
  6. Выкладываем на прод и проверяем, что всё ок.
  7. Вливаем в мастер.

Если на 6 шаге обнаруживаются проблемы — откатываемся и спокойно решаем проблемы. После чего собирается новый релиз или вообще релиз переносится на другой день.

НЛО прилетело и опубликовало эту надпись здесь
Сомнительный/спорный совет. Существует практика, что после сборки приложения, один и тот-же пакет (сейчас можно делать контейнер) проходит по всем окружениям, от dev до prod.

Существует, да, но часто оказывается сильно тормозит процесс, когда редкий дев-билд доходит до прода.
НЛО прилетело и опубликовало эту надпись здесь
Основная проблема — видение заказчика о новой фиче изменилось до выкладки на прод. Грубо, «не, синенькую кнопочку мы на прод не пустим, переделайте на красненькую».
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Atlassian называет свою методологию Simple Git Workflow, все посты в их блоге про эту методологию объединены тегом Git together. Идея примерно та же, но есть некоторые отличия. Например, они агитируют за rebase & merge --ff-only веток, что приводит к абсолютно линейной истории и на мой взгляд не очень-то полезно. И их методология не настолько проработана по части CI и рабочих окружений.


Но идеи-то везде общие, вы можете использовать Bitbucket и практиковать GitLab Flow с какими-то модификациями. Судя по комментариям выше, многие подстраивают систему под себя.

НЛО прилетело и опубликовало эту надпись здесь

Если не трудно, оповестите как-нибудь о статье, мне будет очень интересно почитать.

Прочитал статью, перечитал комменты, поглядел на опусы, типа If you cherry pick, your branch model is wrong или Stop cherry-picking, start merging и вижу, что как только появляется ветка support (а если не одна?) то без cherry-pick уже не обойтись: когда изменения /обычно фиксы/ появились уже давно в dev или даже master, и вдруг потребовались в support-release-1.0. При этом сам cherry-pick не предоставляет возможности проследить историю изменения. Странно, что в том же Subversion, худо-бедно это сделано через обычный merge и svn:mergeinfo (пожалуй, единственное, что мне нравится в Subversion).


Т.е. для приложений, для сервисов подобные схемы вполне себе, но для библиотек нужно, даже если исходить из семантического версионирования: выпустили релиз 1.0.0, для него логично иметь tag v1.0.0 и бранч поддержки release-1.0, куда будут попадать только багофиксы некоторое время, при этом остальная команда будет работать над 1.1 и, внезапно, пофиксит проблему, которая актуальна и для 1.0...

Зарегистрируйтесь на Хабре, чтобы оставить комментарий