如何动态选择要在Jenkins构建中使用的git分支

Lad*_*nka 26 git continuous-integration build jenkins

我正在尝试为Jenkins构建服务器创建一个新的项目配置.为了简化我正在尝试做的事情,我将仅使用两个组件来描述问题.

ComponentA

  • 此组件中的更改会触发在CI服务器上构建此项目.
  • CI服务器具有静态配置的分支以监视更改和构建.例如.掌握或发展分支.
  • 该组件包含一个配置文件,其中包含所需的ComponentB版本.

以componentB

  • 对此组件的更改不会触发在CI服务器上构建此项目(将有另一个项目来涵盖ComponentB的开发).
  • 各个版本的组件都已标记
  • ComponentA在其配置文件中需要ComponentB版本
  • 在以某种方式解析ComponentA的配置文件之前,CI服务器不知道要检出的分支(标记).

在詹金斯实现这一目标的正确方法是什么?我试图找出如何添加解析配置文件的动态行为,并使Git插件根据Co​​mponentB的预期版本检出分支,但到目前为止我没有任何线索.

在下一步中,我甚至可能希望在配置文件中使用通配符(如5.3.*),因此我必须找到与通配符匹配的最新ComponentB标记.

编辑

现在我看到我过多地简化了我的问题,并且由于简化,主要限制不再存在.

主要限制是组件A和B必须一起构建.由于它们形成一个可执行文件/库而构建脚本需要来自两个组件的源文件,因此无法单独构建它们.

如果你问为什么这么奇怪的配置,让我们给组件A和B一些描述:

  • ComponentA:特定于本机平台的代码
  • ComponentB:与本机平台无关的代码

可能有许多组件为 - 每个平台一个,但只有一个组件B.将特定A与B合并为单个平台生成完整的源代码,但并非每个平台都可以更新到最新版本的B,因此需要对其进行控制哪个版本的B应该用于构建.

zep*_*lin 21

实现您想要的一个选项是使用以下设置:

创建两个Jenkins作业:

  • "组件A"(在SCM更改时自动触发)
  • "组件B"("手动"触发)

步骤1

定义"Component B" 的branch 构建参数:

在此输入图像描述

使用此参数作为"Git插件"分支说明符:

在此输入图像描述

现在,您应该能够通过为其指定适当的分支(标记)参数来手动触发"组件B"构建,例如tags/5.3.0.

第2步

将新的"Execute Shell"构建步骤添加到"Component A"构建中,该构建将从工作区中的配置文件中提取"Component B"版本,并b.properties使用"Component B"构建参数准备文件.

在此输入图像描述

安装参数化触发器 Jenkins插件,并在"组件A"作业中添加一个新的"触发/调用构建在其他项目上"构建步骤:

在此输入图像描述

使用您的b.properties文件作为构建参数的来源.

现在每次重新构建"组件A"时,将触发新的"组件B"构建,目标分支/标记作为构建参数.

添加通配符支持

如果要支持通配符版本,可以使用git ls-remote命令查找最新标记,如下所示:

#B=$(obtain B version from the config file in a usual way)   

LATEST=$(\
    git ls-remote --tags YOUR_REPOSITORY_URL "$B"\
    |cut -d / -f3|sort -r --version-sort|head -1\
)

cat <<EOF > b.properties
    branch=tags/$LATEST
EOF
Run Code Online (Sandbox Code Playgroud)

这将在远程"组件B"存储库中列出匹配"B"版本模式的所有标记,并将最新版本号保存在LATEST变量中.

将其添加到"组件A"作业的"执行Shell"步骤中,它应该能够处理版本号模式,如: 5.3.*

问题是shell脚本将作为Jenkins守护程序用户运行,因此必须配置适当的凭据才能访问远程Git存储库(例如,通过ssh pubkey).

或者,您可能需要查看凭据绑定插件,以重用存储在Jenkins本身中的Git凭据.

使用Jenkins 2.0样式管道

您还可以使用Jenkins 2.0样式的管道来解决手头的任务,该管道允许您将组件A和B的代码签出到单个工作区中,然后对它们应用一些常见的构建步骤.

你的管道看起来像这样:

node {

   //Settings
   def credentialsId = '8fd28e34-b04e-4bc5-874a-87f4c0e05a03'    
   def repositoryA = 'ssh://git@stash.com/projects/a.git'
   def repositoryB = 'ssh://git@stash.com/projects/b.git'

   stage('Checkout component A') {
      git credentialsId: credentialsId , 
      url: repositoryA , branch : "master"
   }

   stage("Resolve and checkout component B") {
      def deps = readProperties file: 'meta.properties'
      echo "Resolved B version = ${deps['b']}"

      dir("module/b") {
           //Clone/Fetch Component B 
           checkout scm:[
                $class: 'GitSCM', 
                userRemoteConfigs: [[url: repositoryB, credentialsId: credentialsId]], 
                branches: [[name: 'refs/tags/*']]
           ], 
           changelog: false, poll: false

           //Checkout the tag, matching deps['b'] pattern     
           sshagent([credentialsId]) {
                sh "git checkout \$(git tag -l \"${deps['b']}\" |sort -r --version-sort|head -1)"
           }
      }
   }

   stage("Build A+B") {
        //Apply a common build step
   }

}
Run Code Online (Sandbox Code Playgroud)

这里我们使用"readProperties"命令,它是Pipeline Utility Steps插件的一部分,用于从中提取"Component B"版本模式meta.properties.还有readYaml,readJSON命令可用.

接下来,我们使用changelog: false, poll: false标志来获取/克隆"Component B",以防止它被注册用于SCM轮询,进入当前工作空间的"module/b"文件夹.

然后根据我们上面获得的版本模式调用一个shell命令来选择标签,然后结帐(5.3.*样式通配符也应该有效).

sh调用,被包裹在sshagent,使其重用从詹金斯凭据存储相应的凭据.