有一些技巧可以让它发挥作用,我发现了(现已不复存在)chloky.com
博客文章对大部分内容都有帮助。因为听起来您至少已经让 Webhook 与您的 Jenkins 实例进行通信,所以我现在将跳过这些步骤。但是,如果您想要更多详细信息,只需滚动到我的答案末尾即可查看我能够从中抢救的内容chloky.com
- 我不知道原作者,这些信息可能已经过时,但我确实发现它很有帮助。
总而言之,您可以执行以下操作来处理有效负载:
- 在 Jenkins 作业中设置一个名为“payload”的字符串参数。如果您计划手动运行构建,那么在某个时候为其提供一个默认的 JSON 文档可能是一个好主意,但您现在不需要一个。这个参数名称似乎区分大小写(我使用的是 Linux,所以这并不奇怪......)
在github中设置webhook以使用带有参数的构建端点而不是build端点,即http://<<yourserver>>/job/<<yourjob>>/buildWithParameters?token=<<yourtoken>>
配置要使用的 Webhook应用程序/x-www-form-encoded代替应用程序/json。前一种方法将 JSON 数据打包在一个名为“payload”的表单变量中,这大概就是 Jenkins 将其分配给环境变量的方式。这应用程序/json方法只是 POST 原始 JSON,它似乎无法映射到任何东西(我无法让它工作)。您可以通过将 webhook 指向类似的内容来查看差异请求箱 http://stedolan.github.io/jq/并检查结果。
- 此时,您应该得到您的$payload当你开始构建时变量。要解析 JSON,我强烈建议安装jq https://jqplay.org/在你的 Jenkins 服务器上尝试一些解析语法here https://i.stack.imgur.com/r9Z1e.png。 JQ 特别好,因为它是跨平台的。
- 从这里开始,只需将 JSON 中的所需内容解析为其他环境变量即可。与条件构建步骤相结合,这可以为您提供很大的灵活性。
希望这可以帮助!
EDIT这是我可以从原始博客文章中获取的内容http://chloky.com/tag/jenkins/
,已经死了一段时间了。
希望此内容对某人也有用。
帖子 #1 - 2012 年 7 月
Github 提供了一种很好的方法,每当针对存储库进行提交时,都会向 jenkins 等 CI 系统发出通知。这对于在 jenkins 中启动构建作业以测试刚刚在存储库上进行的提交非常有用。您只需转到存储库的管理部分,单击左侧的服务挂钩,单击列表顶部的“webhook URLs”,然后输入 jenkins 所需的 webhook 的 URL(查看这个詹金斯插件 https://wiki.jenkins.io/display/JENKINS/GitHub+Plugin用于设置 jenkins 以从 github 接收这些钩子)。
不过最近,我正在寻找一种方法,在针对存储库发出拉取请求时而不是在对存储库进行提交时触发 Webhook。这样我们就可以让 jenkins 在决定是否合并拉取请求之前对拉取请求运行一堆测试 - 当您有很多开发人员在自己的分叉上工作并定期向主分支提交拉取请求时非常有用回购。
事实证明,这并不像人们希望的那么明显,并且需要对 github API 进行一些修改。
默认情况下,当您配置 github webhook 时,它被配置为仅在针对存储库进行提交时触发。当您设置 webhook 时,没有简单的方法可以在 github Web 界面中查看或更改这一点。为了以任何方式操作 webhook,您需要使用 API。
要通过 github API 对存储库进行更改,我们需要自行授权。我们将使用curl,所以如果我们愿意,我们可以每次传递我们的用户名和密码,如下所示:
# curl https://api.github.com/users/mancdaz --user 'mancdaz'
Enter host password for user 'mancdaz':
或者,如果您想编写这些内容的脚本,这是一个更好的选择,我们可以获取一个 oauth 令牌并在后续请求中使用它,从而不必继续输入密码。这就是我们在示例中要做的事情。首先我们需要创建一个 oauth 授权并获取令牌:
curl https://api.github.com/authorizations --user "mancdaz" \
--data '{"scopes":["repo"]}' -X POST
您将收到类似以下内容的信息:
{
"app":{
"name":"GitHub API",
"url":"http://developer.github.com/v3/oauth/#oauth-authorizations-api"
},
"token":"b2067d190ab94698a592878075d59bb13e4f5e96",
"scopes":[
"repo"
],
"created_at":"2012-07-12T12:55:26Z",
"updated_at":"2012-07-12T12:55:26Z",
"note_url":null,
"note":null,
"id":498182,
"url":"https://api.github.com/authorizations/498182"
}
现在我们可以在后续请求中使用此令牌通过 API 操作我们的 github 帐户。因此,让我们查询我们的存储库并找到我们之前在 Web 界面中设置的 Webhook:
# curl https://api.github.com/repos/mancdaz/mygithubrepo/hooks?access_token=b2067d190ab94698592878075d59bb13e4f5e96
[
{
"created_at": "2012-07-12T11:18:16Z",
"updated_at": "2012-07-12T11:18:16Z",
"events": [
"push"
],
"last_response": {
"status": "unused",
"message": null,
"code": null
},
"name": "web",
"config": {
"insecure_ssl": "1",
"content_type": "form",
"url": "http://jenkins-server.chloky.com/post-hook"
},
"id": 341673,
"active": true,
"url": "https://api.github.com/repos/mancdaz/mygithubrepo/hooks/341673"
}
]
请注意 json 输出中的重要部分:
"events": [
"push"
]
这基本上是说,只有在对存储库进行提交(推送)时才会触发此 Webhook。 github API 文档描述了许多可以添加到此列表中的不同事件类型 - 出于我们的目的,我们想要添加 pull_request,这就是我们的做法(请注意,我们从上面的 json 输出中获取 webhook 的 id。如果您定义了多个钩子,您的输出将包含所有这些钩子,因此请确保获得正确的 ID):
# curl https://api.github.com/repos/mancdaz/mygithubrepo/hooks/341673?access_token=b2067d190ab94698592878075d59bb13e4f5e96 -X PATCH --data '{"events": ["push", "pull_request"]}'
{
"created_at": "2012-07-12T11:18:16Z",
"updated_at": "2012-07-12T16:03:21Z",
"last_response": {
"status": "unused",
"message": null,
"code": null
},
"events": [
"push",
"pull_request"
],
"name": "web",
"config": {
"insecure_ssl": "1",
"content_type": "form",
"url": "http://jenkins-server.chloky.com/post-hook"
},
"id": 341673,
"active": true,
"url": "https://api.github.com/repos/mancdaz/mygithubrepo/hooks/341673"
}
See!
"events": [
"push",
"pull_request"
],
现在,每当针对我们的存储库发出提交或拉取请求时,都会触发此 Webhook。您在 jenkins/ 中使用此 Webhook 执行的具体操作取决于您。我们使用它在 jenkins 中启动一系列集成测试来测试建议的补丁,然后自动合并并关闭(再次使用 API)拉取请求。相当甜蜜。
帖子 #2 - 2012 年 9 月
在之前的一篇文章中,我讨论了配置 github webhook 以触发拉取请求,而不仅仅是提交。如前所述,github 存储库上会发生许多事件,并且根据 github 文档,其中很多事件可用于触发 webhook。
无论您决定触发什么事件,当 webhook 从 github 触发时,它本质上都会向 webhook 中配置的 URL 发出 POST,包括正文中的 json 负载。 json 负载包含有关导致 webhook 触发的事件的各种详细信息。可以在此处查看在简单提交上触发的示例有效负载:
payload
{
"after":"c04a2b2af96a5331bbee0f11fe12965902f5f571",
"before":"78d414a69db29cdd790659924eb9b27baac67f60",
"commits":[
{
"added":[
"afile"
],
"author":{
"email":"[email protected] /cdn-cgi/l/email-protection",
"name":"Darren Birkett",
"username":"mancdaz"
},
"committer":{
"email":"[email protected] /cdn-cgi/l/email-protection",
"name":"Darren Birkett",
"username":"mancdaz"
},
"distinct":true,
"id":"c04a2b2af96a5331bbee0f11fe12965902f5f571",
"message":"adding afile",
"modified":[
],
"removed":[
],
"timestamp":"2012-09-03T02:35:59-07:00",
"url":"https://github.com/mancdaz/mygithubrepo/commit/c04a2b2af96a5331bbee0f11fe12965902f5f571"
}
],
"compare":"https://github.com/mancdaz/mygithubrepo/compare/78d414a69db2...c04a2b2af96a",
"created":false,
"deleted":false,
"forced":false,
"head_commit":{
"added":[
"afile"
],
"author":{
"email":"[email protected] /cdn-cgi/l/email-protection",
"name":"Darren Birkett",
"username":"mancdaz"
},
"committer":{
"email":"[email protected] /cdn-cgi/l/email-protection",
"name":"Darren Birkett",
"username":"mancdaz"
},
"distinct":true,
"id":"c04a2b2af96a5331bbee0f11fe12965902f5f571",
"message":"adding afile",
"modified":[
],
"removed":[
],
"timestamp":"2012-09-03T02:35:59-07:00",
"url":"https://github.com/mancdaz/mygithubrepo/commit/c04a2b2af96a5331bbee0f11fe12965902f5f571"
},
"pusher":{
"email":"[email protected] /cdn-cgi/l/email-protection",
"name":"mancdaz"
},
"ref":"refs/heads/master",
"repository":{
"created_at":"2012-07-12T04:17:51-07:00",
"description":"",
"fork":false,
"forks":1,
"has_downloads":true,
"has_issues":true,
"has_wiki":true,
"name":"mygithubrepo",
"open_issues":0,
"owner":{
"email":"[email protected] /cdn-cgi/l/email-protection",
"name":"mancdaz"
},
"private":false,
"pushed_at":"2012-09-03T02:36:06-07:00",
"size":124,
"stargazers":1,
"url":"https://github.com/mancdaz/mygithubrepo",
"watchers":1
}
}
整个有效负载作为单个参数在 POST 请求中传递,并带有富有想象力的标题payload
。它包含大量有关刚刚发生的事件的信息,当我们在触发器之后构建作业时,jenkins 可以使用所有或任何这些信息。为了在 Jenkins 中使用这个有效负载,我们有几个选择。我在下面讨论一个。
获取 $payload
在 jenkins 中,当创建新的构建作业时,我们可以选择指定希望在触发构建的 POST 中传递给作业的参数名称。在这种情况下,我们将传递一个参数payload
,如下所示:
将参数传递给 jenkins 构建作业
在作业配置中,我们可以指定我们希望能够远程触发构建(即我们希望允许 github 通过使用有效负载发布到我们的 URL 来触发构建):
然后,当我们在 github 存储库中设置 webhook 时(如第一篇文章中所述),我们为其提供 jenkins 告诉我们的 URL:
您无法在屏幕截图中看到所有内容,但我为 webhook 指定的 URL 是 jenkins 告诉我的 URL:
http://jenkins-server.chloky.com:8080/job/mytestbuild//buildWithParameters?token=asecuretoken
现在,当我在 jenkins 中构建新作业时,为了进行此测试,我只是告诉它回显“有效负载”参数的内容(该参数在参数化构建中作为同名的 shell 变量提供),使用一个简单的脚本:
#!/bin/bash
echo "the build worked! The payload is $payload"
现在要测试整个事情,我们只需提交到我们的存储库,然后跳到 jenkins 查看触发的作业:
mancdaz@chloky$ (git::master)$ touch myfile
mancdaz@chloky$ (git::master) git add myfile
mancdaz@chloky$ (git::master) git commit -m 'added my file'
[master 4810490] added my file
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 myfile
mancdaz@chloky$ (git::master) git push
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 232 bytes, done.
Total 2 (delta 1), reused 0 (delta 0)
To [email protected] /cdn-cgi/l/email-protection:mancdaz/mygithubrepo.git
c7ecafa..4810490 master -> master
在我们的 jenkins 服务器中,我们可以查看触发的作业的控制台输出,你瞧,$payload 变量中包含我们的“有效负载”,可供我们使用:
太棒了,关于我们 github 活动的所有信息都在这里。并且完全可以在我们的詹金斯工作中使用!确实,它在一个大的 json blob 中,但是通过一些巧妙的 bash,你应该可以开始了。
当然,这个例子使用了一个简单的提交来演示在jenkins内部获取payload的原理。正如我们在之前的文章中讨论的那样,提交是存储库上可以触发 Webhook 的众多事件之一。一旦触发,你在 jenkins 中做什么取决于你,但是当你开始与 github 交互以根据以下结果对存储库采取进一步操作(发表评论、合并拉取请求、拒绝提交等)时,真正的乐趣就来了由初始事件触发的构建作业。
请留意后续的帖子,其中我将所有内容结合在一起,并向您展示如何处理、运行测试并最终合并拉取请求(如果成功)——所有这些都在 jenkins 内自动进行。自动化很有趣!