Trigger nested Jenkins job from VSTS build - jenkins

I've configured a service hook in VSTS to connect to Jenkins. I'm able to use the Jenkins extension to trigger a Jenkins job if it's not in a subfolder. E.g. http://myhost/job/Always%20succeed/
In that case, I can simply connect like this and run my job:
If my job is nested, however, I can't figure out how to connect. Here's an example: http://myhost/view/Production/job/Automation/job/Test/job/My%20Job
I've tried using just the name (e.g. "My Job"), the whole url, and a dot notation (Production.Automation.Test.My Job). How can I make this run and where can I find more documentation?

It's pretty nuanced and one could argue buggy. First off, I can reach the same job with two urls:
http://myhost/view/Production/job/Automation/job/Test/job/My%20Job
http://myhost/job/Automation/job/Test/job/My%20Job
Turns out the latter is the way to go.
I tried the following name, and it tried reaching the corresponding endpoint:
Automation/job/Test/job/My%20Job <- name used in VSTS "Job name" field
/job/Automation/job/job/Test/job/My%20Job/build <- url attempted, failed (404)
Note the double job/. Then I tried the following with better results:
Automation/Test/job/My%20Job <- name used
/job/Automation/job/Test/job/My%20Job/build <- url tried, success
It's a bit concerning that the pattern isn't consistent regarding the double "job/" part but whatever.

Related

How to get taskid that "waitForQualityGate()" is going to check for?

I apologize for duplicating my post from sonarsource, but sometimes this gets a different audience.
We’re using SonarQube 7.9.2.
Our Jenkins builds use the pipeline steps “withSonarQubeEnv” and “waitForQualityGate”, and in between we use “mvn sonar:sonar” to run the scan. At the end of the latter, it prints the task id it’s going to be waiting for in “waitForQualityGate”. It also shows that task id in the results of that step.
What WebApi call(s) can I perform in between “mvn sonar:sonar” and “waitForQualityGate” that will let me store into a variable the task id that is going to be polled for? I know the project key at that point. I’ve inspected all of the environment variables in scope at that point.
I know how to find the WebApi documentation, and I’ve scanned through what I think are the relevant operations, but I can’t figure out which operation I need for this particular “task”.
When you run the mvn sonar:sonar, report-task.txt will be created in the workspace folder .scannerwork.
You will get the ceTaskUrl and ceTaskId in report-task.txt. Now, you can use that ceTaskUrl to get the analysisId.
You can use the below api to get the quality gate status using analysisId.
https://localhost:9000/sonarqube/api/qualitygates/project_status?analysisId=$ANALYSIS_ID"

Jenkins Extended Choice Parameter - using the values

I'm new to Jenkins so this is probably an easy one. I have the Extended Choice Parameter plugin installed. I'm using the Multi Select parameter type to pick from a list of servers (SERVER1,SERVER2,SERVER3) I've set Source for Value, Default Value, and Value Description.
I save it, and it looks great. I can pick any or all servers for the build. Now for the big question.. how do I use these values in the build? Basically I have a step in the build that can take in a comma separated list that is called by a shell command:
d:\python\deploy.py?serverlist=$blah
What do I put in for $blah to use that list of servers?
Just to be clear, if I'm on command line I would do the following:
d:\python\deploy.py?serverlist=SERVER1,SERVER2,SERVER3
I'm sure it's something simple but I just cannot find it in the docs or an example.
We could get the servers list like this
d:\python\deploy.py?serverlist=$SERVERLIST
or this on Windows
d:\python\deploy.py?serverlist=%SERVERLIST%
To see the list of environment variables which we could you, try this URL (change localhost by your Jenkins URL, TEST by the job name, 10 by the build number)
https://localhost:8080/job/TEST/10/injectedEnvVars/
UPDATE to #sniperd's edition:
This URL will shows us the parameters list in the Job:
http://localhost:8080/job/TEST/59/parameters/

Is there a jenkins plugin to add a why-I-built-this remark, that will appear with 'started by [user]'?

When I run a manual build, I'd often like to mark it with documentation to show why I ran it. Is this feature available with a plugin?
thank you!
I would approach this by adding a build parameter as a string, as above, then use the Description Setter Plugin to set it from that parameter. We use something like this for the regex:
^\++ : BUILD DESCRIPTION : GERRIT_CHANGE_OWNER_EMAIL=([^#\s]*)\S*, BUILD_USER_EMAIL=([^#\s]*)\S*, GERRIT_BRANCH=(\S*), GIT_COMMIT=(\S{8}).*$
and this for the description:
\1\2, \4, \3
As a result we get:
jspain, 0ee3198b, master
or when it fails, we get:
Failed due to timeout.
wayvad, fc7bdf2a, master
this "Failed..." text comes from the Build Timeout Plugin
I am not aware of a plugin that can do this, and after a brief search I could not find one to do what you describe.
You can mimic this behavior by adding a string parameter in the job that takes a default value of automatically started when it's normally run, but that you can change to my reasons for this build when starting it manually.
You could then use a batch (or groovy or ) build step to print the contents of that parameter into the build log. If you do some sort of SCM checkout I'm not sure how close you can get it to print to the line that contains the username that started the job, however you can click on the view parameters button in the job build and see what was in the field quickly without having to parse the logs.
The downside of this is that parameter would have to be added to each job.

Jenkins - retrieve full console output during build step

I have been scouring the internet for days, I have a problem similar to this.
I need to retrieve the console output in raw (plain) text. But if I can get it in HTML that is fine too, I can always parse it. The only thing is that I need to get it during the build step, which is a problem since the location where it should be available is truncated...
I have tried retrieving the console output from the following URL's (relative to the job):
/consoleText
/logText/progressiveText
/logText/progressiveHTML
The two text ones are plain text and would be perfect if not for the truncation, same goes for the HTML one... exactly what I need - only its truncated....
I am sure it is possible to retrieve this information somehow, since when viewing /consoleFull there is a real-time update of the console, without truncating or buffering.
However, upon examining that web page, instead of finding the content I desired, I found this code where it should have been (I did not include the full pages code, since it would be mostly irrelevant, and I believe those answering would be able to find out and know what should be there on their own)
new Ajax.Request(href,{
method: "post",
parameters: {"start":e.fetchedBytes},
requestHeaders: headers,
onComplete: function(rsp,_) {
var stickToBottom = scroller.isSticking();
var text = rsp.responseText;
if(text!="") {
var p = document.createElement("DIV");
e.appendChild(p); // Needs to be first for IE
// Use "outerHTML" for IE; workaround for:
// http://www.quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
if (p.outerHTML) {
p.outerHTML = '<pre>'+text+'</pre>';
p = e.lastChild;
}
else p.innerHTML = text;
Behaviour.applySubtree(p);
if(stickToBottom) scroller.scrollToBottom();
}
e.fetchedBytes = rsp.getResponseHeader("X-Text-Size");
e.consoleAnnotator = rsp.getResponseHeader("X-ConsoleAnnotator");
if(rsp.getResponseHeader("X-More-Data")=="true")
setTimeout(function(){fetchNext(e,href);},1000);
else
$("spinner").style.display = "none";
}
});
Specifically, I am hoping there is a way for me to get the content from text whatever it may be. I am not familiar with this language and so am not sure how I might be able to get the content I want. Plugins won't help since I want to retrieve this content as part of my script during the build step
You did pretty much good investigation already. I can only add the following: all console related plug-ins I know are designed as a post build actions.
The Log Trigger plugin provides a post-build action that allows Hudson
builds to search their console log for a given regular expression and
if found, trigger additional downstream jobs.
So it looks like there is no straightforward solution to your problem. I can see the following options:
1. Use tee or something similar (applicable to shell build steps only)
This solution is far from being universal, but it can provide quick access to the latest console output, produced by a command or set of command.
tee - read from standard input and write to standard output and files
Using synonyms on the system level other Jenkins build steps can modified in order to produce console output. File with console output can be referenced through Jenkins or using any other way.
2. Modify Jenkins code
You can just do a quick fix for internal usage or provide a patch introducing specific system-wide setting.
3. Mimic /console behavior
Code in your example is used to request updates from the Jenkins server. As you may expect the server side can return piece of information starting with some offset. Let me show.
Periodically console page sends requests to the server:
Parameters are straightforward:
Response is a chunk of information to be added:
Another request with updated offset (start) value
You can easily understand there is no data by analyzing Content-Length
So the answer is: use url/job-name/build-number/logText/progressiveHtml, specify start offset, send request and receive console update.
I had a similar issue, the last part of my Jenkinsfile build script needs to parse the ConsoleLog for particular error messages to put in an email build report.
First attempt: http request.
It felt like a hack, it mostly worked, but ran into issues when we locked down access to the Jenkins server & my build nodes could no longer perform annon http gets on the page
Second attempt: use the APIs to enumerate the log lines.
It felt like the right thing to do, but it failed horribly as my nodes would take 30 minutes to get through the 100 meg log files. My presumption is that the Jenkins server was not caching the file, so each request involved a re-reading of the entire file up until the point of the last read.
Third and most successful solution: run grep on the server.
node('master') {
sh 'grep some_criteria $JENKINS_HOME/workspace/path/to/job/console.log'
}
it was fast, reliable, and it didn't matter how big the log files were.
Yes, this required trust of the Jenkins admin and knowledge of the directory paths on the Jenkins server - but since I was the admin, I trusted myself to do the right thing. Your mileage may vary.
To add some insight: when the Jenkins build was in progress, the response for the .../consoleText URL maxed out at 10000 lines, exactly.
I was using 'requests()' package in Python. I have tried the same URL with curl and again received only the first 10K lines.
Only after the build has finished both methods returned the full log (>22K lines in my case).
I will research further and hope to report back.
[2015-08-18] Update: It seems that this is a known issue (see here) and it's fixed in Jenkins 1.618 and later. I am still running 1.615 so I cannot verify.
Amir

Fail Jenkins Build based on build output and email failed log sections

I want to make the build fail by analyzing the results of the console log, for a mac project I am building. It builds each module and gives the results like this:
###################################
XX XXX XXX
##########################
It then returns BUILD FAILED
I want to show that the build failed at the end of the console output, and at the same time I want to know which module failed. It should be sent by email since I am already using the email-ext plugin.
I am unsure of what needs to be done; I am aware of text-finder, log parser and setting the run condition - but do not know what steps to follow.
You will need to use the text-finder plugin and the email-ext plugin together in order to accomplish both your objectives.
First set up the text-finder plugin and provide an appropriate regex. Something like: .*(?i)failed.*|.*(?i)error.* would find the words "failed" or "error" in a case insensitive manner. You will need to specify a path to your log files and probably want to check the "Also search console output" check box.
This will cause any build which outputs "failed" or "error" to fail in Jenkins.
Your requirement to email the module which failed is a little more complex, but possible with the email-ext plugin. This plugin allows you to specify a regex which is used to gather email content using a special token which accepts arguments. The full argument list and token name is: ${BUILD_LOG_REGEX, regex, linesBefore, linesAfter, maxMatches, showTruncatedLines, substText, escapeHtml, matchedLineHtmlStyle}
Most of these arguments are optional, something like this should do the trick for you: ${BUILD_LOG_REGEX, regex=".*(?i)failed.*|.*(?i)error.*", linesBefore=10, linesAfter=10}. Put this in the "Default Content" section of the email-ext configuration. You can specify multiple tokens as well, see this answer for instructions to get the full list: Jenkins Email-ext plugin - tokens
You can of course edit the LinesBefore and LinesAfter parameters to suit your needs.

Resources