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

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

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

Я только не совсем понял из текста:

Разработка ведется по модели Trunk based development. Большинство пользователей работает с HEAD или наиболее свежей копией репозитория, полученной из основной ветви, называемой trunk, в которой идет разработка. Фиксация изменений в репозитории осуществляются последовательно. Сразу после коммита новый код виден и может использоваться всеми разработчиками. Разработка в отдельных ветках не приветствуется, хотя ветки могут использоваться для релизов.


Что значит разработка в отдельных ветках не приветствуется? Имеются в виду ветки, в которых может осуществляться долгая параллельная разработка (до недель)? Потому что по ссылке trunkbaseddevelopment.com явно написано, что каждое изменение выделяется в одну ветку (feature branch), которая существует некоторое время (короткое — дни), а потом вливается в репозиторий при помощи мержа. Это не совсем то же самое, что и «каждый отдельный коммит». Или вы заставляете обязательно делать людей squash для всех коммитов в их feature branch, а потом rebase того, что получилось, от trunk (master)? Хотелось бы конкретики :)

А еще я проглядел (или в статье этого нет): какую систему контроля версий вы используете?
Что значит разработка в отдельных ветках не приветствуется? Имеются в виду ветки, в которых может осуществляться долгая параллельная разработка (до недель)? Потому что по ссылке trunkbaseddevelopment.com явно написано, что каждое изменение выделяется в одну ветку (feature branch), которая существует некоторое время (короткое — дни), а потом вливается в репозиторий при помощи мержа. Это не совсем то же самое, что и «каждый отдельный коммит». Или вы заставляете обязательно делать людей squash для всех коммитов в их feature branch, а потом rebase того, что получилось, от trunk (master)? Хотелось бы конкретики :)


Строгих правил нет, только рекомендации, никто никого не заставляет. Некоторые команды используют подход с feature-braches. У нас есть много примеров, когда команды сами приходят к пониманию того что разработка в trunk намного удобнее. Многие проекты вели разработку в отдельных ветках, которые могли жить по несколько месяцев. Мержить изменения в trunk и обратно, отщеплять новые ветки – все это было достаточно трудоемкими задачами. Далее время жизни веток постепенно сокращалась, пока разработка полностью не переезжала в trunk. Твой вариант (про squash) почти корректный, но есть набор некоторых допущений.

А еще я проглядел (или в статье этого нет): какую систему контроля версий вы используете?


В статье этого нет, для монорепозитория у нас используется несколько систем контроля версий, которые работают над одним набором данных. На текущий момент это svn, hg и некоторые внутренние разработки.
Если развернуть, то получится еще одна статья, – когда-нибудь обязательно напишем, если вам интересно.
На текущий момент это svn, hg и некоторые внутренние разработки.

Теперь понятно, почему часто фигурирует слово trunk. Не проще всё перевести на git? С svn не работал, а вот с серьёзными проблемами вытягивания большого объёма данных при пропадающем соединении у hg уже успел столкнуться за единственный раз работы с ним. Догадываюсь, что у git есть преимущества по сравнению с обоими системами контроля версий.
Про git ответил здесь.
Если вам интересно, через некоторое время мы напишем подробный пост про проблемы, которые стоят перед системой контроля версий. Про преимущества и недостатки различных решений.
Тоже интересно и хотелось бы узнать детали, т.к. на прошлой работе использовался стандартный подход с N репозиториями. БОльшая часть проектов — C++ (система сборки CMake). Подход был не без проблем, со своими костылями, но жило всё хорошо. Из основных проблем были: как найти зависимости какого-то проекта, который тебе надо поправить, как обновлять каждую зависимость (к сожалению, каждая команда решала эту проблему сама: кто-то делал общий git-репозиторий с подмодулями, кто-то, как я, писал специальные скрипты и поддерживал список зависимостей), а также, если ты правишь свои проекты в нескольких версиях, то нужно либо под каждую версию держать свое дерево зависимостей, либо каждый раз все их обновлять.

Есть некоторые вопросы:

1. Каким образом разработчик взаимодействует с репозиторием? Он же не клонирует себе все 25 Гб? Отсюда же вопрос про push/pull. На следующий день придется скачивать более 2к коммитов? Полагаю, что нет и есть возможность скачать часть репозитория.

2. > любой проект из репозитория получает готовую инфраструктуру
А GitLab разве не дает все то же самое? Тот же community-edition. Если возможностей код-ревью GitLab мало, конечно, можно запилить своё, но просмотр и навигация по коду там сделаны вполне себе неплохо.

3. > система сборки и распределенная сборка. Это отдельная большая тема, и мы обязательно ее раскроем в следующих статьях.
Что имеется в виду под системой сборки? Система сборки проектов на C++? А что вообще у вас используется для сборки проектов на C++? CMake/waf/SCons? Или же имеется в виду аналог Jenkins?

4. > система непрерывной интеграции.
А чем не подошел Jenkins?

5. > совместное использование кода, активное взаимодействие команд.
В чем проблема совместно использовать код и активно взаимодействовать в подходе с множеством репозиториев?

6. > С общим кодом у вас появляется возможность сделать часть работы самим и «помочь случиться» нужным вам изменениям.
Опять непонятно каким образом то же самое не дает делать подход с N репозиториями: склонировал себе, сделал ветку, запушил, сделал pull request.

7. > появляется возможность проводить глобальный рефакторинг. Вам не надо поддерживать старые версии вашего API или библиотеки, вы можете изменить их и поменять те места, где они используются в других проектах.

Опять как-то странно. Когда N репозиториев: склонировал их себе, поправил, запушил. Сделали деплой новой версии на рабочие сервера и перестали поддерживать старую версию.

Из плюсов для себя вижу только решение проблемы dependency hell и упрощение сборки, т.к. не надо поддерживать список зависимостей с ревизиями/ветками, на которые надо обновляться. Но даже если и его надо было бы поддерживать, то это не такая и большая проблема, т.к. многое можно автоматизировать.
1. Каким образом разработчик взаимодействует с репозиторием? Он же не клонирует себе все 25 Гб? Отсюда же вопрос про push/pull. На следующий день придется скачивать более 2к коммитов? Полагаю, что нет и есть возможность скачать часть репозитория.


Есть селективный checkout.
Что имеется в виду под системой сборки? Система сборки проектов на C++? А что вообще у вас используется для сборки проектов на C++? CMake/waf/SCons? Или же имеется в виду аналог Jenkins?


Имеется в виду система автоматизации сборки.
А чем не подошел Jenkins?

— Jenkins не умеет делать то что умеет делать наш CI. Стоимость доработки и адаптации под наши процессы, интеграция с другими нашими системами может легко превышать стоимость разработки своей системы с нуля.
— Тесная интеграция CI системы с нашими процессами и другими системами.
— Наша система скрывает за собой комплекс из нескольких систем. CI система, распределённая система выполнения задач общего назначения с кластером большого размера, система распределенной сборки. Обо всем этом мы будем постепенно рассказывать.
— зато стоимость поддержки может легко превышать стоимость коробки или опенсурс решения. Тем более, что коммьюнити ничего не выиграет от вашей системы сборки.
— касательно Jenkins. Мне он не очень нравится. Мне больше нравится Gitlab-ci, еще крутой concourse. Что-нибудь такое готовое используете? Потому что платформа сборки — это чуточку шире, чем какой-то отдельный продукт. И я могу представить себе систему, которая объединяет под капотом concourse/gitlab-ci/ набор сервисных докер-образов и все это работает поверх какого-нибудь менеджера ресурсов (k8s?)
В некоторых проектах все еще используется Jenkins и не только он, но все постепенно переезжают в общий CI. Opensource и многие платные решения тут не заработают, хотя бы из-за объема обрабатываемых данных. Тут нужно полностью пересматривать архитектуру. А еще поддержка описанных выше сценариев. Подожди следующую статью про устройство системы – она будет опубликована примерно через неделю.
Да, жду. Спасибо.
В Polymetal мы тоже нуждались в системе более гибкой чем Jenkins. По хорошему нам нужен был framework на котором мы бы создали свой CI инструмент. Выбрали Buildbot. Мягко сказать он не популярен в рунете. У нас работает на ура. Не всегда требуется прям все писать с нуля в плане своего CI. Вот я статья которую я написал на этот счет . Кратко, наш полет фантазии эта система никак не ограничевает, напротив здорово помогает. Но тут надо знать python так как она состоит из python модулей.
Вот я статья которую я написал на этот счет

ссылку не увидел. Или ее не было?

Некоторые команды используют подход с feature-braches


Не совсем понял из статьи. Подскажите пожалуйста — для feature branch так же как и для trunk автоматически будут запускаться сборки, тесты и т.п.?
Если подключить к CI системе – да.
> какую систему контроля версий вы используете

Для хранения единой кодовой базы Яндекс использует SVN

Про git видимо не слышали

Не любитель SVN, но разве git умеет комофортно работать с монорепозиторием таких размеров?
НЛО прилетело и опубликовало эту надпись здесь
Единый (монолитный) репозиторий — это довольно популярная тема, про которую написано много статей. В рамках данной статьи нет возможности раскрыть эту тему подробнее. Если хочется изучить тему подробнее, можно почитать в Википедии. Там есть очень хороший набор ссылок.
Ребята, вы явно застряли в прошлом, в нулевых. Я понимаю что при таких масштабах сложно совершать маневры и это накладывает ограничения. Но Git изменил идеологию совместной работы с кодом. И вам давно пора внедрить корпоративный Gitlab. Ну не кошерно все хранить в одной «помойке». Аргументы больше надуманные в пользу монолитных репозиториев. Разделяй и властвуй. То же относится и к коду.

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


Ну и монолитная репа помогает сразу отлавливать проблемы API, ибо при смене API в одной зависимости надо сразу же починить все зависимые куски, иначе у тебя не пройдет CI.


Другое дело, что создавать свой YMake, который типа не CMake, держать код в svn, потому что "тижило портировать" — ну это детский сад.

Пакетные менеджеры С++ довольно сильно развиваются, но с озвученные проблемы тоже пришлось решать.
К примеру — conan, crosspm

:)
что «тижило портировать» — ну это детский сад.


Свой проект — еще куда не шло.

А все используемые либы, и либы от которых зависят используемые либы и те либы от которых они зависят либы используемые либами, которые мы используем и…
Слышали, завести гит на монорепозитории с таким объемом кода невозможно без огромного количества дополнительных приседаний.

Microsoft gvfs на текущий момент полностью эту задачу не решает.
Каких-либо доступных снаружи решений нет.

Т.к. с git мы знакомы достаточно тесно, внутренние разработки в районе VCS базируются как раз на git.

25GB — ни о чём объёмы для гита. Это я вам как бывший обладатель Git-репозитория на полтора терабайта и нынешний обладатель Git-репозитория на 70GB говорю.

25 GB — это размер текущего полного чекаута в HEAD репозитория, без метаданных и истории. Положить такой репозиторий в git можно. Но эффективно разрабатываться в несколько тысяч разработчиков в одном таком репозитории — другая более сложная задача. Эту задачу мы уже решаем, напишем отдельно через какое-то время :)
А как же подмодули? С ними крайне неудобно, но если заскриптовать всё по максимому, то вполне сносно.
  • Добавляется унификация проектов, в том числе и в CI. Иерархически подключенные подмодули — сложно (в плане CI/CD), но реализуемо.
  • Возможность множественных вложенных (в плане повторений в рамках проекта) подмодулей тоже реализуема, но через систему сборки и скрипты над git.
  • Всё однотипное, тестируется по одинаковым принципам.


На мой взгляд, монорепозиторий — это крайне неудобно. К тому же из подмодулей можно вполне и тот же монорепозиторий сделать, если очень захочется.
«каждый отдел мог использовать любые языки, любые технологии, любые системы деплоя. И как показала практика, такая свобода не всегда помогала двигаться вперед быстрее»
А Гуглю помогает… habr.com/post/429018/#comment_19334662
Набирают олимпиадников-хипстеров, которые пишут свои велосипеды, а потом сами же бегут от этого зоопарка. Бинго! до них дошло, что должны быть какие-то правила, переиспользование кода. Вместо того, чтобы писать свои велосипеды, лучше развивать то, что уже есть, вкладываться в опенсурсные проекты
Знание всяких заумных алгоритмов и хайповых технологий — далеко не показатель ума и качества работы потенциального сотрудника, гораздо важнее уметь писать поддерживаемый код и разрабатывать стройную архитектуру, а не «мермишель», но зато ппц какую крутую, имхо
+++
50 000 проектов и библиотек / 2000+ разработчиков = 25 проектов на разработчика…
Есть ощущение, что что-то идет не так.

Судя по такой статистике каждый вновь прибывший разработчик пишет свой велосипед, каждый ушедший разработчик оставляет за собой гору велосипедов, которые никто не хочет использовать и поддерживать или не знает как использовать.

Там где я работаю можно не хило по шапке получить за новую библиотеку или зависимость или за то что народ не разбирается в твоем велосипеде. А в больших компаниях наоборот… вот недавно только пост был habr.com/post/429018

А если по теме статьи, то такое ощущение что создается монолит со скоростью 10 коммитов в секунду и этот адский огромный монолит нужно прогонять по тестам в короткие промежутки времени… но тестов очень много и за секнду не прогоняется и падает всегда. Да и вообще даже внутри тестов энтропия такая, что неизвестно тест вообще рабочий или нет.

Был на гугловой конфе, там одна из команд рассказывала про международный проект, где была всего лишь одной из сотен команд по всему миру (то есть суммарно тоже тысячи разрабов). Так вот они отвечают только за свои микросервисы (а может и не микро). Каждый имеет свою документацию поддерживаему и технически не сильно зависит от остальных. Свои сервера, свои технологии. Главное что бы документация была подробной, понятной, актуальной и доступной для всех пользователей (внутренних) этого сервиса. В общем полная децентрализация и минимум зависимостей и своих велосипедов и всё у них хорошо.
Вывод не совсем верный. 50 000 проектов и библиотек = 50 000 целей системы сборки. Сюда входят библиотеки, различные составные части проектов, бинарники программ, множество исходников open-source библиотек и другие артефакты.
Начиная с некоторого размера, свои велосипеды просто необходимы.

Во-первых, люди хорошо знают проект и могут очень быстро починить проблему.

Во-вторых, если писать код с оглядкой на специфику компании, а не под общий случай, с которыми обязаны работать продукты общего назначения, можно улучшить технические показатели (память, нагрузка на CPU) на порядок. Например, если известно, что в БД только целые числа, а индексы и запросы только определённого вида, код можно написать на порядок эффективнее, чем для БД общего назначения.
Во-первых, люди хорошо знают проект и могут очень быстро починить проблему.

да ладно… этож не стартаперы. Люди приходят и уходят. Среднее время работы разработчика около 3х лет. Сомневаюсь что в Яндексе по 10 лет работают в среднем.

+ Ротация между проектами наверняка имеет место быть, а то с ума сойти можно.

Так что если доки актуальной нет на велосипед (а обычно никто не поощряет документирование велосипедов) — то скорее всего проще написать еще один велосипед, получить премию и почёт. Ну или закостылять, ведь подругому то никак в старом велосипеде не разобраться.

_____

А то что необходимы — это да… но не 25 проектов на человека ведь.

Согласен и не согласен одновременно. Меня тоже очень удивляло желание Яндекса писать все самостоятельно, да ещё и на с++. С другой стороны, у них велосипеды получаются реально крутые (например, Кликхаус, Я.Облако)

При найме проверяются в основном самые базовые знания. Подготовиться к собеседованию достаточно просто, если поставить перед собой такую цель и стремиться к ней: yandex.ru/jobs/ya-interview
Уж наслышаны о вас, тем боле в свете этой статьи… благодарю, но нет такой цели
Ошибок в вашем коде быть не должно, лучше написать неэлегантный код, но без ошибок, чем наоборот
вот так и пишутся разного рода неподдерживаемые «лисапеды» с говнокодом, зато ЧСВ у написавшего зашкаливает. И что значит не должно быть ошибок? Как вы в таком случае нанимаете сотрудников, да еще и CI/CD настраиваете, когда сами себе и противоречите?
Речь не про неудачные проекты. Таких и у нас хватает – все иногда ошибаются. Речь про повторное использование результатов труда. Если в каждом новом проекте не нужно заново изобретать велосипед, работа пойдет гораздо быстрее. Если все же нужно сделать велосипед — поделись с коллегами, поставь его на видное место.

Очень обстоятельная статья. Спасибо. Дочитал до середины, остальное — на закуску


Сразу два вопроса.


  1. Безопасность. Все ли разработчики видят код всех остальных? По всем проектам? А что с секретами — реквизиты подключения к БД, сертификаты ssl и пр.?
  2. trunk. Это косвенно говорит об использовании svn. Я угадал? Если нет, то какая система управления версиями используется ?
Sensitive данные и ключи доступа хранятся в специальных система, не в исходном коде.
Исходный код доступен всем.

Про trunk ответил тут.

Получается нет исходного кода, который является тайной? Я как-то читал, что то ли алгоритм ранжирования, то ли еще что-то в Яндексе хранится за семью замками. Это не правда?

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

Ну, и инфраструктура тоже в отдельном репо, видимо?

Инфраструктура живет в общем репозитории. Было бы странно если бы мы первыми не использовали общие и основные решения.

Сколько по времени обычно длится бинарный поиск коммита, который ломает тесты?

Зависит от того как часто запускается тест, сколько было влияющих на тест коммитов и сколько времени работает тест. Мы планируем работать над ускорением этого процесса. При бин. поиске можно делать несколько запусков с опережением, но это дорого. Можно пробовать предсказывать коммит, который вызывал поломку теста.
Один общий репозиторий на 25 гигабайт? Это звучит так отстойно, что… ну неужели это обязательно было делать то?
Ответит тут.
Один общий репозиторий на 25 гигабайт? Это звучит так отстойно, что… ну неужели это обязательно было делать то?


Монорепы очень любит и Google.
И самый большой в мире репозитарий — у Microsoft.

Почему так не скажу, но большие репы в организациях, серьезно занимающихся ИТ — не редкость.
не редкость. И они решают часть проблем с версиями. Но сразу тащат за собой необходимость специализированного тулинга. В случае кучи маленьких репозиториев — можно попробовать обойтись штатными средствами git/jenkins/gitlab-ci и пр., но, как показывает практика, тулинг все равно понадобится (хотя может и не сразу).
А как из общего репозитория вытащить только код конкретного проекта? Или надо качать все 25 гбайт?
У нас есть селективный checkout, который интегрирован с нашей системой сборки. При сборке определенного проекта можно выкачивать все нужные ему зависимости.
Не понял про «нужной вам библиотеки может не быть в репозитории, но она есть в open-source. Есть затраты на ее добавление и обновление. Сильно зависит от языка и библиотеки, где-то почти бесплатно, где-то очень дорого.»
Вы все внешние зависимости прямо исходниками в репу тащите? О_о
OpenSSL нужен — фигак и забрали, webkit нужен — фигак и тоже…
Да.
Это же в какую попоболь выливается обновление минорной версии библиотеки, не говоря уже про мажорные релизы. При таком подходе к разработке техдолг должен накапливаться только в путь.

Да ни в какую, если соблюдать semver. Другое дело, что на семвер обычно кладут. И в любом случае боль не больше, чем если обновится внешняя библиотека, которая лежит не в монорепе, а где-то в репозитории debian.

Если не монорепа, то обновление зависимости будет быстрым для проекта. Для устранения техдолга есть тикет в джире (состоит из подзадач: устранение костылей, обновление зависимостей, рефакторинг), как он закрывается — создается аналогичный новый и закидывается в конец очереди.
А за тем, какие дебпакеты приедут на сервера, где крутится мой сервис — я сам прослежу.

Как это выглядит в монорепе? Кто выделяет ресурс для таких общих и масштабных задач? Или какая-то одна проектная команда тратит свои драгоценные человеко-дни, чтобы всем сделать хорошо?
Если не монорепа, то обновление зависимости будет быстрым для проекта.

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


С другой стороны я бы послушал аргументы amkruglov по этому поводу.

Когда проекты зависят по исходникам – обновление зависимости подразумевает обновление всех проектов, которые от неё зависят.

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

Иногда требуемую open-source зависимость может положить в репозиторий какая-либо проектная команда. Но заметную часть работы выполняет соседняя с нами команда. И всем действительно хорошо :)
вообще это правильная история. Дело в том, что любая внешняя зависимость может в любой момент времени взять и умереть.
Я знаю кучу брошенных репо на гитхабе.
Например, github.com/moira-alert/worker (слава Богу — это не зависимость).

Дык она же не прошена. Там честно написано, что куда переехало.
Хватит уже набрасывать на Мойру. Что она вам такого сделала?

Роман, да все уже, проехали (у меня к мойре претензий нет).
Просто ссылка попалась под руку как пример.
И это прикол такой — комменты месячной давности поднимать?

В большой системе вероятность поломки в любой произвольно взятый промежуток времени стремится к единице. Расскажите, что происходит во время поломанного HEAD? Каковы реакции со стороны системы и разработчиков? Сколько времени уходит в среднем на восстановление работоспособности?

Не все так страшно. Прекоммитные проверки помогают ловить большую часть поломок до коммита. Прекоммитных проверок становится все больше и в самых важных местах они становятся обязательными. Это сводит кол-во крупных поломок практически к нулю.
прекоммитные — это локально, на стороне разработчика? Или я не правильно понял?
Не увеличивает ли это сильно время коммита и не потребляет ли этого много ресурсов на ноутбуках разрабов?
Запускать тесты на ноутбуке или разработческом сервере – это полезно, но при больших изменениях (рефакторинги общих библиотек и т.д.), затрагивающих много целей, локально не получится запустить все затронутые тесты. Их много. К тому же, локально разработчику не нужно иметь все исходники из-за селективного checkout'а.

Прекоммитные проверки – это процесс проверки твоих локальных изменений в CI системе. Прекоммитные проверки позволяют понять что будет если закоммитить изменения прямо сейчас. Твои изменения в виде патча/diff'а отправляются в CI систему, далее CI система определяет затронутые цели и осуществляет сборку, запуск тестов и т.д. Патч накладывается на HEAD.

А большое количество предкоммитных проверок не затягивают время коммита? Я так понимаю, что на время предкоммитной проверки репозиторий блокируется?

Репозиторий не блокируется во время проверок. Мержить все изменения по очереди, каждый раз заново проверяя поверх HEAD, при большом кол-ве проверок невозможно. Суммарное время выполнения всех проверок за день во много раз превышает длительность суток.

Продолжу мысль. Есть вероятность поломки тестов в репозитории после коммита, потому что проверка осуществляется поверх одного коммита из trunk, а коммит – спустя некоторое время. Но при осуществлении коммита после успешной прекоммитной проверки вероятность поломки стремится к нулю.
Не очень тогда понятно, как разрешаются конфликты, если я и мой сосед исправляем один и тот-же файл и коммитим одновременно.
Как и во всех популярных системах контроля исходного кода. Редактирование одного и того же файла еще не гарантирует конфликт. Если все же конфликт случается, то 2-й коммит не пройдет и разработчик должен разрешить конфликт прежде можно будет коммитить.

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

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

Возможно я упустил, но код попадает в основою ветку без ревью? И оно делается постфактум?

Большие/значимые изменения — через ревью. Требования к тому что и как следует ревьюить зависят от команды/проекта.

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

Спасибо за статью. Интересно было бы узнать, как QA занимающиеся ручным тестированием вписываются в данный процесс. Еще не очень понятно как организуются зависимости между проектами. Допускается ли между ними прямая связь на уровне исходного кода? Как часто можно делать релизы при такой схеме? Спасает ли ревью и тесты от попадания багов в релиз?
Интересно было бы узнать, как QA занимающиеся ручным тестированием вписываются в данный процесс.

С описанными выше процессами наша система управления ручным тестированием сейчас не интегрирована. Но все впереди.

Еще не очень понятно как организуются зависимости между проектами. Допускается ли между ними прямая связь на уровне исходного кода?

Зависимости между проектами по исходному коду.

Как часто можно делать релизы при такой схеме?

Зависит от сложности проекта, времени выполнения тестов, наличия ручного тестирования. Несколько раз в неделю для самых сложных проектов — вполне достижимо. Про один из наших проектов рассказывали на мероприятии Яндекс изнутри: умные технологии в рекламе. Для более простых проектов — так часто как хочется, хоть покоммитно.

Спасает ли ревью и тесты от попадания багов в релиз?

100% гарантию никто не даст.

Ещё интересно, как делать завивмость на определенную версию библиотеки?
Как релизить проекты независимо?

А зачем релизить проекты независимо?
Вот есть у Вас какой-нибудь условный Слак или Gmail. И у него, как коробочного продукта, нет различных версий. Только «последняя». Ну, может с какими-то встроенными feature toggle и функциональностью A/B тестов, чтобы проверять гипотезы.

Ну вот допустим пишу я слак и либу для него. У тебя новая версия ещё не закончена, но уже влита. А вот слак пора срочно хотфиксить. Что делать? Релизить сразу с новой либой, даже если ещё не доделана?

ниже amkruglov ответил.
Если декомпозиция именно такая, как я понял, то не должно быть ситуации, когда либа не доделана и вмержена. Т.е. сначала новый протестированный функционал в либе, и потом уже изменения следом в 'слак'. Либо если текущий слак сломался и нужен хот-фикс, то делаешь хот-фикс в транке…

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

То есть все сервисы обязаны одновременно перейти на новую версию библиотеки, даже если нарушена совместимость? Как достигаете этого? Сколько времени это занимает обычно после подготовки самой либы?

Обсуждали в этом треде. В некоторых случаях все происходит быстро, иногда — сложно и долго. Зависит от того какая это библиотека – внутренняя или внешняя open source библиотека.
Интересные процессы.
Скажите а занимаются ли SDET поддержкой тестовых стендов?
Имею ввиду:
— организацию доставки нового кода на тестовый стенд;
— решением интеграционных проблем на тестовых стендах;
— обновление тестовых данных на cерверах;
— собственно написание ansible скриптов для разворачивания этих серверов.

Или же автоматизаторы занимаются только написанием автотестов?

Разработчики автотестов у нас есть. Но у нас все стремится к тому чтобы разработчики сами писали тесты. И мы делаем все возможное чтобы упростить им жизнь. Но тут тоже все зависит от конкретной команды. Я пишу про общий тренд.


Про деплой.


  • Первый этап – пакетирование. Для этого у нас есть стандартное решение. Особый файл json описывает какие артефакты (цели в терминах системы сборки, файлы из репозитория, артефакты из хранилища ресурсов) и как нужно скомпоновать в один пакет (tarball, debian).
  • Собрать пакет можно локально, но скорее в тестовых целях. Обычно собирают в распределённой системе выполнения задач общего назначения – так надежнее, т.к. там правильное и безопасное окружение.
  • Далее сам деплой. Сейчас есть выбор из нескольких способов деплоя (различные системы деплоя, куда деплоить).

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

Алексей к сожалению не ответили на вопрос.
Понял что разработчики пишут автотесты сами, хорошо. Разработчики занимаются devops делами или этим заняты соответственно отдельные люди (организацией тестовой среды, настройками интеграции и тд)?
У всех по разному. Где-то есть выделенные команды devops, так часто бывает в крупных проектах. В других командах разработчики могут отвечать за все процессы. Поэтому мы много инвестируем в общие инструменты.
Столько букв. Можно было написать одним предложением: и это мы тоже передрали у Гугла. И дать ссылки на их лекции об использовании единого репозитория, транк-бейс разработке, непрерывном тестировании и т.д. датированные где-то 2011-2012 годом.
А вы gerrit не используете? Мне кажется, это самый стабильный метод жизни в больших проектах с разной компетенций участников.

Основная идея, что в мастер мержит только робот и только после а) успешного прохода CI (можно больше одной штуки) б) +2 на code review.
Не используем. Но у нас также есть авто-merge с возможностью настройки требований (наличие ship it, успешные сборки, тесты, тяжелые тесты).
Т.е. в мастер у вас мержится человеком, т.е. человек определяет исполнение workflow. Моя devops часть души говорит, что workflow человеков плохой и стохастический. Must obe4 bots.

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

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

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

Здесь я отвечал про прекоммитные проверки. Для посткоммитных проверок это тоже актуально.
Опубликовали продолжение: habr.com/company/yandex/blog/429956

Там рассказываем про устройство системы непрерывной интеграции в Яндексе.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий