На моей предыдущей работе мы использовали подход, аналогичный тому, который упоминал @Alexis, с одним основным отличием. Имейте в виду, что мы работали над новой версией какого-то довольно крупного унаследованного программного обеспечения (наша кодовая база состояла из нескольких миллионов строк кода, между Java, flex и COBOL) и провели для нас бета-тестирование с партнером-заказчиком. Релизы проводились раз в две недели, в том числе для потребителя (хотя обычно они на одну версию отстают от последних, так как сначала они проходят QA), и на этой неделе мы должны были провести «тестовый» базовый контроль качества с помощью клиент нашего кода, который был другим разработчиком в компании, а затем выпустил реальный QA.
По сути, мастер был нашей веткой разработки. Если элемент разработки занимал более одного или двух дней, он был завершен в ветви функций, а затем объединен в dev, когда будет готов. Была еще одна «будущая» ветка разработчика, которая была зарезервирована для довольно серьезной работы над новыми функциями (всего, что значительно изменило программу) или серьезного рефакторинга. В какой-то момент это станет основным «dev», когда мы решим, что у нас есть время, чтобы должным образом протестировать и устранить ошибки, или что пришло время представить новые функции и справиться с неизбежной болью:)
Когда пришло время для выпуска, была создана новая ветвь с именем 'release_x', тогда все исправления, пришедшие из QA, были там реализованы и объединены 'up'. Под этим я подразумеваю, что у нас может быть две или три версии в игре одновременно, поэтому у клиента, очевидно, будет самая старая версия, к которой мы могли бы исправить, если бы они нашли showtopper. Это будет сделано в ветви исправлений, выходящей из соответствующего выпуска, которая в какой-то момент будет объединена с этим выпуском и удалена (чтобы вы могли легко увидеть выдающиеся исправления в списке ветвей), а другая сборка будет выполнена и отправлена клиенту. Существовали ветки «исправлений», так что мы могли выбирать, что входило в конкретную сборку, которая функционировала как для выпуска клиента, так и для выпуска разработчика, чтобы избежать потенциально рискованных исправлений для мелких проблем, нарушающих выпуск исправления для showtopper .
Затем это будет объединено с выпуском, который имели ребята из QA, затем оно будет объединено с выпуском, который использовали другие разработчики (всегда последний выпуск из-за их зависимости от наших плагинов и инфраструктуры j2ee для выполнения своей работы). ), затем возвращайтесь в dev, просто чтобы держать все на уровне.
У всех выпусков, находящихся в настоящее время в игре, был свой собственный автоматический цикл сборки в Jenkins, а также ветка dev, с некоторыми автоматизированными функциональными тестами, работающими на более важных (в основном, dev и QA). Каждая сборка добавляла в отчет тег о коммите, который использовался в качестве HEAD, и номер сборки был доступен из программы, чтобы мы могли видеть точно , какую версию использовал репортер ошибок.
Итак, по сути, две ветки разработчика, одна из которых для основной работы, будет выпущена позже как новая основная версия. Ветви релизов для каждого релиза, с ветвями исправлений. Найти последний выпуск было легко, ищите ветку релиза с наибольшим номером.
Единственным недостатком было то, что если вы сделали много исправлений при выпуске нескольких версий назад, тогда графики слияния были ... интересны для подражания:)