Pull to refresh

Comments 21

Использую git flow с минимальной модификацией (master=develop, production). Всегда merge --no-ff и тег, соответствующий фиче, ребейз в ветку — иногда и без фанатизма: считаю, что достоверность истории важна и имеет практическую ценность, а линейность мастера — чистая вкусовщина.
UFO just landed and posted this here
Используем 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 шаге обнаруживаются проблемы — откатываемся и спокойно решаем проблемы. После чего собирается новый релиз или вообще релиз переносится на другой день.

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

Существует, да, но часто оказывается сильно тормозит процесс, когда редкий дев-билд доходит до прода.
UFO just landed and posted this here
Основная проблема — видение заказчика о новой фиче изменилось до выкладки на прод. Грубо, «не, синенькую кнопочку мы на прод не пустим, переделайте на красненькую».
UFO just landed and posted this here
UFO just landed and posted this here

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


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

UFO just landed and posted this here

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

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

Sign up to leave a comment.