分布式团队使用Monorepo的Git-based CI/CD流程

156次阅读
没有评论

问题描述

想要了解在使用Monorepo的项目中,是否有已经建立的CI/CD策略和最佳实践。用户提供了两个具体的用例:1. 在内容分发中,例如每日/每周的HTML电子邮件通讯;2. 用于构建LaTeX文档的多项目目录。这两种情况都将使用相同的CI/CD流程(构建/发送电子邮件,编译和上传LaTeX文档),但内容的增长和变化使得每个文档都有独立的仓库不可取。大多数使用Monorepo的项目似乎都是JavaScript项目,存在很多代码的交叉依赖。这是一个与之不同的步骤,但我仍然希望在自动化的开发过程中充分利用版本控制的审计跟踪来生成内容。这些项目是否在每次更改时都编译所有代码?是否有一种方法可以利用git diff或在仓库根目录中使用某种“标志”文件来使用Monorepo的CI/CD工具?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

首先,尽管所有代码都在一个仓库中,并不意味着每次提交都会更改所有代码。我们可以首先明确代码中的“路径”。例如,您可以有几个子目录:

- App1/
  - Docs/
  - Code/
  - Tests/
  - Makefile
- App2/
  - Docs/
  - Code/
  - Tests/
  - Makefile

假设App1与App2是相互独立的,您可以通过检查该目录中是否有任何更改来触发构建。大多数持续集成工具都有一个git插件或本地功能,允许您根据路径进行过滤。如果您使用Jenkins,您可以设置几个作业,每个作业的包含区域都是应该触发的路径,例如,对App1/*的更改将触发jobs/app1/,该作业执行make -f App1/Makefile或类似的操作。因此,维护这个项目的关键在于Makefile或您选择的其他构建工具,您可以在其中编写依赖关系。您还可以使用单个全局Makefile,并使用上面提到的git diff-tree技巧:

if grep -q App1 `git diff-tree --no-commit-id --name-only -r <commit>` ; then
  # trigger pipeline App1
  cd App1
  make build
  make test
  make publish
fi

方案2

我创建了一个使用Gradle作为构建工具和CircleCI或Bitbucket Pipelines作为CI工具的Monorepo演示项目。它基于接受的答案中的相同思想,我在两个项目中使用了类似的设置。具体请参考:https://github.com/zladovan/monorepo。Gradle特定的内容应该很容易被其他工具替换。只需更改tools/ci/core/list-dependencies.sh即可。

评论

  1. 如果您更改了根目录中的文件,例如.gitlab-ci文件,将不会触发构建,因为在App*中没有文件更改。
  2. 当然,构建触发逻辑必须适应您的用例。
  3. 这个解决方案忽略了库的事实,如果您构建库A,还必须构建依赖于A的服务C和D。(我自己正在尝试弄清楚这个问题,之前在Twitter工作过,他们有这个功能,但他们使用了Pants构建系统,而Pants有点糟糕…速度很慢)

正文完