在gitlab通过webhook触发Jenkins的job中用script获取当前分支

Sue ·
更新时间:2024-11-10
· 979 次阅读

文章目录webhook给jenkins发了什么找对分支名了吗第一种方法调整分支第二种方法调整分支感谢 webhook给jenkins发了什么

gitlab触发jenkins的job是通过webhook完成的,也就是一次http请求,请求体在jenkins的job的ConsoleOutput中可以看到。长这样子(网页上的json是一坨,这里format了一下):

GenericWebhookEnvironmentContributor Received: { "object_kind": "push", "before": "0000000000000000000000000000000000000000", "after": "1d09c45658d42cd6c8c41d3370d4a2d5b46690b4", "ref": "refs/heads/xxx-dev", "checkout_sha": "1d09c45658d42cd6c8c41d3370d4a2d5b46690b4", "message": null, "user_id": 142, "user_name": "xxx", "user_email": "xxx@x.com", "project_id": 531, "repository": { "name": "test", "url": "ssh://git@172.16.*.*:*/test.git", "description": "test", "homepage": "http://172.16.*.*:*/test", "git_http_url": "http://172.16.*.*:*/test.git", "git_ssh_url": "ssh://git@172.16.*.*:*/test.git", "visibility_level": 10 }, "commits": [ { "id": "1d09c45658d42cd6c8c41d3370d4a2d5b46690b4", "message": "test\n", "timestamp": "2020-03-17T21:34:10+08:00", "url": "http://172.16.*.*:*/test/commit/1d09c45658d42cd6c8c41d3370d4a2d5b46690b4", "author": { "name": "xxx", "email": "xxx@x.com" } } ], "total_commits_count": 1 } 找对分支名了吗

在单元测试之类的触发中,通常需要跑pipeline的分支是不可预知的,这就需要在jenkins脚本中进行动态获取。我们可以注意到上面有一个字段ref的值为refs/heads/xxx-dev,看上就是他了,但实际上这是不能用的,我们先试一下。

在jenkins脚本中,可以直接获取到ref的值:

node(label) { println ref }

这里println是groovy的语法,jenkins的PiplineScript基本上就是groovy。

然后我们来试一下直接用ref当分支:

node(label) { stage('test') { dir('/home/jenkins/agent/workspace/test') { git branch: ref, credentialsId: 'xxxx', url: 'http://172.16.*.*:*/test.git' } } }

然后会看到这样的报错:

using GIT_ASKPASS to set credentials > git fetch --tags --force --progress -- http://172.16.*.*:*/test.git +refs/heads/*:refs/remotes/origin/* # timeout=10 > git rev-parse refs/remotes/origin/refs/heads/xxx-dev^{commit} # timeout=10 > git rev-parse refs/remotes/origin/origin/refs/heads/xxx-dev^{commit} # timeout=10 > git rev-parse origin/refs/heads/xxx-dev^{commit} # timeout=10 ... ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job. 第一种方法调整分支

我们有两个办法让jenkins拿到准确分支,先说第一种,checkout的方式:

node(label) { stage('test') { dir('/home/jenkins/agent/workspace/test') { git branch: 'develop', credentialsId: 'xxxx', url: 'http://172.16.*.*:*/test.git' sh ''' git checkout ${ref##*/} ''' } } }

在script里调用sh来实现checkout,这里${ref##*/}就是xxx-dev,如果写${ref#*/}就是heads/xxx-dev,如果写${ref}就是refs/heads/xxx-dev

但是有些情况下,checkout会报错:

+ git checkout xxx-dev error: The following untracked working tree files would be overwritten by checkout: vendor/github.com/PuerkitoBio/purell/.gitignore vendor/github.com/PuerkitoBio/purell/.travis.yml ...

这时我们就该考虑能不能让jenkins上来就在指定分支上工作呢,其实是可以的,我们来看第二种方法。

第二种方法调整分支

第二种方法就是借助groovy代码对ref变量做手脚,简单思路就是用split函数将字符串分割,然后取后面的部分。

ref.split("refs/heads/")

这里有点奇怪的是,他的返回值首先是个引用类型,如果直接println ref.split("refs/heads/")会看到[Ljava.lang.String;@618657aa,所以不能直接ref.split("refs/heads/")[0]

def arr = ref.split("refs/heads/") as List

第二点比较奇怪的是,在其他语言比如C#、Java、go中,这种情况返回的数组只包含一个元素,而这里返回的却是两个元素:

def arr = ref.split("refs/heads/") as List println arr // [, xxx-dev]

所以我们需要取arr[1]来拿到分支名,这样一来我们就可以将上面的脚本改写:

node(label) { stage('test') { dir('/home/jenkins/agent/workspace/test') { def arr = ref.split("refs/heads/") as List def currentBranch = arr[1] git branch: currentBranch, credentialsId: 'xxxx', url: 'http://172.16.*.*:*/test.git' } } } 感谢

参考文章:我在这里看到了split;在这里看到了as LinkedList。感谢以上作者的文章!如果你有更巧妙的方法,欢迎留言告诉我!


作者:-_-void



gitlab script jenkins

需要 登录 后方可回复, 如果你还没有账号请 注册新账号