Привет! Мы GrandCore Foundation. Создаём идеальную организацию для  развития свободных проектов: ПО, этичных онлайн-сервисов и стандартов  изделий. Подробнее читайте здесь. Присоединяйтесь к нашему чату в Telegram. Всегда рады единомышленникам! Для нашего нового проекта — универсального генератора документации  у нас появилась потребность в создании монорепозитория, поскольку функционал генератора будет расширяться плагинами. Ниже читайте как мы  полностью автоматизировали данный процесс при помощи GitHub Actions и Lerna. Монорепозиторий — это совокупность множества проектов в одном репозитории.  Преимущества: Нет необходимости поддерживать огромное количество репозиториев отдельно; Возможность отслеживания и редактирования кода во всем проекте каждой отдельной командной; Атомарные коммиты. Проблемы: Увеличение объема данных; Возможная проблема с версионированием каждого подпроекта; Уменьшение ответственности каждой команды, которая работает над подпроектами репозитория. В качестве основного инструмента работы с монорепозиторием в NPM  необходимо рассматривать Lerna. Она является достаточно удобным  инструментом для работы над монорепозиториями. Lerna позволяет решить  множество возникающих при работе проблем. Возможности: Сквозное версионирование; Индивидуальное версионирование каждого подпроекта; Удобная публикация всех подпроектов; Автоматическое управление зависимостями между подпроектами; Работа с Yarn или NPM. Для  демонстрации исходных настроек Lerna мы создадим проект по умолчанию, а  далее продемонстрируем вариант, который мы реализовали в нашем проекте. Установите Lerna глобально: Инициализируйте проект: После этого в корне проекта создаестся директория packages/, файл package.json и файл lerna.json.  Содержимое lerna.json: Сначала указывается  директория со всеми вложенными проектами (директорий может быть  несколько). Далее указывается версия монорепозитория (для сквозного  версионирования данное значение совпадает во всех подпроектах).  Cоздание нового пакета (подпроекта): После ввода данной команды в директории packges/  (по умолчанию) создается новый каталог с именем, которое указывается в  качестве параметра. Далее необходимо ответить на несколько стандартных  вопросов от Lerna. Важно отметить, что для всех пакетов желательно  использовать названия следующего типа @project_name/pkg_name.  Таким образом можно привязать все пакеты, которые разрабатываются  внутри репозитория, к одному монорепозиторию или одной организации.  Допустим, что мы создали новый пакет. Тогда в директории с этим пакетом создается файл package.json. Чтобы данный пакет в дальнейшем был доступен публично и корректно публиковался, необходимо добавить в данный файл: Естественно, подпроекты можно создавать и вручную. Публикация изменённых проектов: Возможные проблемы: Не авторизованы в NPM; Забыли добавить публичный доступ в package.json пакета; Занятое или некорректное название одного из пакетов. Важные замечания: Публикация возможна только после коммита при использовании данной команды в таком виде; По умолчанию задается сквозная версия для всех пакетов. Рекомендуем почитать в документации Lerna о дополнительных параметрах данной команды. Если вы хотите использовать собственную структуру проекта, то вы можете её изменить. В качестве примера рассмотрим наш проект универсального генератора документации.  Мы  решили оставить в основном модуле только функционал менеджера потока, а  также markdown финализатор, совместимый с основными генераторами  статических сайтов. Для того, что бы обрабатывать сами файлы с  документацией, необходимо подключить соответствующие плагины. Наш файл lerna.json: В нашем проекте все плагины находятся в каталоге plugins/, а основной модуль в папке main/. Таким образом структура нашего проекта представляет из себя следующий вид: Поговорим  теперь о взаимодействиях между разными частями проекта. Очевидно, что в  монорепозитории каждый подпроект может как-то зависеть от других.  Возникает проблема зависимостей между подпроектами. Кроме того, не очень  удобно устанавливать зависимости отдельно для каждого подпроекта. Lerna  умеет решать данные проблемы. Установка зависимостей: При выполнении данной команды Lerna анализирует все подпроекты и выполняет npm install в каждом из них. Если в зависимостях одного локального модуля (подпроекта) B находится другой A, то Lerna создает символическую ссылку в папке node_modules/ подпроекта B на подпроект A. Таким образом не происходит лишних копирований файлов в node_modules/. Работая с монорепозитоием, мы должны выполнять данную команду вместо установки зависимостей в каждом подпроекте.  Рекомендуем почитать в документации Lerna о дополнительных параметрах данной команды. Мы  создали монорепозиторий, даже смогли опубликовать его в NPM, но теперь  возникает вопрос: "Как можно автоматически отправлять изменения в NPM?".  Для решения такой задачи можно использовать GitHub Actions.  Создадим в корне проекта папку .github/workflows/, а в ней файл main.yml (название может быть любое). Рассмотрим на нашем примере.  Содержание нашего yml файла: Что тут происходит: В качестве тригера запуска установлен коммит или пулл реквест в мастер; Операционной системой выбирается Ubuntu; Далее в склонированном репозитории выполняется установка npm-пакетов; После этого добавляем пользователя NPM. Для этого необхдоимо создать секрет в проекте с npm-токеном. В нашем проекте токен содержится в секрете NPMTOKEN.  Выполняем публикацию с помощью соответствующей команды lerna publish from-package --yes. В нашем случае, мы обновляем только те пакеты, которым мы поменяли вручную версию в их файлах package.json. Отслеживать ход выполнения можно во вкладке Actions в вашем репозитории. Будем рады выслушать ваши замечания в комментариях.  Если читателя заинтересуют наши Open Source проекты, будем рады видеть в нашем чате.