Post-Commit Hook 触发自动 Jenkins 构建 [英] Post-Commit Hook to trigger automatic Jenkins Build

查看:18
本文介绍了Post-Commit Hook 触发自动 Jenkins 构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有很多类似的帖子,但我没有找到解决方案,其他帖子中提供的建议和解决方案与我所看到的不太相符.

I know that there are many similar postings, but I have not found a solution, and the advice and solutions presented in the other posts don't quite jive with what I'm seeing.

场景非常简单:我在 Eclipse 中有一个项目,当我将该项目的更改签入到我们的 Subversion 服务器(即 VisualSVN Server 2.5.3)时,我想要我们的 Jenkins 持续集成服务器(即, Jenkins 1.546) 来接受这个变化并开始一个新的构建.我不想从 Jenkins 那里投票.

The scenario is pretty darn simple: I have a project in Eclipse, and when I check-in changes from that project to our Subversion server (i.e., VisualSVN Server 2.5.3), I want our Jenkins continuous integration server (i.e., Jenkins 1.546) to pick up this change and kick off a new build. I do not want to poll from Jenkins.

我一直在遵循这篇文章中的步骤.这是我的提交后挂钩脚本:

I've been mostly following the steps in this article. Here's my post-commit hook script:

repos   = WScript.Arguments.Item(0)
rev     = WScript.Arguments.Item(1)
svnlook = WScript.Arguments.Item(2)
jenkins = WScript.Arguments.Item(3)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("C:Program Files (x86)VisualSVN Serverlog.txt")

objFile.Writeline "repos=" & repos
objFile.Writeline "rev=" & rev
objFile.Writeline "svnlook=" & svnlook
objFile.Writeline "jenkins=" & jenkins

Set shell = WScript.CreateObject("WScript.Shell")

Set uuidExec = shell.Exec(svnlook & " uuid " & repos)
Do Until uuidExec.StdOut.AtEndOfStream
  uuid = uuidExec.StdOut.ReadLine()
Loop

objFile.Writeline "uuid=" & uuid

Set changedExec = shell.Exec(svnlook & " changed --revision " & rev & " " & repos)
Do Until changedExec.StdOut.AtEndOfStream
  changed = changed + changedExec.StdOut.ReadLine() + Chr(10)
Loop
objFile.Writeline "changed=" & changed

url = jenkins + "crumbIssuer/api/xml?xpath=concat(//crumbRequestField,"":"",//crumb)"
Set http = CreateObject("Microsoft.XMLHTTP")
http.open "GET", url, False
http.setRequestHeader "Content-Type", "text/plain;charset=UTF-8"
http.send
crumb = null

objFile.Writeline "rev url=" & url
objFile.Writeline "http.status=" & http.status
objFile.Writeline "http.responseText=" & http.responseText

if http.status = 200 then
  crumb = split(http.responseText,":")
end if

url = jenkins + "subversion/" + uuid + "/notifyCommit?rev=" + rev + "&token=pinkfloyd65"
objFile.Writeline "url=" & url

if not isnull(crumb) then 
    objFile.Writeline "crumb(0)=" & crumb(0)
    objFile.Writeline "crumb(1)=" & crumb(1)
end if

if isnull(crumb) then 
    objFile.Writeline "crumb=null"
end if

Set http = CreateObject("Microsoft.XMLHTTP")
http.open "POST", url, False
http.setRequestHeader "Content-Type", "text/plain;charset=UTF-8"
if not isnull(crumb) then 
  http.setRequestHeader crumb(0),crumb(1)
  http.send changed
  if http.status <> 200 then
    objFile.Writeline "Error. HTTP Status: " & http.status & ". Body: " & http.responseText
  end if

  if http.status = 200 then
    objFile.Writeline "HTTP Status: " & http.status & ".
 Body: " & http.responseText
  end if
end if

问题在于,尽管上面的 POST 命令最终会得到 200 响应,但该作业永远不会启动.什么都没有发生.好的,让我们检查一下 Jenkins 作业配置;也许我错过了一个设置或其他东西.好吧,在 Build Triggers 部分下,我已经检查了Trigger builds remote (e.g., from scripts)"选项,并且我还提供了一个身份验证令牌.但是,该部分下方的方向看起来与我一直在做的不同:

The issue is that, although the POST command above ends up getting a 200 response back, the job never kicks off. Nothing ends up happening. Alright, so let's check the Jenkins job configuration; maybe I'm missing a setting or something. Well, under the Build Triggers section, I've checked the option for "Trigger builds remotely (e.g., from scripts)" and I've supplied an authentication token as well. But, the directions underneath that section look different from what I've been doing:

使用以下 URL 远程触发构建:JENKINS_URL/job//build?token=TOKEN_NAME/buildWithParameters?token=TOKEN_NAME可选择附加 &cause=Cause+Text 以提供将包含在记录的构建原因中的文本.

Use the following URL to trigger build remotely: JENKINS_URL/job/<job-name>/build?token=TOKEN_NAME or /buildWithParameters?token=TOKEN_NAME Optionally append &cause=Cause+Text to provide text that will be included in the recorded build cause.

所以,我看到的指令集之间似乎存在差异,我不确定如何弥合这一差距.遵循 Jenkins 作业配置页面上的说明似乎很明显,除了我不知道如何获取作业名称,而不是 UUID.

So, it seems like there's a delta between the sets of instructions I'm seeing, and I'm not sure how to bridge that gap. It seems pretty obvious to follow the instructions on the Jenkins job configuration page, except that I don't know how I'd get the job name, rather than the UUID.

要注意的另一件事是我的存储库设置.由于 CI 服务器被许多组和部门使用,我想我会很聪明,并创建一个顶级存储库来存放我部门的项目.所以,我有一个类似的设置:

Another thing to note is my repository setup. Since the CI server is used by many groups and departments, I thought I'd be all smart and create a top-level repository to house just my department's projects. So, I have a setup something like:

VisualSVN Server  
  -- Repositories  
     -- Project_A  
     -- Project_B  
     -- <my-department>  
        -- DepartmentProject_A  
        -- DepartmentProject_B  

我想知道这里的存储库结构是否增加了我的问题,但我觉得我应该能够找出任何更改来自哪个特定存储库.如果这是真的,那么我可以调整我的脚本以使用作业名称,而不是 UUID,然后按照我的 CI 服务器配置页面上的明确说明进行操作.当我在我的 vbs 脚本中记录传入的 repos 变量时,它指向顶级部门存储库,而不是项目的子存储库(即 D:<visual-svn-repos><my-department> 而不是 D:).

I'm wondering if the repository structure is adding to my issues here, but I feel like I should be able to find out which specific repository any changes came from. If that were true, then I could adjust my script to use the job name, rather than UUID, and then follow the explicit instructions seen on my CI server's configuration page. When I log the incoming repos variable in my vbs script, it points to the top-level department repository, rather than the project's child repository (i.e., D:<visual-svn-repos><my-department> rather than D:<visual-svn-repos><my-department>DepartmentProject_B).

任何帮助将不胜感激,谢谢大家.

Any help would be greatly appreciated, thanks guys.

推荐答案

你链接的文章说

Jenkins 上的作业需要配置 SCM 轮询选项以受益于这种行为.这样你就可以有一些工作不会被 post-commit 钩子触发的(在$REPOSITORY/hooks 目录),如发布相关任务,由省略 SCM 轮询选项.配置的轮询可以有任何时间表(可能不频繁,如每月或每年).净效应就好像轮询发生在它们通常的周期之外.

Jobs on Jenkins need to be configured with the SCM polling option to benefit from this behavior. This is so that you can have some jobs that are never triggered by the post-commit hook (in the $REPOSITORY/hooks directory), such as release related tasks, by omitting the SCM polling option. The configured polling can have any schedule (probably infrequent like monthly or yearly). The net effect is as if polling happens out of their usual cycles.

为此,您的 Jenkins 必须允许匿名读取访问(特别是作业 > 读取"访问)系统.如果访问控制对您的 Jenkins 的限制更大,您可能需要指定用户名和密码,取决于您的身份验证方式配置好了.

For this to work, your Jenkins has to allow anonymous read access (specifically, "Job > Read" access) to the system. If access control to your Jenkins is more restrictive, you may need to specify the username and password, depending on how your authentication is configured.

您的服务器是否满足此限制?

Does you server meets this restrictions?

这篇关于Post-Commit Hook 触发自动 Jenkins 构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆