Exporting Console Output of Jenkins Pipeline - github

I have built a pipeline which runs a set of sql scripts to generate results. I would like to be able to export the console output, ideally into a .txt file or .xlsx file. Is this possible? For info I drive the pipeline via GitHub.
Thanks
Tried searching the web but have been unable to find a solution

Do you want to Save the Console output to a file and then Commit it to Github? Check the following sample Pipeline.
pipeline {
agent any
stages {
stage('Sample') {
steps {
script {
echo "Somehitng 1"
echo "Something 2"
// Read the console log
def consoleLog = Jenkins.getInstance().getItemByFullName(env.JOB_NAME).getBuildByNumber(Integer.parseInt(env.BUILD_NUMBER)).logFile.text
//Write the log to a file
writeFile(file: "Log_${BUILD_NUMBER}.txt", text: consoleLog, encoding: "UTF-8")
sh'''
git add *
git commit -m "Add console log"
git push
'''
}
}
}
}
}

Related

How to read file through jenkins from github

I am trying to read a file from github using readFile,
sshagent (credentials: ["${github_cred}"]) {
script {
sh """
git checkout test_branch
"""
def file = readFile(file: "/myrepo/${params.value}.txt")
But in other case, this file will not be available for certain parameters passed. So I would like to check if the file exists in github and proceed with the next steps if it is available or else it should skip the stage.
First Try:
When I try to do with the above code, it is throwing NoSuchFileException when it is not available. I tried with fileExists function which actually works only on the controller node, not on the github. Is there any possible to achieve this?
Second Try:
I also tried with git show as below but I got illegal string body or character after dollar sign error, I don't know what is wrong here.
git show HEAD~1:/myrepo/"${params.value}".txt > /dev/null 2>&1
The fileExists should run in the current node the Pipeline is running on. So it should ideally work.
if (fileExists("/myrepo/${params.value}.txt") {
def file = readFile(file: "/myrepo/${params.value}.txt")
}
Another easy workaround is to wrap your readFile with a try-cath given you know readFile will fail if the file is not available.
def isSuccess = true
def file = null
try {
file = readFile(file: "/myrepo/${params.value}.txt")
}catch(e) {
isSuccess = false
}
The Jenkins machine is windows or macos or linux?
sh """
pwd
git checkout test_branch
"""
In case it's linux or macos add pwd to see the local full path of the repo
And then use this full path in the readfile

Can't run flutter build from Jenkins

I tried to run a flutter build from jenkins using the following pipeline code :
pipeline {
agent any
stages {
stage('build') {
steps {
bat 'C:\\path_to_doc\\flutter_dev\\flutter\\bin\\flutter.bat build web -t "C:\\path_to_doc\\lib\\src\\main\\main.dart"'
}
}
}
post{
always {
archiveArtifacts artifacts: 'C:\\path_to_doc\\build\\web\\index.html', fingerprint: true, followSymlinks: false
}
}
}
I got this error in jenkins :
I tried to write the flutter build code in a bat file in the root of my flutter project, and then execute this file on the pipeline code, got the same error.
What is the correct way to proceed to avoid this error ?
Jenkins has a habit of reverting to the initial workspace directory for each separate command. Try setting the directory after your steps{ line:
dir('C:\\path_to_doc\\flutter_dev\\flutter\\bin\\') {
bat 'flutter.bat build web -t "C:\\path_to_doc\\lib\\src\\main\\main.dart"'
}
This will ensure that your script will run in this location. So if your pubspec.yaml is in this location, it should be able to find it. In any case, this is a problem with the directory, so if this doesn't work, some manual debugging would be necessary to see what went wrong.

Display jest warning as a warning in the Azure DevOps pipeline build results page

We have an Azure DevOps pipeline which uses self hosted Windows agents with Azure DevOps server 2019. The pipeline runs our front-end tests. For this we use the following command line to run the tests:
npm run jest -- --ci --reporters=default --reporters=jest-junit. Then we use the publish test results task to publish the results.
This all works just fine. However, we noticed recently that the runtime warnings in the tests aren't being displayed anywhere. We have our linter warnings displayed in the build results page by adding the vso formatter like this: npm run nx run-many -- --target="lint" --all --skip-nx-cache=true --parallel --format=vso. However, it doesn't seem jest has any kind of format argument we can use.
Is it possible to take the warnings that display in the jest tests and log them in the results page of the build? Thank you for any help, please let me know if I can provide additional information.
So I ended up using the following PowerShell task to append a version of what #PerryQian-MSFT posted into my jest-setup.js file.
- task: PowerShell#2
displayName: Make test log warnings
inputs:
targetType: 'inline'
script: |
Add-Content -path config/jest-setup.js -value #"
import { command, log } from "azure-pipelines-logging";
const { error, warn } = console;
global.console.error = (...args) => {
error(...args);
log(command("task", "logissue", { type: "error" })(...args));
};
global.console.warn = (...args) => {
warn(...args);
log(command("task", "logissue", { type: "warning" })(...args));
};
"#
I had to change the solution from the GitHub post because I didn't want the tests to fail if they hit a warning, the pipeline should still succeed, just with issues. To fix this I included azure-pipelines-logging as a dependency. Then I was able to use log(command("task", "logissue", { type: "warning" })(...args)); to log in the pipeline whenever a warning is called.

How can we check in Jenkins home directory to Github?

We want to check in the Jenkins home directory into Github, certainly ignoring some files/folders. As we want to have everything defined by code, we try to achieve this using Job DSL & Pipeline DSL (not writing the pipeline script inside Jenkins GUI but having it read from a workspace file - see below).
My problem right now is that, being not very proficient in both DSL's yet, I don't know how to force git to do an initial clone of the remote repo (and later push) inside the home directory - which is a parent directory of the job's directory.
I tried this pipeline:
node('master') {
dir('../..') {
scm {
git {
remote {
github('company/repo', 'https')
credentials('xyz')
}
}
}
}
}
The job itself is defined like this:
pipelineJob('backup') {
definition {
cps {
script(readFileFromWorkspace('pipelines/backup.groovy'))
sandbox(true)
}
}
}
The job fails with this error message:
ERROR: ‘checkout scm’ is only available when using “Multibranch Pipeline” or “Pipeline script from SCM”
So I guess the above used 'pipelineJob(backup)' does not fit. Should I change this, and if, how, or should I take another approach?
Another shot at this was trying to rewrite the pipeline like this:
node {
dir('../..') {
git url: 'https://github.com/company/repo.git'
}
}
But then it won't work because credentials are missing...

How to fix "Test reports were found but none of them are new. Did tests run?" in Jenkins

I am getting the error "Test reports were found but none of them are new. Did tests run?" when trying to send unit test results by email. The reason is that I have a dedicated Jenkins job that imports the artifacts from a test job to itself, and sends the test results by email. The reason why I am doing this is because I don't want Jenkins to send all the developers email during the night :) so I am "post-poning" the email sending since Jenkins itself does not support delayed email notifications (sadly).
However, by the time the "send test results by email" job executes, the tests are hours old and I get the error as specified in the question title. Any ideas on how to get around this problem?
You could try updating the timestamps of the test reports as a build step ("Execute shell script"). E.g.
cd path/to/test/reports
touch *.xml
mvn clean test
via terminal or jenkins. This generates new tests reports.
The other answer that says cd path/to/test/reports touch *.xml didn't work for me, but mvn clean test yes.
Updating the last modified date can also be achieved in gradle itself is desired:
task jenkinsTest{
inputs.files test.outputs.files
doLast{
def timestamp = System.currentTimeMillis()
test.testResultsDir.eachFile { it.lastModified = timestamp }
}
}
build.dependsOn(jenkinsTest)
As mentioned here: http://www.practicalgradle.org/blog/2011/06/incremental-tests-with-jenkins/
Here's an updated version for Jenkinsfile (Declarative Pipeline):
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make build'
}
}
stage('Test') {
steps {
sh 'make test'
script {
def testResults = findFiles(glob: 'build/reports/**/*.xml')
for(xml in testResults) {
touch xml.getPath()
}
}
}
}
}
post {
always {
archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
junit 'build/reports/**/*.xml'
}
}
}
Because gradle caches results from previous builds I ran into the same problem.
I fixed it by adding this line to my publish stage:
sh 'find . -name "TEST-*.xml" -exec touch {} \\;'
So my file is like this:
....
stage('Unit Tests') {
sh './gradlew test'
}
stage('Publish Results') {
// Fool Jenkins into thinking the tests results are new
sh 'find . -name "TEST-*.xml" -exec touch {} \\;'
junit '**/build/test-results/test/TEST-*.xml'
}
Had same issue for jobs running repeatedly (every 30 mins).
For the job, go to Configure, Build, Advanced and within the Switches section add:
--stacktrace
--continue
--rerun-tasks
This worked for me
Navigate to report directory cd /report_directory
Delete all older report rm *.xml
Add junit report_directory/*.xml in pipeline
Rerun the test script , navigate to Build Number → Test Result
Make sure you have one successful build without any failure, only after this you can able to see the reports
Make sure that you have mentioned the correct path against "Test report XMLs" under jenkins configuration, such as "target/surefire-reports/*.xml"
There is no need to touch *.xml as jenkins won't complain even though test results xml file does not change.
if you use Windows slave, you can 'touch' results using groovy pipeline stage with powershell:
powershell 'ls "junitreports\\*.*" | foreach-object { $_.LastWriteTime = Get-Date }'
It happens if you are using a test report which is not modified by that job in that run.
In case for test purpose if you are testing with already created file then, add below command inside jenkins job under Build > Execute Shell
chmod -R 775 /root/.jenkins/workspace/JmeterTest/output.xml
echo " " >> /root/.jenkins/workspace/JmeterTest/output.xml
Above command changes timestamp of file hence error wont display.
Note: To achieve same in Execute Shell instead of above, do not try renaming file using move mv command etc. it won't work , append and delete same for change file timestamp only works.
For me commands like chmod -R 775 test-results.xml or touch test-results.xml does not work due to permission error. As work around use is to set new file in test report settings and command to copy old xml report file to new file.
you can add following shell command to your "Pre Steps" section when configure your job on Jenkins
mvn clean test
this will clean the test
Here's an updated version of the gradle task that touch each test result files.
From Jenkins pipeline script, just call "testAndTouchTestResult" task instead of "test" task.
The code below is with Kotlin syntax:
tasks {
register("testAndTouchTestResult") {
setGroup("verification")
setDescription("touch Test Results for Jenkins")
inputs.files(test.get().outputs)
doLast {
val timestamp = System.currentTimeMillis()
fileTree(test.get().reports.junitXml.destination).forEach { f ->
f.setLastModified(timestamp)
}
}
}
}
The solution for me was delete node_modules and change node version (from 7.1 to 8.4) on jenkins. That's it.