我正在尝试为Jenkins构建服务器创建一个新的项目配置。为了简化我正在尝试做的事情,我将仅使用两个组件来描述问题。
ComponentA
以componentB
在Jenkins上实现这一目标的正确方法是什么?我试图找出如何添加解析配置文件的动态行为,并使Git插件根据ComponentB的预期版本检出分支,但到目前为止我没有任何线索。
在下一步中,我甚至可能希望在配置文件中使用通配符(如5.3。*),因此我必须找到与通配符匹配的最新ComponentB标记。
修改
现在我看到我过多地简化了我的问题,并且由于简化,主要限制不再存在。
主要限制是组件A和B必须一起构建。由于它们形成一个可执行文件/库而构建脚本需要来自两个组件的源文件,因此无法单独构建它们。
如果你问为什么这么奇怪的配置,让我们给组件A和B一些描述:
可能有许多组件为 - 每个平台一个,但只有一个组件B.将特定A与B合并为单个平台生成完整的源代码但不是每个平台都可以更新到最新版本的B,因此它需要控制哪个版本的B应该用于构建。
答案 0 :(得分:18)
实现目标的一个选择是使用以下设置:
创建两个Jenkins作业:
为“组件B”定义branch
build parameter:
将此参数用作“Git插件”分支说明符:
现在,您应该能够通过为其指定适当的分支(标记)参数来手动触发“组件B”构建,例如, tags/5.3.0
。
向“Component A”构建添加一个新的“Execute Shell”构建步骤,该构建将从工作区中的配置文件中提取“Component B”版本,并使用“Component B”准备b.properties
文件“建立参数。
安装Parameterized Trigger 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
这将在远程“组件B”存储库中列出匹配“B”版本模式的所有标记,并将最新版本号保存在LATEST
变量中。
将此添加到“组件A”作业的“执行Shell”步骤,
它应该能够处理版本号模式,如:5.3.*
问题是shell脚本将作为Jenkins守护程序用户运行, 因此必须配置适当的凭据才能访问远程Git存储库(例如通过ssh pubkey)。
或者,您可能需要查看Credentials Binding Plugin,以重用存储在Jenkins中的Git凭据。
您还可以使用Jenkins 2.0样式的Pipeline来解决手头的任务,这将允许您将组件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
}
}
这里我们使用“readProperties”命令,它是Pipeline Utility Steps Plugin的一部分,用于从meta.properties
中提取“Component B”版本模式。还有readYaml,readJSON命令可用。
接下来,我们使用changelog: false, poll: false
标志获取/克隆“Component B”,以防止它被注册为SCM轮询,进入当前工作空间的“module / b”文件夹。
然后根据我们上面获得的版本模式调用一个shell命令来选择标签,然后结帐(5.3。*样式通配符也应该有效)。
sh
调用包含在sshagent中,以使其重用相应的内容
来自Jenkins凭证商店的凭证。
答案 1 :(得分:2)
使用Credentials Binding Plugin对我来说效果很好(@zeppelin也提到过)
Add Credentials
类型:“用户名密码”。这应该是使用 HTTPS 协议的组件B存储库git服务器的用户名和密码(SSH选项不适用于此目的)Git
部分所有必填字段(存储库,分支等)下的常规源代码管理中)。
Check out to a sub-directory
并写入:component_a
Build when a change is pushed to GitHub
在构建环境部分,勾选Use secret text(s) or file(s)
Variable
某个名称:MY_CRED Credentials
中选择您在步骤1中创建的特定凭据。现在使用执行shell 代码中的MY_CRED
,您将可以访问组件B存储库:
DIR="component_b"
if [ "$(ls -A $DIR/.git)" ]; then
cd $DIR
git fetch
else
git clone https://$MY_CRED@github.com/proj/component_b.git $DIR
cd $DIR
fi
git show
git clone 'https://****@github.com/proj/component_b.git' component_b
从组件A解析配置以获取所需的标记:TAG=$(cat ./component_a/config.cfg | grep ... | sed ...)
cd component_b; git checkout -f $TAG
-f
强制标记。答案 2 :(得分:1)
1 - 将项目B
添加为项目A
的子仓库是否可能成为解决方案?
2-(如果真的要避免包含B的完整源代码):将B的构建推送到某个B_builds
repo,并将此repo添加为A
的子仓库一种可能的解决方案?
基本原理:使A
和B
之间的依赖关系更加明确的一种方法是在存储库的依赖项中表示它。
这需要在管理A
项目时添加额外的步骤:
update `B` sub repo in `A` project, and push this to `A`
每次为B
生成新版本。
但是,您可以从A
清楚地了解B
的版本何时被整合(例如:&#34;我们仅从{{{}开始使用B 2.0.1
1}}&#34;),推送到A 4.3.2
会触发你常用的Jenkins流程。