Условное облако строит множество пакетов в Monorepo - PullRequest
0 голосов
/ 07 ноября 2019

Мотив

Я хочу полностью автоматизировать развертывание многих сервисов с помощью Google Cloud Build и Google Kubernetes Engine . Эти сервисы расположены внутри monorepo , в котором есть папка с именем services.

. Поэтому я создал cloudbuild.yaml для каждого сервиса и создал триггер сборки. cloudbuild.yaml выполняет:

  1. запуск тестов
  2. сборка новой версии образа Docker
  3. push новый образ Docker
  4. применение изменений к кластеру Kubernetes

Проблема

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

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

Пример

Предположим, у меня есть монорепо с такой файловой структурой:

├── packages
│   ├── enums
│   ├── components
└── services
    ├── backend
    ├── frontend
    ├── admin-dashboard

Затем я внесу некоторые изменения в сервис frontend. Поскольку службы frontend и admin-dashboard зависят от пакета components, необходимо перестроить несколько служб:

  • frontend
  • admin-dashboard

Но не бэкэнд!

То, что я попробовал

(1) Несколько триггеров сборки

Настройка нескольких триггеров сборки для каждый сервис. Но 80% этих сборок являются избыточными, поскольку большинство изменений в коде относятся только к отдельным сервисам. Также становится все сложнее управлять многими триггерами сборки, которые выглядят почти одинаково. Один файл cloudbuild.yaml выглядит следующим образом:

steps:
  - name: "gcr.io/cloud-builders/docker"
    args:
      [
        "build",
        "-f",
        "./services/frontend/prod.Dockerfile",
        "-t",
        "gcr.io/$PROJECT_ID/frontend:$REVISION_ID",
        "-t",
        "gcr.io/$PROJECT_ID/frontend:latest",
        ".",
      ]
  - name: "gcr.io/cloud-builders/docker"
    args: ["push", "gcr.io/$PROJECT_ID/frontend"]

  - name: "gcr.io/cloud-builders/kubectl"
    args: ["apply", "-f", "kubernetes/gcp/frontend.yaml"]
    env:
      - "CLOUDSDK_COMPUTE_ZONE=europe-west3-a"
      - "CLOUDSDK_CONTAINER_CLUSTER=cents-ideas"

(2) Цикл по файлам облачной сборки

Этот вопрос касается очень похожей проблемы. Поэтому я попытался установить один файл "1072 *" "точки входа" в корне проекта и перебрал все службы:

steps:
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    for d in ./services/*/; do
      config="${d}cloudbuild.yaml"
      if [[ ! -f "${config}" ]]; then
        continue
      fi

      echo "Building $d ... "
      (
        gcloud builds submit $d --config=${config}
      ) &
    done
    wait

Это избавило бы от необходимости иметь несколько триггеров сборки. Но я также столкнулся с проблемами при использовании этого метода:

Каждый сервис отправляется в свой собственный процесс сборки с областью файлов этого конкретного сервиса. Это означает, что я могу получить доступ только к файлам внутри /services/specific-service во время сборки. Для меня это полный облом (мне нужен доступ к файлам в родительских каталогах, таких как packages и файлам конфигурации в корне).

(3) Сборка только измененных сервисов

Так как я хочумеханизм для создания только измененных сервисов, я попытался определить сервисы, которые нужно перестроить. Кажется, это довольно легко сделать с помощью lerna . Запуск

lerna changed --all --parseable

вернет пути файла списка к измененным пакетам следующим образом:

/home/username/Desktop/project/packages/components
/home/username/Desktop/project/services/frontend
/home/username/Desktop/project/services/admin-dashboard

Однако список также включает packages, и я понятия не имею, как бы я былвозможность использовать этот список в скрипте для циклического обхода уязвимых сервисов. Также: когда я запускаю сборку (например, с помощью пометки коммита), lerna не сможет распознать измененные пакеты во время процесса сборки, так как изменения уже зафиксированы.


Я знаю, что этодлинный. Но я думаю, что это важная тема, поэтому я очень ценю любую помощь!

PS: Этот выглядит так, как выглядит мой настоящий проект, если вы хотите более внимательно изучить конкретный вариант использования.

1 Ответ

1 голос
/ 07 ноября 2019

Чтобы построить из monorepo , вы действительно хотите строить постепенно (что изменилось и детали, которые зависят от измененных деталей). Чтобы достичь этого, ваш инструмент сборки должен каким-то образом обрабатывать граф зависимостей.

Lerna, который вы описываете, предназначен для монорепозиций. Но это также относится к Bazel и доступно в качестве опции в Google Cloud Builder, cloud-builders / bazel с документацией для использования в сочетании с Docker Builder.

Тем не менее, инструменты сборки, разработанные для monorepos, обычно более сложны в настройке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...