多分支流水线
https://jenkins.io/zh/doc/tutorials/build-a-multibranch-pipeline-project/
多分支流水线项目是 Jenkins 的一种功能,可以为代码仓库中的每个分支自动创建单独的流水线,并根据分支执行相应的构建和部署。
多分支流水线项目的工作流程如下:
- 创建多分支流水线项目:在 Jenkins 中创建一个多分支流水线项目,并配置与源代码管理工具(如 Git)的连接。
- 自动创建流水线:当有新的分支被推送到源代码仓库时,Jenkins 会自动检测到新的分支,并为每个分支创建一个独立的流水线。
- 流水线配置:每个分支都有自己的流水线配置,可以在 Jenkinsfile 中定义不同的构建、测试和部署步骤。
- 自动触发构建:当新的提交或分支更新被检测到时,Jenkins 会自动触发相应分支的流水线构建。
- 并行构建:多分支流水线项目可以同时执行多个分支的构建,以提高整体构建效率。
- 状态和日志记录:Jenkins 会记录每个分支的构建状态、日志和结果,并提供可视化的界面来查看和监控各个分支的构建状态。
通过多分支流水线项目,您可以更好地组织和管理多个分支的构建和部署过程,使每个分支都具有独立的构建流程,并自动触发构建和部署操作。这样可以加快开发和测试过程,并提供更高的可靠性和可扩展性。
插件支持
我们简化一下流程,假如使用develop分支作为开发分支,master分支作为集成测试分支,看一下如何使用多分支流水线来管理。
插件支持

git仓库分支创建
# 创建分支且推到远程
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (master)
$ git checkout -b dev
Switched to a new branch 'dev'
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$ git branch
* dev
master
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$ git push origin -u dev
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for dev, visit:
remote: http://gitlab.yuchaoit.cn/elamin-ops/eladmin-api/-/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote:
To http://gitlab.yuchaoit.cn/elamin-ops/eladmin-api.git
* [new branch] dev -> dev
branch 'dev' set up to track 'origin/dev'.
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$

创建多分支job
先禁用旧的pipeline
在 Jenkins 中创建多分支流水线项目的步骤如下:
- 登录到 Jenkins 管理界面。
- 点击 "New Item" 或 "创建新任务" 创建一个新的 Jenkins 项目。
- 在 "Item Name" 或 "项目名称" 输入框中给项目起一个名称,并选择 "Multibranch Pipeline" 或 "多分支流水线" 作为项目类型。
- 点击 "OK" 或 "确定" 继续创建项目。
- 在项目配置页面中,找到 "Branch Sources" 或 "分支源" 部分,选择 "Git" 或其他适用的版本控制工具。
- 在 "Repository URL" 或 "仓库 URL" 输入框中填入代码仓库的 URL。
- 增加分支源:点击 "Add Source" 或 "添加源",然后选择 "Git" 或其他适用的版本控制工具。
- 在分支源配置中,设置以下参数:
- "Discover branches" 或 "发现分支":勾选此选项,Jenkins 会自动发现新的分支。
- "Discover tags" 或 "发现标签":勾选此选项,Jenkins 会自动发现新的标签。
- "Filter by name" 或 "根据名称过滤":输入一个正则表达式,用于过滤要添加到多分支构建视图中的分支和标签。例如,使用正则表达式
develop|master|v.*可以匹配以develop、master或v开头的标签。 - "Advanced clone behaviors" 或 "高级克隆行为":在此部分可以进行更高级的克隆配置,如设置浅克隆。
- 完成分支源配置后,点击 "Save" 或 "保存" 保存项目配置。
- Jenkins 将自动检索代码仓库中所有存在 Jenkinsfile 文件的分支和标签,并将符合过滤条件的分支和标签添加到多分支构建视图中。
- 默认情况下,添加到视图中的分支和标签将会触发一次构建任务。
通过以上步骤,您可以在 Jenkins 端创建一个多分支流水线项目,并配置相应的分支源和过滤规则,以便自动检索和构建符合条件的分支和标签。

分支源

"Periodically if not otherwise run" 是 Jenkins 中用于配置定期构建任务的选项。
这个选项的含义是,如果没有其他条件触发构建任务,那么定期按照指定的时间间隔运行构建。
具体而言,您可以在 Jenkins 项目的配置中找到这个选项,并设置一个时间间隔。Jenkins 将会在每个时间间隔到达时检查是否有触发构建任务的条件,如果没有其他条件满足,则会自动运行构建。
这个选项非常适用于需要定期执行构建任务的情况,例如每天、每周或每个月都要进行构建。您可以根据自己的需求设置适当的时间间隔,确保构建任务按照期望的频率运行。
需要注意的是,如果项目已经设置了其他触发条件,例如代码提交或定时触发器,那么定期构建将在这些条件触发时被忽略。只有在没有其他触发条件满足时,定期构建才会生效。
因此,"Periodically if not otherwise run" 提供了一种默认的定期构建机制,以便在没有其他条件触发构建时,按照指定的时间间隔运行构建任务。

查看多分支job
扫描分支结果,默认自动会构建,俩分支都会构建,给取消就行。

jenkins会自动发现gitlab仓库里,有几个分支,于超老师设置的是1分钟扫描一次。

生产下的git分之,可能一个仓库有十几个分支,我们这里配置的规则就是
- jenkins会去扫描每一个分支,哪一个分支里有Jenkinsfile
- 并且名字是符合正则表达式匹配到的
- 则自动触发构建任务
Jenkins 在扫描每个分支时,会检查分支中是否存在 Jenkinsfile 文件,并且根据您配置的正则表达式来确定是否匹配。
如果分支满足以下两个条件:
- 分支中存在 Jenkinsfile 文件。
- Jenkinsfile 文件的名称与您配置的正则表达式匹配。
那么 Jenkins 将会自动触发相应的构建任务。
这种方式非常适用于管理大量分支的情况,Jenkins 可以自动识别和构建符合条件的分支,而无需手动配置每个分支的构建任务。
您只需要在 Jenkins 配置中设置好分支源和正则表达式,Jenkins 将根据这些配置自动扫描和触发构建任务。这样可以减少手动配置的工作量,并确保所有符合条件的分支都能够自动进行构建。
再次美化构建日志
构建日志的详细程度,决定了拍错,以及更好的运维。
这段代码是一个Jenkins Pipeline的脚本,用于定义一系列的构建阶段和后续处理。
以下是脚本的主要部分:
agent { label '10.0.0.81' }: 指定构建运行的代理节点(agent)。在这个例子中,指定了一个具有标签为'10.0.0.81'的代理节点。environment { ... }: 定义了一些环境变量,供后续阶段使用。其中包括IMAGE_REPO(镜像仓库地址)、DINGTALK_CREDS(DingTalk凭据)、TAB_STR(用于缩进的字符串)等。stages { ... }: 定义了一系列的构建阶段。每个阶段包含一个或多个步骤(steps)。stage('gitlog'): 这个阶段用于获取最新的Git提交日志,并将结果保存到gitlog.file文件中。stage('checkout'): 这个阶段用于从源代码管理系统(scm)中检出代码,并设置BUILD_TASKS环境变量。stage('mvn package'): 这个阶段用于运行Maven命令进行清理和打包,并更新BUILD_TASKS环境变量。stage('build-image'): 这个阶段用于构建Docker镜像,使用docker build命令,并更新BUILD_TASKS环境变量。stage('push-image'): 这个阶段用于将Docker镜像推送到远程仓库,使用docker push命令,并更新BUILD_TASKS环境变量。stage('deploy'): 这个阶段用于部署应用程序,包括替换部分文件内容和执行kubectl apply命令,并更新BUILD_TASKS环境变量。
post { ... }: 定义了构建后的处理步骤,根据构建结果执行相应的操作。success { ... }: 如果构建成功,则发送一条Markdown格式的消息到指定的DingTalk机器人,包含构建的相关信息。failure { ... }: 如果构建失败,则发送一条Markdown格式的消息到指定的DingTalk机器人,包含构建的相关信息。always { ... }: 无论构建结果如何,始终执行该步骤,并输出一条消息。
这段代码的作用是在Jenkins中定义了一个包含多个阶段的构建流水线,涵盖了代码获取、打包、构建镜像、推送镜像和部署等步骤,并在构建完成后发送构建结果通知到DingTalk机器人。
pipeline {
agent { label '10.0.0.81'}
environment {
IMAGE_REPO = "10.0.0.66:5000/eladmin/eladmin-api"
DINGTALK_CREDS = credentials('dingtalk')
TAB_STR = "\n \n "
}
stages {
stage('gitlog') {
steps {
script{
sh "git log --oneline -n 1 > gitlog.file"
env.GIT_LOG = readFile("gitlog.file").trim()
}
sh 'printenv'
}
}
stage('checkout') {
steps {
checkout scm
script{
env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('mvn package') {
steps {
sh 'mvn clean package'
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('build-image') {
steps {
retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('push-image') {
steps {
retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('deploy') {
steps {
timeout(time: 1, unit: 'MINUTES') {
sh "sed -i 's##${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
sh "kubectl apply -f manifests/"
}
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
}
post {
success {
echo 'Congratulations!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"eladmin-api",
"text": "😄👍 构建成功 👍😄 \n**项目名称**: www.yuchaoit.cn \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
failure {
echo 'Oh no!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"eladmin-api",
"text": "😖❌ 构建失败 ❌😖 \n**项目名称**: www.yuchaoit.cn \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
always {
echo 'I will always say Hello again!'
}
}
}
dev分支推送
git commit -m 'k8s pretty jenkinfile'
git push origin -u dev

项目会为什么会构建
多分支类型的项目,默认没有webhook功能,但是我们配置了1分钟的扫描,所以还是会自动构建。

成功美化构建

钉钉看到报警

并且加入了一个git log版本信息,更清晰对比构建项目的版本
$ git log --oneline -n 1
29340c7 (HEAD -> dev, origin/dev) k8s pretty jenkinfile 3
通知gitlab构建状态
我们刚才是基于dev分支的构建测试,确认无误后,可以通知给开发,可以合并到master,且更新生产环境。
在一个使用Jenkins进行构建的项目中,可以通过GitLab提供的API将构建状态通知发送到GitLab。这个通知可以作为开发人员发起Merge Request(合并请求)或合并Merge Request的依据之一。
具体来说,当Jenkins进行构建时,它可以获取构建的状态(成功或失败),然后使用GitLab的API将这个状态通知发送到相关的GitLab项目中。这个通知可以被开发人员用作触发他们发起新的Merge Request或合并已有Merge Request的决策依据之一。
通过将构建状态与GitLab中的Merge Request关联起来,开发人员可以更方便地了解构建的结果,并在需要时根据构建状态做出相应的操作。例如,如果构建成功,开发人员可以发起新的Merge Request,将其合并到主分支中。如果构建失败,开发人员可以检查失败的构建日志,并相应地修复问题或修改代码。
总之,通过将构建状态通知发送到GitLab,Jenkins可以与GitLab无缝集成,并为开发人员提供有关构建状态的重要信息,以便他们能够根据构建状态做出适当的决策。
Jenkins端做了构建,可以通过gitlab通过的api将构建状态通知过去,作为开发人员发起Merge Request或者合并Merge Request的依据之一。
注意一定要指定gitLabConnection('gitlab'),不然没法认证到Gitlab端
对比修改了哪些配置就行。
具体groovy脚本

连接gitlab配置
下面是每个选项的解释:
buildDiscarder(logRotator(numToKeepStr: '10')): 这个选项指定了构建日志的处理方式。logRotator是Jenkins中的一个构建日志管理器,numToKeepStr参数设置保留的构建日志数量为10个。这意味着只会保留最新的10个构建日志,旧的构建日志会被自动删除。disableConcurrentBuilds(): 这个选项禁用了并发构建。当这个选项设置为true时,Jenkins将确保同一个项目在同一时间只能执行一个构建。如果有其他构建正在进行,新的构建请求将被排队等待执行。timeout(time: 20, unit: 'MINUTES'): 这个选项设置了构建的超时时间。在本例中,构建的最长执行时间被设置为20分钟。如果构建超过了这个时间限制,Jenkins将终止该构建并标记为超时。gitLabConnection('gitlab'): 这个选项指定了与GitLab的连接名称。在Jenkins的全局配置中,你需要配置一个与GitLab的连接,其名称为'gitlab'。这样,Jenkins就可以使用这个连接来与GitLab进行通信,例如发送构建状态通知等操作。
通过在Pipeline的options部分配置这些选项,你可以自定义构建的行为和设置,以满足你的需求。
更新gitlab状态
updateGitlabCommitStatus是Jenkins Pipeline中的一个步骤,用于更新GitLab上某个提交的状态。
在这个特定的代码行中,updateGitlabCommitStatus步骤被用于更新当前的GitLab提交状态,以表明某个阶段(env.STAGE_NAME)的执行结果为成功(state: 'success')。
通过调用这个步骤,Jenkins可以通过GitLab API将状态更新发送到相应的GitLab提交。这个操作可以帮助开发人员和团队了解到某个特定阶段的执行结果,并在需要时采取相应的行动。
注意,为了能够使用updateGitlabCommitStatus步骤,你需要在Jenkins中配置正确的GitLab连接,并确保提供了适当的认证凭据。
pipeline {
agent { label '10.0.0.81'}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
disableConcurrentBuilds()
timeout(time: 20, unit: 'MINUTES')
gitLabConnection('gitlab')
}
environment {
IMAGE_REPO = "10.0.0.66:5000/eladmin/eladmin-api"
DINGTALK_CREDS = credentials('dingtalk')
TAB_STR = "\n \n "
}
stages {
stage('gitlog') {
steps {
script{
sh "git log --oneline -n 1 > gitlog.file"
env.GIT_LOG = readFile("gitlog.file").trim()
}
sh 'printenv'
}
}
stage('checkout') {
steps {
checkout scm
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('mvn package') {
steps {
sh 'mvn clean package'
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('build-image') {
steps {
retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('push-image') {
steps {
retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
stage('deploy') {
steps {
timeout(time: 1, unit: 'MINUTES') {
sh "sed -i 's##${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
sh "kubectl apply -f manifests/"
}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
}
}
}
}
post {
success {
echo 'Congratulations!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"eladmin-api",
"text": "😄👍 构建成功 👍😄 \n**项目名称**: www.yuchaoit.cn \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
failure {
echo 'Oh no!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"eladmin-api",
"text": "😖❌ 构建失败 ❌😖 \n**项目名称**: www.yuchaoit.cn \n**Git log**: ${GIT_LOG} \n**构建分支**: ${GIT_BRANCH} \n**构建地址**: ${RUN_DISPLAY_URL} \n**构建任务**: ${BUILD_TASKS}"
}
}'
"""
}
always {
echo 'I will always say Hello again!'
}
}
}
提交git
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$ git add .
warning: in the working copy of 'Jenkinsfile', LF will be replaced by CRLF the next time Git touches it
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$ git commit -m 'update gitlab'
[dev 5e7b368] update gitlab
1 file changed, 13 insertions(+), 1 deletion(-)
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 20 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 531 bytes | 531.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for dev, visit:
remote: http://gitlab.yuchaoit.cn/elamin-ops/eladmin-api/-/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote:
To http://gitlab.yuchaoit.cn/elamin-ops/eladmin-api.git
29340c7..5e7b368 dev -> dev
Sylar@DESKTOP-G6C412R MINGW64 ~/Desktop/eladmin (dev)
查看构建结果

钉钉

查看gitlab通知

查看gitlab 的pipeline

可以更无缝的结合gitlab、和jenkins的构建结果,点击立即跳转到jenkins的构建日志。
此时开发可以去合并代码了(create merge)

既然dev分支的构建没问题了,合并到master。
创建合并请求

查看gitlab合并对应的pipeline
你代码是否可以合并,根据dev分支下的构建结果,确认无误可以合并。

合并分支

dev分支被删除

master分支自动构建

钉钉
