Post-Commit Hook to trigger automatic Jenkins Build
Solution 1
The article you linked says
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.
and
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?
Solution 2
I tried to get the svn plugin examples to work, but no luck. Instead I used the build token root plugin and this works without having to poll.
https://wiki.jenkins-ci.org/display/JENKINS/Build+Token+Root+Plugin
Build Triggers > Trigger builds remotely option > give it a token
On VisualSVN server add this to the post-commit hook:
SET CSCRIPT=%windir%\system32\cscript.exe
SET VBSCRIPT=C:\Repositories\post-commit-hook-jenkins.vbs
"%CSCRIPT%" "%VBSCRIPT%" "MyJobName" "MyTokenFromBuildTrigger"
For 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
liltitus27
Updated on November 17, 2020Comments
-
liltitus27 over 3 years
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.
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 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
The issue is that, although the
POST
command above ends up getting a200
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: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.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.
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
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 thanD:\<visual-svn-repos>\<my-department>\DepartmentProject_B
).Any help would be greatly appreciated, thanks guys.
-
liltitus27 over 10 yearsthe first one was it: i needed to also configure the job to poll the scm, providing no schedule. i'm not sure how i missed that blurb, i guess i was less thorough than i had thought. anyway, thank you, scaytrase!