【问题标题】:GitHub Cloud Build Integration with multiple cloudbuild.yamls in monorepoGitHub Cloud Build 与 monorepo 中的多个 cloudbuild.yamls 集成
【发布时间】:2025-11-29 08:15:01
【问题描述】:

如果 cloudbuild.yamlDockerfile 不在存储库的根目录中,GitHub 的 Google Cloud Build integration 不会检测到。

当使用包含多个 cloudbuild.yamls 的 monorepo 时,如何配置 GitHub 的 Google Cloud Build 集成以检测正确的 cloudbuild.yaml

文件路径:

services/api/cloudbuild.yaml
services/nginx/cloudbuild.yaml
services/websocket/cloudbuild.yaml

Cloud Build 集成输出:

【问题讨论】:

    标签: google-cloud-platform monorepo google-cloud-build


    【解决方案1】:

    您可以通过一个gcr.io/cloud-builders/gcloud 步骤在存储库的根目录中添加cloudbuild.yaml 来做到这一点。这一步应该:

    1. 遍历每个子目录或使用find 查找其他cloudbuild.yaml 文件。
    2. 对于每个找到的 cloudbuild.yaml,通过运行 gcloud builds submit 派生并提交构建。
    3. 等待所有分叉的gcloud 命令完成。

    the root cloudbuild.yaml 中的the GoogleCloudPlatform/cloud-builders-community repo 中有一个很好的示例。

    如果我们去掉不重要的部分,基本上你有这样的东西:

    steps:
    - name: 'gcr.io/cloud-builders/gcloud'
      entrypoint: 'bash'
      args:
      - '-c'
      - |
        for d in */; do
          config="${d}cloudbuild.yaml"
          if [[ ! -f "${config}" ]]; then
            continue
          fi
    
          echo "Building $d ... "
          (
            gcloud builds submit $d --config=${config}
          ) &
        done
        wait
    

    【讨论】:

    • 顺便说一下这个解决方案的功劳归于@philippe-modard。
    • 感谢您的解决方案 Rohan,很高兴得到答复!很遗憾,本机不支持此功能,希望此线程将使 cloudbuild 开发人员考虑支持此用例。
    • 如果我们像我们一样使用 monorepo 但在 /website/web/src 中只有 1 个 cloudbuild.yaml 文件,你会怎么做 - 我们的触发器设置为该目标,但是当我们运行,好像找不到那个文件夹(比如找不到package.json)
    • 每次对任何项目进行提交时,这是否会构建 repo 中的每个项目,或者它是否足够聪明地识别提交是否不适用于该子目录?
    • 它构建了一切。
    【解决方案2】:

    我们现在正在迁移到单一存储库,我还没有找到任何可以很好地处理这个问题的 CI/CD 解决方案。

    关键是不仅要检测更改,还要检测依赖于该更改的任何服务。这是我们正在做的事情:

    • 要求每个服务都有一个带有构建命令的 MAKEFILE。
    • 将 cloudbuild.yaml 放在 mono repo 的根目录
    • 然后我们使用这个小工具(旧但似乎仍然可以使用)https://github.com/jharlap/affected 运行自定义构建步骤,其中列出了所有已更改的包以及依赖于这些包的所有包等。
    • 然后shell 脚本将在受更改影响的任何服务上运行make build

    到目前为止,它运行良好,但我完全理解这是否不适合您的工作流程。

    许多人使用的另一个选项是 Bazel。不是最简单的工具,但如果您有多种不同的语言或跨单存储库构建流程,则尤其有用。

    【讨论】:

    • 老实说,我认为您的做法是正确的。另一种方式(在 Google Cloud Build 中定义了多个触发器和过滤器)的可移植性较差。我更喜欢在 monorepo 本身内触发构建的所有逻辑。
    • 是的,如果您使用 monorepo,您​​还应该使用与 monorepo 兼容的构建工具,例如 Bazel。 monorepo 的目的是更改可能会影响多个应用程序,因此它需要在编写时知道依赖关系 - 只有像 Bazel 这样的工具才能这样做。
    【解决方案3】:

    您可以为您的存储库创建一个build trigger。使用cloudbuild.yaml 为构建配置设置触发器时,您需要提供存储库中cloudbuild.yaml 的路径。

    【讨论】:

    • GitHub 插件的重点是自动检测cloudbuild.yaml 文件,因此无需手动创建构建触发器。