How to get surefire reports form Travis-CI build? - travis-ci

The question says it all really. How can I download or view the surefire-reports generated during a build on Travis?

You can just do
after_failure:
- cat target/surefire-reports/*.txt

Having not found a direct way to access the surefire-report files I came up with the this workaround:
In .travis.yml I added an after_failure hook:
after_failure: print_surefire_reports.sh
In the hook print_surefire_reports.sh I put:
#!/usr/bin/env sh
echo "Current directory is $(pwd)"
echo "\n=== SUREFIRE REPORTS ===\n"
for F in target/surefire-reports/*.txt
do
echo $F
cat $F
echo
done

I am using python html2text in travis after script phase.
My travis script looks like:
after_script:
- python html2text.py target/site/surefire-report.html
surefire-report.html is generated by surefire-report-plugin
See example output here: https://travis-ci.org/rmpestano/dbunit-rules/builds/160170324#L3541

Based on this bug report and this question, there is not a clean way to do this. There are, however, a couple unsupported methods of getting the reports listed in the bug report.
Those may provide options for you to look into, but the Travis CI maintainers have not provided or supported an explicit way to handle this yet. Note that those bug reports/questions are well over a year old too.
The prevailing suggestion in those threads seems to be to have Travis recommit the build artifacts back to the user's repository. This, however, requires authentication, which you probably shouldn't store in your .travis.yml file

Related

Jenkins TestNG plugin does not fetch results from the test-results.xml file

In my project workspace, the test-results.xml file exists inside the target\surefire-reports\testng-results.xml directory. But Jenkins fails to read the XML file and gives below error on console.
TestNG Reports Processing: START
Looking for TestNG results report in workspace using pattern: **\target\surefire-reports\testng-results.xml
Did not find any matching files.
To ensure the file isn't too old, I had checked that the test-results.xml (and other files) belong to the latest test run. The Jenkins server is running on Ubuntu 14.04 LTS.
I'm running my tests in this manner: My project root directory has a run_tests.sh script which looks like this:
#!/bin/bash
if [ "$1" = "" ]; then
echo "Please provide a valid suite XML file name."
else
mvn clean
mvn compile
mvn clean test -Dsurefire.suiteXmlFiles="$1"
fi
I just pass the suite XML file name as a parameter to this script in Jenkins (execute shell).
Please help.
I found the solution for this.
Go to Configure of your Job
in General Tab, you may find
Advanced Button, Click on this
Check the check box of "Use custom
workspace", under this you see the Directory text box, here you copy
your Selenium Workspace Folder, for example mine is
"E:\eclipse\eclipse-workspace\WebDriveTest\"
Scroll down the page
under the Post-build Actions, Publish TestNG Results, TestNG XML
report pattern : give like this
"**/target/surefire-reports/testng-results.xml" (check this path in
the same workspace).
I hope this will help you!.
You should be using / instead of \ (since you mentioned that your Jenkins is running on a UNIX box)
Krishnan, in the testng-users Google Group, pointed out that it could be an issue with my Jenkins project workspace, and it was the same.
I changed the default workspace in my Jenkins project.
So I've added the path "$HOME/myWorkspace/myProject/" in my Jenkins project workspace, and "**/target/surefire-reports/testng-results.xml" in my TestNG setting in the same Jenkins project, and it works!
Thank you Krishan for your help.
Please see my answer in another post here, it should be very clear.
In short, it is caused by the current directory was changed to the default Jenkins workspace, you need set your custom workspace in the Job's Config.
I agree with Krishnan Mahadevan usage of '\' instead of '/' while providing the path for TestNG Report also solved my problem.
Extremely important thing to note here:
When providing path for Root POM in the build section '\' is used
C:\Users\harsh\eclipse-workspace\ProjTwo3\pom.xml
When providing path for TestNG XML report pattern in Publish TestNG Result section
'/' is used
C:/Users/harsh/eclipse-workspace/ProjTwo3/target/surefire-reports/testng-results.xml
Console Output:
channel stopped
TestNG Reports Processing: START
Looking for TestNG results report in workspace using pattern:
C:/Users/harsh/eclipse-workspace/ProjTwo3/target/surefire-reports/testng-results.xml
Saving reports...
Processing 'C:\Users\harsh.jenkins\jobs\MyApplication\builds\12\testng\testng-results.xml'
11.688312% of tests failed, which exceeded threshold of 0%. Marking build as UNSTABLE

How can I get the path of a newly built apk in gitlab after the code is checked in, which I need in the command 'curl' to upload it to ADF

I wrote a python script, which uses boto3 to schedule android app UI test on ADF. My next step is to make gitlab CI work. My test suite program is Java Appium with TestNG, not integrated with the android program.
My problem now is how to get the PATH of files(apk and test.zip) in gitlab repo which needed in curl command to upload the newly build apk(builded after new code checked in) and my test suite.
Actually, foremost, am I in the right track?
Can I use curl in gitlab like that?
If so, what's the path I could use? (if you could shortly explain the storage structure(or say namespace?) or give me some reference). Actually, is it just take the project home directory as '/'?
for test suite, its actually easier, if I figure out what's the path, I could just put it in the home directory.
for the newly built apk, I don't actually know where is it. We use the pipeline, I think the apk file is somewhere in the server. Below is the YAML snippet:
archive_project:
stage: archive
script:
- ./gradlew assembleRelease
only:
- master
- search
artifacts:
paths:
- main/build/outputs/
tags:
- android
- gradle
If not, how can I do that? This actually suit if I am not in the right track as well.
So after you check in code, the runner look at the .gitlab_ci.yml, and runs following its instruction. And this process, happens in the server machine(either yours or gitlab's), so everything is basically the same as you in your computer(sure you will need the right environment, just appoint the right image or docker).
so yes, we could use 'curl' there. For the directory structure, if you have the privilege to login your server(thru ssh, for instance), you could get it easily. Or we could just explore it like what we do locally(pwd, ls, cd). So what I did is I have a script which have some "pwd, ls, cd ", and call this script from yml, then I look at the info it print to help figure out the directory structure. Then I got what I want(the path), then problem solved.
Although I didn't use dependencies, but you might want to read it to get more about how to pass artifacts between jobs.
If you are looking for this problem, hope it helps you.

Trigger Jenkins Build on Perforce submit by keyword

I am wondering if anyone knows if it is possible to trigger a Jenkins build on a Perforce commit, only if it has a certain keyword in it?
My use case is that I am looking to find a way to trigger a Jenkins build that will build a Nuget package of the library I am working on, and place it in the correct Nuget server directory. I don't want to build a Nuget package each and every time I make a submit to Perforce, so I was wondering if it is possible to set up some kind of trigger to only run the Jenkins build if some keyword was included in the changelist description.
Does anyone know if this is possible, or any other possible ideas on how to implement this?
This works for me. I'm sure it could be more efficient, but it works. This looks for the string "buildit" in the changelist description.
First, create a change-submit trigger in Perforce, e.g.,
buildit change-submit //... "/usr/bin/buildthis %changelist%"
(wherever you place it should be writable, and create a file called "description" that should also be writable).
Below is the contents of the buildthis script:
#!/bin/sh
changelist="$1"
P4PORT=perforce:1666
P4CLIENT=myclient
P4USER=myuser
p4 -p $P4PORT -c $P4CLIENT -u $P4USER describe $changelist >/usr/bin/description
if grep -q buildit /usr/bin/description;
then
curl -X POST http://jenkinsserver:port/job/jobname/build?token=TOKEN
else
exit 0
fi

What's the best way to bulk update Jenkins projects?

We have hundreds of Jenkins projects (mostly created from a few templates), often need to make the same change to all of them. e.g. today I need to add a post-build step to delete workspace at the end. Next I need to change the step to copy build result to a shared drive to Nexus repository.
What's the best way to apply such kind of bulk change to Jenkins projects?
You could use Configuration Slicing Plugin which is designed to do this.
It supports many configuration options.
The REST API is quite powerful. The following sequence worked for me:
In loop for all relevant projects (list of projects is available via e.g. /api/xml?tree=jobs[name]):
download config.xml via /job/{name}/config.xml
edit using your favorite scripted xml editor (mine was xmlstarlet)
upload new config xml via /job/{name}/config.xml
Some random notes:
do *BACKUP* before doing anything
I probably could post some bash script example if anyone is interested
Good luck!
EDIT> Example bash script:
#!/bin/bash
jenkinsUrlBase='http://user:token#jenkins'
callJenkins() { # funcPath
curl --silent --show-error -g "${jenkinsUrlBase}${1}"
}
postJenkinsFile() { # funcPath fileName
curl --silent --show-error -g -d "#${2}" "${jenkinsUrlBase}${1}"
}
callJenkins '/api/xml?tree=jobs[name]' | xmlstarlet sel -t -v '//hudson/job/name' | while read projectName ; do
echo "Processing ${projectName}..."
origFile="${projectName}_old.xml"
newFile="${projectName}_new.xml"
callJenkins "/job/${projectName}/config.xml" > "$origFile"
echo " - Updating artifactory url..."
cat "$origFile" \
| xmlstarlet ed -P -u '//maven2-moduleset/publishers/org.jfrog.hudson.ArtifactoryRedeployPublisher/details/artifactoryUrl' -v "http://newServer/artifactory" \
> "${newFile}"
if false ; then
echo " - Commiting new config file..."
postJenkinsFile "/job/${projectName}/config.xml" "$newFile"
else
echo " - Dry run: not commiting new config file"
fi
done
Groovy is by far the best way to bulk update jobs. You may have to do a little digging into the jenkins / plugin api to figure out what api calls to make, but the script console (http://yourJenkinsUrl/script) provides an easy way to play around with the code until you get it right.
To get you started, you can add / remove post-build steps by calling the getPublishersList() method on a job and then calling the add / remove methods.
def publishersList = Jenkins.instance.getJob("JobName").getPublishersList()
publishersList.removeAll { it.class == whatever.plugin.class }
publishersList.add(new PluginConstructor())
If you're not sure what publisher class you need to delete the workspace, I would suggest manually adding the desired configurations to one job, and then run getPublishersList() from the script console on that job. You will see the class you are working with in the list, and then you can go look at the api to see what is required to construct it.
You can then iterate through all your jobs and add the publisher doing something like this:
Jenkins.instance.getView("All Jobs").items.each { job ->
//Maybe some logic here to filter out specific jobs
job.getPublishersList().add(new PluginConstructor())
}
Alternatively, you can use the Jenkins CLI api or the REST api, but in order to update post-build actions, you will have to modify the project configuration xml file (which isn't trivial programmatically configure) and then overwrite the job configuration with the new configuration file.
You can edit the config.xml file with your favorite text tool (I use Python) and then reload the jenkins configuration.
In my setup the jobs are stored in ~/.jenkins/jobs/*/config.xml.
See: https://wiki.jenkins-ci.org/display/JENKINS/Administering+Jenkins
Here is a small example to update foo to bar:
</com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition>
<hudson.model.StringParameterDefinition>
<name>additional_requirements</name>
<description>foo</description>
...
Script:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals, print_function
import sys
from lxml import etree
from collections import defaultdict
def change_parameter_description(config_xml_path, parameter_name, new_description):
tree=etree.parse(config_xml_path)
for tag in tree.findall('.//hudson.model.StringParameterDefinition'):
name_tag=tag.find('./name')
if not name_tag.text==parameter_name:
continue
description=tag.find('./description')
description.text=new_description
tree.write(config_xml_path)
for config_xml_path in sys.argv[1:]:
change_parameter_description(config_xml_path, 'additional_requirements', 'bar')
In this small example a regex would work, but if things span several lines, it is better to work with xml tools :-)
The other answers are great, but if you use pipelines, I'd suggest you to use Pipeline Shared Libraries.
We have all our jobs in a git repository. To develop a new feature we try it in a branch, since it is possible to point just one job to a specific branch. When we need to update them, just merge into master. The jobs are treated as code, with a proper release process.

execute shell step skipped completely in jenkins

I can't seem to run a build execute shell step in Jenkins. I've worked with Hudson in the past on windows and I was able to create shell/batch steps without a problem but I seem to be be missing something here.
It's a fresh jenkins install and I go to "add build step", "execute shell" and enter "echo hi" in the command. I run the build and when I look in the console output, nothing happens.
I've also tried executing a test.sh file which also just echoes hi. I've tested this in both a linux install and an os X installed Jenkins server.
What am I missing in the configuration to run a shell script?
The console output shows that the shell script steps were skipped completely
Started by user admin
Finished: SUCCESS
It looks like Jenkins is not being able to redirect the output from the system. What version of Java are you using? If you're using OpenJDK, could you try with Sun Java/Sun JDK?
First test to try to check if anything is executing at all: add the following to your "Execute Shell"
#!/bin/bash
echo "HELLO WORLD" > /tmp/testfile
Run this and check if there is a /tmp/testfile in on your Linux system, and if it contains the HELLO WORLD text, it means your script is in fact executing.
Which version of Jenkins do you have?
The last good version that I can attest to (last one I know works well at least for us) is 1.447. If you're not using that one, would you be able to try with it?
Also, could you add #!/bin/sh or #!/bin/bash before echo hi on your "Execute Shell" for the Linux system and see if that works.
Also, try running a script using source /path/to/script and see if that works. The script should contain #!/bin/sh or #!/bin/bash as the first line, just to see if that makes a difference.
Note: none of this should be required, but is helpful just to get more information on what's going on. Couldn't fit all this into a comment. I'll update my answer based on your answers to the above, or delete if I can't get anything..
Putting this here for posterity.
I had a Jenkins project configured with Maven running clean test and a execute shell in the pre steps. The logs from Maven where not coming through and the script was not executing. Once I unchecked Build modules in parallel under the Maven build options my logs and scripts started working.
Make sure its in a location where Jenkins can see it, check permissions.

Resources