请指定您要合并哪一个分支_Jenkins CI: 多分支构建

jenkins 允许用户开发插件,扩展功能,因此你可以在社区找到丰富的插件,但是插件质量参差不齐,想让多个插件协作,需要非常复杂的配置。

现代的 CI/CD 如 gitlab CI、 travis CI 均摒弃了这样的插件思路

比如,一个普遍遇到的问题就是,如何支持构建不同的分支?这几乎大部分 CI 支持、用户以为理所当然的功能,在 jenkins 里是件比较麻烦的事情

前提

除非是非常简单的项目,大多数项目会使用 jenkins pipeline 来计划构建、部署任务

有两个方式定义 Pipeline

  1. 直接写在 web ui 项目配置里
  2. 提交到 SCM,在项目配置中指定其位置

复杂一点的 Pipeline 会采用第二种方式,因为可以帮助我们追踪 Pipeline 的变更。 但是这会引发我们今天要讨论的问题:

问题:Pipeline 过早初始化

采用 Pipeline from SCM 的项目,随便打开任意构建 console output,会看到类似这样的日志:

baa9454229b39b6e388244e1885cae5c.png

我们可以看到,Pipeline 是在拉取代码之前就被确定、初始化的。

而 Pipeline 是存放在 SCN(代码仓库)里, 因此我们需要在配置里面指定拉取的分支:

89771a367530c853fd6d8e9613c9004f.png

如果我们想要构建不同的分支,不同分支上的 Pipeline 有些不一样,怎么办?

解决方法 #1:环境变量

我们可以用参数化构建中的环境变量代替手写的分支名:

2008ae5123bde0eadf1cda341bca7cad.png
BRANCH 是参数化构建中的一个参数

CI/CD ?

问题似乎解决了,但是我们不可能每次构建都要打开 jenkins 手动点击触发,这样就不叫 CI/CD 了。我们要支持 trigger,比如 gitlab hook,由 git push 触发构建任务

你需要安装 gitlab-plugin

这样,分支可能来自 trigger 注入的环境变量,可能来自参数化构建的参数。

很容易想到,我们可以使用同样的名字来隐藏两者的区别,比如 gitlab hook 注入的变量 gitlabBranch,那我们也以同样的名字作为参数化构建中的一个参数名

a662d3b60dfc9b26c720862f5581d683.png

因此,不管 gitlabBranch 是来自哪里,我们的 Pipeline 文件都是最新的。

如果需要更复杂的逻辑,而不是简单的”合并“,也许你需要 EnvInject 插件

解决方案 #2:动态加载 Pipeline

问题的本质在于 Pipeline 是在拉取代码之前被确定的,那么,我们可不可以反过来,在拉取代码之后再去「初始化 Pipeline」,像其他 CI 那样?

利用 load API,我们可以做到这一点。

load 可以动态加载一个 Groovy 文件(假设名为 Main.groovy),我们可以把主要的任务逻辑放在 Main.groovy.

而我们的 Pipeline 文件只是一个启动入口,本身不定义任务,只做一件事情——git checkout,之后就加载 Main.groovy。 如下:

deploy/
├── Jenkinsfile
└── Main.groovy
  // Jenkinsfile

  // 1. checkout
  def repo = checkout([$class                           : 'GitSCM',
                       branches                         : [[name: "${gitlabBranch}"]],
                       doGenerateSubmoduleConfigurations: false,
                       extensions                       : [],
                       gitTool                          : 'Default',
                       submoduleCfg                     : [],
                       userRemoteConfigs                : scm.userRemoteConfigs
  ])

  // 2. load main pipeline
  load "deploy/Main.groovy"
由于 Main.groovy 永远是当前分支的,所以整个 Pipeline 也是当前分支的,除非 Jenkinsfile 发生变更

为什么不使用 Multibranch Pipeline

Multibranch Pipeline 为项目的每一个分支单独创建一个对应的 job,看起来不错,但是这种方式不支持 tag pushmerge request 等。 在实际工作中,也很少看到项目使用这样的方式。

总结

大家可以看到仅仅是多分支,jenkins 就需要你花时间去 google,阅读各种不同风格的 plugin 文档,学习 groovy API,不断尝试。

虽然这篇是关于 Jenkins Pipeline,但是我不推荐使用 jenkins,除非像我一样万不得已(团队内部原因)

如果公司代码托管使用的是 gitlab,明显可以选择 gitlab ci。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值