提交后钩子触发自动 Jenkins 构建

12

我知道有很多类似的帖子,但我没有找到解决办法,其他帖子中提出的建议和解决方案与我看到的情况不太一致。

场景非常简单:我在Eclipse中有一个项目,当我将更改从该项目提交到我们的Subversion服务器(即VisualSVN Server 2.5.3)时,我希望我们的Jenkins持续集成服务器(即Jenkins 1.546)获取此更改并启动新的构建。 我不想从Jenkins轮询。

我主要遵循这篇文章中的步骤。 这是我的 post-commit hook 脚本:

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 Server\log.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 & ".\n Body: " & http.responseText
  end if
end if
问题在于,尽管上述“POST”命令最终获得了“200”响应,但作业从未启动。什么也没发生。好吧,让我们检查Jenkins作业配置;也许我错过了一些设置。嗯,在“构建触发器”部分,我已经选中了“远程触发构建(例如,来自脚本)”选项,并且我也提供了身份验证令牌。但是,该部分下面的说明与我一直在做的不同:

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

因此,似乎存在着我看到的指令集之间的差异,我不知道如何弥合这种差距。按照Jenkins作业配置页面上的说明似乎很明显,只是我不知道如何获取作业名称,而不是UUID。

还要注意的另一件事是我的存储库设置。由于CI服务器被多个团体和部门使用,所以我认为我会很聪明地创建一个顶级存储库,以仅容纳我的部门项目。所以,我的设置看起来像这样:

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

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

非常感谢您的帮助,谢谢大家。

2个回答

10
您提供的文章说:

在Jenkins上的作业需要配置SCM轮询选项才能从中受益。这是为了使您可以有一些作业不会被后提交挂钩($REPOSITORY/hooks目录中)触发,例如与发布相关的任务,通过省略SCM轮询选项。已配置的轮询可以有任何计划表(可能不频繁,如每月或每年)。其净效应就像轮询发生在它们平时的周期之外。

以及

为了使其正常工作,您的Jenkins必须允许匿名读取访问(具体来说,“作业>读取”访问权限),如果您的Jenkins访问控制更加严格,则可能需要根据配置的身份验证方式指定用户名和密码。

您的服务器是否符合这些限制要求?


第一个问题是:我还需要配置作业来轮询SCM,不提供任何计划。我不确定我是如何错过那个小节的,我想我没有想象中那么仔细。无论如何,谢谢你,scaytrase! - liltitus27

1

我尝试让svn插件示例工作,但没有成功。相反,我使用了构建令牌根插件,并且这可以在不必轮询的情况下工作。

https://wiki.jenkins-ci.org/display/JENKINS/Build+Token+Root+Plugin

构建触发器 > 远程触发构建选项 > 提供令牌

在 VisualSVN 服务器上将此添加到提交后钩子:

SET CSCRIPT=%windir%\system32\cscript.exe
SET VBSCRIPT=C:\Repositories\post-commit-hook-jenkins.vbs
"%CSCRIPT%" "%VBSCRIPT%" "MyJobName" "MyTokenFromBuildTrigger"

对于post-commit-hook-jenkins.vbs:

Set args = WScript.Arguments
JobName = args.Item(0)
Token = args.Item(1)

'URL to open....
sUrl = "http://MyJenkinsServer.MyCompany.com/buildByToken/build?job=" + JobName + "&token=" + Token
'POST Request to send.
sRequest = ""

HTTPPost sUrl, sRequest

Function HTTPPost(sUrl, sRequest)
  set oHTTP = CreateObject("Microsoft.XMLHTTP")
  oHTTP.open "POST", sUrl,false
  oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  oHTTP.setRequestHeader "Content-Length", Len(sRequest)
  oHTTP.send sRequest
  HTTPPost = oHTTP.responseText
 End Function 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接