Comments
Использую git flow с минимальной модификацией (master=develop, production). Всегда merge --no-ff и тег, соответствующий фиче, ребейз в ветку — иногда и без фанатизма: считаю, что достоверность истории важна и имеет практическую ценность, а линейность мастера — чистая вкусовщина.
UFO landed and left these words here

В базе у нас тоже 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 шаге обнаруживаются проблемы — откатываемся и спокойно решаем проблемы. После чего собирается новый релиз или вообще релиз переносится на другой день.

Немного сумбурно написано. Смешали и методологию и сам продукт, и git, и best practices.
Пришлось пару раз перечитать.

По сути, для Git flow нужны всего две ветки:
1. develop, для разработки
2. master, для стабильной версии
Все остальное можно либо не использовать, если у вас в команде полтора человека, либо использовать, то что вам нужно.
У меня например нет релизных веток, т.к. деплоится каждая законченная фича.

В GitLab flow мне не нравится, что репозиторий с кодом, берет на себя дополнительную ответственность, а именно начинает управлять деплойментом (ветки production, pre-production etc). По моему мнению это ответственность CI и CD, и удобнее управлять релизами используюя соответствующие инструменты.

Простой пример.
Git flow:
У нас баг на проде. Берем master, фиксим, прогоняем по окружениям (сборка, автотесты, автодеплоймент и т.д.).
Учитывая, то, что мы берем один и тот же код, а еще лучше один и тот-же пакет/контейнер у нас пропадает куча рисков.
GitLab flow:
У нас баг на проде. В какой ветке его фиксить, production или pre-production? Ведь возможно в pre-production он уже пофикшен. Логично, что в production, но есть вероятность, что придется следить и помнить о мелких расхождениях в этих ветках.

Во-первых, разработчики должны использовать ветку develop, а не master, потому что последняя зарезервирована под релизный код.

Master для релизного кода — это правильное решение для открытых проектов и в случае когда в компании есть несколько комманд, каждая со своим репозиторием. В этом случае можно спокойно брать последнюю версию из мастера и знать, что там стабильная версия.

Следовательно, можно исключить ветки релизов и хотфиксов и всю лишнюю работу

Тут все зависит от процесса. У кого-то деплой на прод раз в час, а у кого-то раз в месяц. Ветки релизов удобны, когда выпускаете сразу набор фич. Соответственно у каждого релиза может быть свой CI и свое окружение для тестов и экспериментов.
Почему нужно отказываться от веток для хотфиксов — непонятно. Я любую фичу или баг делаю в отдельной ветке. Т.е. непонятно в чем сложность делать и мерджить ветки в git?

ветки для нескольких сред

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

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

Я вот например до того, как сделать CI pipeline обсуждаю это с заказчиком. Ведь даже настроить это требует времени и дополнительных ресурсов (например сервера или лицензии).
Рассказываю плюсы и минусы, возможные затыки с внесением мелких изменений.

Да и процесс выкладки на прод тоже обсуждается. Бывает, что нужен аппрув QA lead или непосредственно заказчика, или обязательное прохождение определенного набора тестов (возможно даже ручных) и неважно что мы там меняли.

Вот для примера, я работал в компании где был крутейший QA lead и он мог спокойно отложить деплой если считал, что качество недостаточное. Причем даже если заказчик говорил — деплойте, последнее слово оставалось за QA lead. С другой стороны, если даже после деплоя нужно было поменять цвет кнопочки, то можно было вместе с ним поправить шаблон на проде, конечно если это можно было так простоо сделать, например изменив css стиль.
Жду статьи «Bitbucket Flow», или может даже две: «Bitbucket Git Flow» и «Bitbucket Mercurial Flow».

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


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

Отлично, первая половина есть. Осталось про Mercurial, заодно решится проблема ребейсов- HG их не поддерживает без плагинов, как и сам Bitbucket, так что ребейс на каждый чих там не сделаешь.
А по настройке под себя это само собой. Я вот веду сейчас маленький форк крупного проекта, и после поддержки репозитория и предвидящегося выхода новой мажорной версии понял, что текущий Workflow никуда не годится, как и вообще все известные. Пришлось выдумывать свой путь, как опробую на переходе на следующую мажорную версию, напишу статью, если он будет удачным.

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

Прочитал статью, перечитал комменты, поглядел на опусы, типа 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...

Only those users with full accounts are able to leave comments. Log in, please.