Как работают над Chromium

https://medium.com/@aboodman/in-march-2011-i-drafted-an-article-explaining-how-the-team-responsible-for-google-chrome-ships-c479ba623a1b
  • Перевод
image
Предисловие от автора оригинала:
В марте 2011 я написал черновик статьи про то, как команда, отвечающая за Google Chrome, разрабатывает и выпускает свой продукт — после чего я благополучно о нем забыл. Лишь несколько дней назад я случайно наткнулся на него. Пусть местами он уже устарел (Chrome форкнул WebKit в Blink в 2013 году, да и я сам больше не работаю в Google), я склонен считать, что изложенные в нем идеи все еще в силе.
Сегодня я собираюсь рассказать вам о том, как работает Chromium. Нет, речь пойдет не совсем о браузере Chrome, а скорее о Chromium — группе людей, занимающихся созданием браузера.

Над проектом Chromium работают сотни инженеров. Вместе мы коммитим в кодовую базу примерно 800 изменений каждую неделю. Мы также зависим от многих других больших и активно развивающихся проектов вроде V8, Skia и WebKit.

Мы отправляем новый стабильный релиз сотням миллионов пользователей каждые шесть недель, четко по расписанию. И мы поддерживаем несколько других каналов раннего доступа, которые обновляются еще быстрее — самый быстрый канал, canary, «тихо» авто-обновляется почти каждый будний день.

Каким образом все это продолжает работать? Почему «колеса» у этого «автобуса» еще не «отвалились»? Почему еще не все разработчики сошли с ума?

С технологической точки зрения, скорость работы команды Chromium стала достижима благодаря надежным, эффективным и «тихим» авто-обновлениям.

С точки зрения человеческих ресурсов, в этом есть заслуга преданных своему делу, трудолюбивых и умных команд QA и релиз-инженеров, без которых весь проект развалился бы на части в считанные недели. А еще — дизайнеров, продакт-менеджеров, писателей, PR, адвокатов, ИБ и всех остальных, кто слаженно работает над каждым стабильным релизом. Сегодня я не буду рассказывать обо всех, сконцентрировавшись только на инженерной тематике, дабы не скатиться в гигантский пост в духе Стива Йегге.

Я собираюсь рассказать о процессе разработки Chromium, который выстроен специально для того, чтобы сделать возможными быстрые релизы. Речь пойдет об интересных находках, которые могут пригодиться другим проектам вне зависимости от того, как выглядит их график релизов; упомяну я и о наших трудностях.

Без веток


Во многих проектах общепринятой практикой является создание ветки для работы над новыми «мажорными» фичами. Идея при таком выборе заключается в том, что дестабилизация из-за нового кода не будет влиять на других разработчиков и пользователей. Как только фича завершена, она мерджится обратно в trunk, после чего обычно следует период нестабильности на то время, пока устраняются интеграционные вопросы.

С Chrome этот подход не сработает, поскольку мы релизимся каждый день. Мы не можем допустить внезапного появления в нашем trunk больших кусков нового кода, поскольку в таком случае велика вероятность, что каналы обновления canary или dev надолго уйдут в отказ. Кроме того, trunk в Chrome движется вперед с такой скоростью, что для разработчиков непрактично оставаться изолированными на своей ветке на слишком долгий промежуток времени. К тому времени, когда они смержат свою ветку, trunk будет выглядеть настолько по-другому, что интеграция будет трудоемкой и легко подвержена ошибкам.

Мы создаем эксплуатационные ветки перед каждым нашим релизом беты, но они живут очень недолго — максимум всего шесть недель, до следующего релиза беты. И мы никогда не ведем разработку непосредственно в этих ветках — все запоздавшие фиксы, которые должны войти в релиз, сначала делаются в trunk, после чего будет сделан cherry-pick в ветку.

Приятный побочный эффект подобного процесса: в проекте нет специальной команды разработчиков «второго сорта», которые занимаются исключительно работой с эксплуатационной веткой. Все разработчики всегда работают с последней актуальной версией исходного кода.

Переключатели среды выполнения


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

Вместо этого, проект Chromium использует проверки исполняющей среды. Каждая фича, находящаяся в разработке, компилируется и тестируется на всех конфигурациях с самого начала. У нас есть флаги командной строки, которые мы тестируем в самом начале; в остальных местах кодовая база по большей части не имеет представления о том, какие функции доступны. Данная стратегия означает, что работа над новыми фичами интегрирована в код проекта с самого начала в максимально возможном объеме. По крайней мере, новый код комплируется, так что все изменения в основном коде, которые необходимо сделать для работы новой функции, протестированы, а пользователь считает, что все работает как обычно и не замечает разницы. Ну а мы можем легко писать автоматические тесты, которые проверяют работу недоступных пока фич, временно «переопределяя» командную строку.

Когда фича подбирается ближе к завершению, мы презентуем опцию в виде флага в chrome://flags, чтобы продвинутые пользователи могли начать ее тестировать и сообщить нам обратную связь. В итоге, когда мы думаем что фича готова к выпуску, мы всего лишь удаляем флаг командной строки и делаем ее доступной по умолчанию. К этому времени код уже обычно протестирован вдоль и поперек, а также обкатан многими пользователями, так что потенциальный ущерб от его активации сведен к минимуму.

Огромный объем автоматического тестирования


Для того, чтобы релизиться каждый день, мы должны быть уверены в том, что наша кодовая база всегда находится в надлежащем состоянии. Это требует автоматизированных тестов, причем очень большого их числа. На тот момент, когда пишутся эти строки, у Chrome есть 12k юнит тестов уровня классов, 2k автоматизированных интеграционных тестов и огромные ассортимент тестов производительности, bloat-тесты, тесты на thread safety и memory safety, а также, возможно, многие другие, о которых я сейчас не вспомню. И все это только для одного Chrome; WebKit, V8 и остальные наши зависимости тестируются самостоятельно; у одного WebKit насчитывается примерно 27k тестов, которые удостоверяются, что веб-страницы отображаются и функционируют корректно. Наше основное правило заключается в том, что каждое изменение должно идти вместе с тестами.

Мы используем публичный buildbot, который постоянно прогоняет новые изменения в нашем коде на тестовом наборе (test suite). Мы придерживаемся политики «зеленого дерева»: если изменение «ломает» тест, то оно тут же откатывается, а разработчик должен пофиксить изменения и перевыложить их. Мы не оставляем подобных «критические» изменений в дереве, поскольку:

  • Это упрощает возможность случайно сделать еще больше «критических» изменений — если дерево и так красное, то никто не замечает, когда оно становится еще краснее
  • Это замедляет разработку, поскольку каждый будет вынужден работать над тем, что сломалось
  • Это поощряет разработчиков делать небрежные быстрые фиксы для того, чтобы пройти тесты
  • Это не дает нам релизиться!


Чтобы помочь разработчикам избежать неприятностей с деревом, у нас есть try-боты, которые являются способом «прогнать» изменение подо всеми тестами и конфигурациями перед тем, как выпустить его. Результаты отправляются на email разработчику. Еще у нас есть commit queue, которая служит для теста изменения и его автоматического применения, если все тесты пройдут успешно. Мне нравится пользоваться ею после долгой ночи, проведенной за хакингом — я нажимаю кнопку, ложусь спать, и спустя какое-то время просыпаюсь с надеждой на то, что мое изменение влито.

Благодаря всему производимому автоматическому тестированию, мы можем отделаться минимальным количеством ручного тестирования на нашем канале dev, а на «канарейках» не проводить его совсем.

Безжалостный рефакторинг


Поскольку у нас есть достаточно обширное покрытие тестами, мы можем позволить себе быть агрессивными в рефакторинге. В проекте Chrome все время идет работа над рефакторингом в нескольких основных направлениях — например, на период 2013 года таковыми являлись Carnitas и Aura.

При наших масштабах и темпе, критически важно держать кодовую базу чистой и доступной для понимания. Для нас эти качества более важны, чем предотвращение регрессий. Инженеры всего проекта Chrome имеют право делать улучшения в любом месте системы (однако, при этом мы можем запросить обязательное ревью владельца модуля). Если в результате рефакторинга что-нибудь в итоге ломается, причем это не удается обнаружить на этапе тестирования, то с нашей точки зрения это вина не того инженера, который делал рефакторинг — а того, чья фича была недостаточно покрыта тестами.

DEPS


WebKit развивается не менее быстрыми темпами. И, аналогично тому, что мы не можем позволить себе иметь ветки для фич, которые когда-нибудь внезапно вольются в основную, мы не можем позволить себе пытаться смержить месячный набор изменений в WebKit весь и сразу, поскольку это дестабилизирует дерево на несколько дней.

Вместо этого мы пытаемся скомпилировать Chrome вместе с самой последней версией WebKit (почти всегда эта версия не старше половины дня), пока не достигнем успеха. В корне проекта Chrome лежит файл, который содержит версию WebKit, с которой он сейчас успешно компилируется. Когда вы делаете чекаут и создаете рабочую копию, или же обновляете исходный код Chrome, то инструмент gclient автоматически получает версию WebKit, указанную в файле.

Ежедневно несколько раз в день инженер обновляет номер версии, выясняет, возникли ли новые проблемы при интеграции, и присваивает баги подходящим инженерам. В результате, мы всегда получаем мелкие изменения в WebKit все сразу, и при подобном подходе оказываемый на наше дерево исходников эффект обычно минимален. Мы также добавили ботов к buildbot WebKit'a, благодаря чему когда инженеры WebKit делают изменение, которое поломает Chrome, они узнают об этом немедленно.

Большим преимуществом системы DEPS является то, что мы можем добавлять изменения к своей веб-платформе очень быстро. Появившаяся в WebKit фича станет доступной пользователям Chrome на канале canary в течение всего лишь нескольких дней. Это сподвигло нас к тому, чтобы делать улучшения сразу в апстриме WebKit, где они пригодятся всем, кто использует WebKit в своих приложениях, а не применять их локально у себя в Chrome. Честно говоря, нашим основным правилом является то, что мы вообще не делаем локальных изменений в WebKit (как и в остальных проектах, от которых зависит Chrome).

Проблемы


Тщательное тестирование остается неразрешенным вопросом. В частности, «нестабильные» интеграционные тесты (flaky integration tests) стали для нас постоянной проблемой. Chrome — большой, сложный, асинхронный, мультипроцессовый и многопоточный. Так что для интеграционных тестов проще простого проваливаться из-за едва различимых проблем синхронизации, что и происходит время от времени. На проекте наших размеров, тест, который фейлится 1% времени, в итоге гарантировано будет фейлиться по несколько раз в день.

Как только тест становится «нестабильным», команда быстро приобретает привычку его игнорировать, в следствие чего бывает просто упустить фейл другого, рабочего теста для той же части кода. Поэтому мы склонны отключать «нестабильные» тесты и теряем в проценте покрытия, делая проще выпуск основных регрессий для пользователя.

Другая проблема состоит в том, что на такой скорости становится тяжело «наводить красоту». Как по мне, команде проще добиться правильного выполнения всех деталей в редких «громких» релизах, чем пытаться сохранить и постоянно удерживать фокус внимания на каждой мелочи в течение неопределенного времени. Поскольку зачастую тестировать мелкие детали вроде расстояния между кнопками в панели инструментов бывает тяжко, в таких местах легко закрадываются ошибки.

Наконец, мне кажется, что вполне себе реальной проблемой является стресс. Учитывая весь этот код, который постоянно меняется, даже если человек пытается сфокусироваться только на своей зоне ответственности, это не значит, что его не заденет что-то происходящее в другой части проекта. Если вы постоянно пытаетесь сохранить вашу часть Chrome в работоспособном состоянии, то рано или поздно вам начнет казаться, что вы живете как на вулкане, и не можете себе позволить ни минуты спокойствия.

С последней проблемой мы боремся при помощи разбиения кодовой базы на основные модули. Инженеры, занимающиеся задачами Carnitas, пытаются установить более ясные и жесткие интерфейсы между некоторыми из наших главных компонентов. На данный момент, значительная часть кода стала чище и яснее, но пока еще слишком рано говорить о том, насколько это поможет уменьшению стресса на глобальном уровне.

В заключение


Итак, благодаря чему «колеса» у нас пока еще не «отвалились»? Вкратце: благодаря жизни без веток, переключателям среды выполнении, тоннам автоматических тестов, безжалостному рефакторингу, и удержанию позиций как можно ближе к HEAD наших зависимостей.

Эти техники будут наиболее полезны большим проектам, у которых есть быстро изменяющиеся апстрим-зависимости, но вполне возможно, что некоторые из них окажутся применимы и к проектам меньших размеров.
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну, и что?
Реклама
Комментарии 51
  • +7
    Действительно интересно было почитать, как серьёзные компании делают продукты, находящиеся в центре внимания миллионов людей.

    И, как всегда, некоторые вещи удивляют — например, заходя сюда, я ожидал увидеть сложные механизмы CI, а взамен — пара бранчей и вообще всё проще и надёжнее, чем казалось.
  • +1
    Да, очень круто. Хотелось бы когда-нибудь в жизни поработать в подобной команде)
    • +20
      Я бы не советовал :) Крупный проект — это всегда отвратительное сочетание колоссальной ответственности и колоссальной же беспомощности.
      • +8
        Другими словами, это одна их тех областей жизни, про которую интереснее читать, чем в ней участвовать.
        • +1
          Я не сказал, что это неинтересно. Я приведу параллель. Работать спасателем в МЧС интересно. Изучать смертельные вирусы интересно. Ловить преступников интересно. Все эти занятия очень интересны — вряд ли кто-то станет отрицать.

          Разумеется, это — гротеск. Но смысл, надеюсь, ясен. Проблема не в том, что интересно, а в том, чего это может/будет вам стоить.
    • –34
      Хотел спросить: В Chromium есть какие то бэкдор механизмы или прочие механизмы для отслеживания пользователей? После информации, которую опубликовал Сноуден, как то стремно доверять большим пиндосовским компаниям типа Google.
      • +13
        Так Интернет и прочее — тоже «пиндосовское» изобретение… Как вы в нем сидите то? =)
        • –29
          Изобретение да, пиндосовское. Но интернет не пиндосовский. Все таки есть огромное количество проектов, которые разрабатываются сообществом из всего мира и не находятся под коммерческим управлением.
          • +3
            А сети и каналы связи как? Тоже сообщество поддерживает?)
            • –7
              Сети и каналы связи неважно кто поддерживает. Главное чтобы информация через эти каналы связи проходила в зашифрованном виде.
              • 0
                Какой вы забавный. Всю информацию шифруете? А сервисами какими-нибудь пользуетесь, они все шифруют? А расшифровать ее точно нельзя или подделать? А перенаправить?
              • –7
                … пока что каналы связи к сожалению поддерживаются коммерческими предприятиями. Но я считаю что будущее интернета именно за так называемыми Mesh-сетями (https://en.wikipedia.org/wiki/Mesh_networking)
                • 0
                  Это мило конечно, но силами сообщества осуществимо только на каком-то небольшом локальном уровне.
          • +1
            Chromium это OpenSource проект, наличие закладок в нём маловероятно. А вот в основанном на нём Chrome да, их наличие гарантировано.
            • +4
              Доверять никому нельзя. Даже себе.

              Мюллер
              • 0
                Так откройте, почитайте, нам расскажете.
              • –13
                С Chrome этот подход не сработает, поскольку мы релизимся каждый день. Мы не можем допустить внезапного появления в нашем trunk больших кусков нового кода, поскольку в таком случае велика вероятность, что каналы обновления canary или dev надолго уйдут в отказ. Кроме того, trunk в Chrome движется вперед с такой скоростью, что для разработчиков непрактично оставаться изолированными на своей ветке на слишком долгий промежуток времени. К тому времени, когда они смержат свою ветку, trunk будет выглядеть настолько по-другому, что интеграция будет трудоемкой и легко подвержена ошибкам.
                Так и запишем — разработку в ветках не осилили. Детский сад какой-то.
                • +7
                  действительно детский сад:
                  Кроме того, trunk в Chrome движется вперед с такой скоростью, что для разработчиков непрактично оставаться изолированными на своей ветке на слишком долгий промежуток времени.


                  — работа в ветках предполагает как минимум ежедневный мерж транка в свою ветку или чаще в зависимости от объема, в результате потом финальный мерж в транк проходит беспроблемно, ничего не изолированно и не уйдет в отказ если руки прямые.
                  • 0
                    rebase
                    • 0
                      Терять историю изменений — это очень «разумно». Вообще работа с ветками в гите — так себе. В меркуриале гораздо лучше.
                      • 0
                        WAT? Когда это rebase убивал историю?
                        • 0
                          Всегда. Это его основная функция. Или по вашему история — это только содержимое изменений без информации о том, в каком контексте они сделаны?
                          • +2
                            Знаете, насчет меркуриала — когда я узнал, что там, в отличие от git, сохраняется пометка о ветке в каждом коммите, тоже сперва восхитился. А потом понял, что расхождение тут — идеологическое. И понял, что идеология git-а разумнее. И состоит она, как мне кажется, в следующем:

                            1. Все разработчики коммитят проект последовательно. Для того, чтобы исключить «технические мержи», существует rebase. (У нас в команде уже полгода десять человек успешно живут втодной ветке и радуются жизни).

                            2. А для чего ветки? Для того, чтобы поддерживать несколько разных версий продукта одновременно. То есть, понимаете ли, если вы заранее знаете, что завтра вы изменения смержите в master, то делать для них отдельную ветку — не комильфо. Вообще, мержи — это фу-фу-фу. Они нужны только в самом экстренном случае. А если вы хотите накатить изменение на 5 веток сразу, то тут есть cherry-pick.

                            3. (Самый главный аргумент в пользу логики гита) Если вы-таки уже смержили одну ветку в другую, то не все ли равно, в какой из них были выполненные ранее изменения? Вы теперь эту ветку вообще можете удалить — разницы в итоге не будет. Нет ее больше. Всё. Если вы теперь в нее коммитите, то по сути вы ее заново отращиваете.

                            При таком подходе «дерево коммитов» действительно будет деревом, а не паутиной.
                            • 0
                              1. А что плохого в технических мержах? Они чётко дают понять, что вот тут фичеветка А была влита в мастер, а вот тут для неё были сделаны дополнительные фиксы, которые потом тоже попали в мастер. А с ребейсом у вас для дофикса нужно заводить отдельную ветку. А потом вам нужно вашу фичу отправить в релиз без остальных и начинается полуручной перенос кода черипиками.

                              2. Я не знаю, когда я смержу в мастер. Может тестировщики найдут критикал баг и конктрено мою фичу придётся отложить.

                              3. Не всё равно. История необходима, чтобы понять где и почему была допущена та или иная ошибка. Банально после rebase у вас может отвалиться bisect, так как вы банально не сможете сбилдить промежуточные коммиты. Подробности: http://habrahabr.ru/post/179673/
                        • +1
                          Почему-то никто из тех, кто хвалит меркуриал не может дать ссылку на нормальную статью или документ, где хорошо объяснено чем же он так лучше. Чтобы прочитал и сразу понятно, вот как круто, без зубрёжки документации и получения очередного высшего образования. Гит тоже сложно понять, но за счёт популярности есть много готовых рецептов и книг вроде того же Pro Git.
                          • 0
                            Вам сюда: http://habrahabr.ru/post/123700/
                            • 0
                              Не вижу ни одного примера команды и вывода в статье
                              • 0
                                А за этим вам сюда: http://hginit.com/
                    • 0
                      events.yandex.ru/lib/talks/2588 — должно быть вам будет интересно.
                      • 0
                        Там почти тот же gitflow. Разве что черрипик коммитов между ветками — это жесть.
                        • 0
                          Это автоматизированное действие. Уже почти два года практически никогда никто не делает черрипики вручную. В момент создания пулл-реквеста в мастер указывается, в каких ветках нужен этот код и пулл-реквесты с черри-пиками в них будут созданы автоматически. Разве что иногда появляются конфликты и робот просит сделать черепки руками и запушить его в ветку, из которой он сделает пулл-реквест. Это был чуть ли не самый ожидаемый плагин к стешу от группы инфраструктуры (после автомерджа, конечно).
                          • 0
                            Жесть не потому, что вручную, а потому, что перенос патчей не трекается полноценно системой контроля версий со всеми вытекающими (привет, SVN < 1.5). И это не говоря о том, что перенос патчей с пропусками череват появлением багов вида «патч неявно зависит от состояния кода, достигнутого другим патчем, который не был перенесён так как относится к другой фиче».
                            • 0
                              На нашей инфраструктуре по сути не имеет смысла трекать историю черри-пика, все равно всегда можно найти соответствующие пулл-реквест и задачу. А подобные баги мы ловим тысячами тестов и тестированием силами команды qa. Да и черни-пики сами по себе, как правило это баг-фиксы, фичи, которые не попали в мастер до отвода релизной ветки в эту ветку не попадают.
                              • 0
                                Как вы узнаёте в какие ветки попал определённый патч?
                                Как вы узнаёте все ли патчи попали в определённую ветку?

                                Прогон тысяч тестов — несколько часов до фидбэка
                                Прогон тестировщиков — несколько дней до фидбека

                                • 0
                                  Робот отписывает в задачу, в какие ветки попал связный патч. Робот же не дает влить патч в ветку, если в задаче не проставлена нужная версия.
                                  Задача закрывается когда патчи для нее попали во все требуемые ветки (это контролирует разработчик).

                                  Тесты прогоняются перед вливанием патча. Патч не вливается, если они не проходят.
                                  Ветка живет шесть недель, этого достаточно чтобы провести несколько этапов тестирования и починить все обнаруженные баги.
                                  • 0
                                    Ну то есть половину функций системы контроля версий вы решаете роботизированным багтрекером и руками разработчика.

                      • 0
                        А знаете, кто еще «не осилил»? Ребята, которые придумали Continuous integration. Почитайте на досуге. Кто что «осилил» — всегда открытый вопрос.
                        • –2
                          Давайте вы лучше почитаете про gitflow: https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow
                          • 0
                            А причем тут это? Continuous integration — это идеология разработки. А git flow — инструмент…
                            • –1
                              Там есть и continuous integration и feature branches.
                      • 0
                        Данная стратегия означает, что работа над новыми фичами интегрирована в код проекта с самого начала в максимально возможном объеме.

                        Есть ли какие способы в подходе «одной ветки» гарантирующие, что новая, еще не законченная фича, которая не должна выезжать на пользователей, выедет, и это повлечет результат, сравнимый с недавним факапом Яндекса?
                        В стандартном подходе «фича — ветка» предполагается, что ветка мерджится в основную только после завершения задачи, и, как следствие, готова к релизу.
                        • +2
                          Нет тут никаких гарантий и быть не может. Всё держится на условиях времени исполнения. При этом не редки случаи, когда фичи сами по себе работают, а при включении обоих флагов что-нибудь где-нибудь ломается. При этом все n^2 комбинаций флагов разумеется никто не тестирует. То есть надеются на авось и на суровый профессионализм C++ разработчиков, привыкших к undefined bahaviour.
                        • 0
                          Статья слегка не актуальна. Вчера код blink был вмерджен в основной репозиторий chromium.
                          • 0
                            Единственное, что не раскрыли — версионирование. С каких пор версии полетели как самолёт по взлётке? Чем 45 так отличается от 44, например, что она не 44.0.1? Я как пользователь вообще разницы не вижу
                            • +2
                              Просто кажды релиз они прибавляют +1 к версии. А учитывая что релиз каждые 6 недель — в год выходит 8-9 версий. И не важно, насколько крутые изменения были. В этом плане мне нравится больше подход Яндекс.Браузера или Ubuntu, где версия выглядит так: год.месяц — все четко, и понятно, и нет таких гигантских чисел даже при минимальных изменениях функционала.
                              • –1
                                Ну ведь согласитесь — это тупо. Для проектов в вечном rolling release есть yy.mm.dd, как вы верно заметили, для всего остального — major.minor.patch. Ох уж эта гонка за цифрами!
                                • +2
                                  Согласен. Мне кажется yy.mm.dd можно было бы вообще ко всем проектам применять, для тех которые релизятся раз в год и реже — уу(Visual Studio 2015), которые чаще чем в раз год, но не чаще раза в месяц — уу.mm (Yandex.Browser 15.10), а для тех, которые пару раз в месяц и чаще — либо yy.mm.dd либо yy.mm.nn(где nn — порядковый номер релиза в текущем месяце, примеров известных вспомнить не могу)
                            • 0
                              Значит ли это, что ревью кода делается когда он уже в стволе? Как быть в таком случае с джуниорами, которые коммитят всякий трэш?
                              • 0
                                Очевидно, они могу себе позволить нанимать только сеньоров :-)
                                • +2
                                  Ревью кода производится до мерджа. Только когда все owner-ы кода отписали LGTM, без этого не пройдет pre_commit сборка. После этого можно нажать кнопку commit, пр попадет в commit-queue и для него соберутся сборки. Если сборки зеленые, то код коммитится в мастер. Вот пример ревью, в котором были и притензии к коду и падающие сборки и четыре owner-а измененного кода: codereview.chromium.org/673623002

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое