Pipeline end without finish the entire pipeline [closed] - jenkins

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 24 days ago.
This post was edited and submitted for review 21 days ago.
Improve this question
I'm having some issues with a Jenkins Pipeline, the build starts and does some steps but then it ends before finish all the steps and doesn't show any error. I have a timeout of 1 hour, but it "ends" at 15 min, sometimes at 8 min. This is showed in Image 1. Sometimes it finishes and shows the entire "normal output" (....Finished: SUCCESS)
I'm Using 3 functions that do the same (I describe just 1):
Select a number of Old Build and delete it if is more older than X days. This is done for SUCCESS, FAILURE and UNSTABLE builds.
The thing is stucking (or Finish) without executing all steps, not for timeout.in some part without any output of Fail or Error. Most of time stuck in SUCCESS function (maybe because i have too much SUCCESS in compared to others).
I don't have enough experience with NonCPS functions and that can be the problem.
Inside the code I'm executing:
#NonCPS
def Funcion_SUCCESS(){
def TOTAL= Jenkins.instance.allItems.findAll() {
it instanceof Job && it.fullName.matches(jobNamePattern)
}
def date_end = new Date( TIME_end ).toString()
def date_start = new Date( TIME_start ).toString()
println(BBLACK+"From " + date_start + " to "+ date_end +NC+"\n")
TOTAL.each { job ->
def builds = []
delete_Items = 0
builds= (job.getBuilds().byTimestamp(TIME_start,TIME_end))
if(!builds.isEmpty())
{
//println ("Builds candidates to Delete for SUCCESS: "+ builds.number)
builds.each {def build ->
if(build.result == hudson.model.Result.SUCCESS && !build.isKeepLog())
{
build.delete()
delete_Items = delete_Items +1
}
}
if(delete_Items > 0){
println(BLUE+delete_Items.toString()+" Builds deleted from "+ job.fullName + " Job"+NC)
}
}
#NonCPS
def Funcion_UNSTABLE(){ Script to detect UNSTABLE jobs ..}
#NonCPS
def Funcion_FAIL(){ Script to detect FAIL jobs ..}
node{
try{
echo 'Clearing workspace before cloning: '
cleanWs()
// Clones the repository from the current branch name
git credentialsId: 'credentialsId', url: repoUrl
Funcion_SUCCESS()
Funcion_UNSTABLE()
Funcion_FAIL()
emailext(body: '${FILE,path="EMAIL.html"}', mimeType: 'text/html', replyTo: '$DEFAULT_REPLYTO', subject: '${DEFAULT_SUBJECT}', to: env.EMAIL)
}
catch (err) {echo "Error detect"}
}
Output that gets stuck:
Output that finishes:

Related

How to make daily Jenkins Jobs Summary Report send to mail in Table format

I tried my best to search and make sure this is not duplicate questions. but didn't get any. so writing it now.
We have Daily Scheduled jobs which runs in night time for our application. so we have our support team who actually make sure all jobs went successfully every night. if not raise a ticket/concern.
Now, Support team checks all this Jobs by going to Jenkins.
We are now looking for option to make this monitoring automated by sending in mail to all stakeholders.
Being said that I have 10 jobs which I want all those jobs listed in a table with Status of execution of last night and send to group of people.
How can we achieve this? is there any Jenkins Plugin which can help us?
Thanks in Advance.
Unfortunately, I was not allowed to use API in our Jenkins due to some security constraints.
so had to go with below solution.
(have added only stage which we need for getting job status. feel free to edit/update as you need)
stage('Get status of Jobs') {
steps {
script {
env.mailText=""
def mailText = "============================================= \n"
//Add your all jobs name in a list.
allDailyJobs = ['Prod/Daily-Jobs/dbBackups', 'Prod/Daily-Jobs/productImport']
allDailyJobs.each() { jobName ->
//Remove the path prefix to get only Job name (to mention in mail report)
def regex = ~"^Prod/Daily-Jobs/"
String just_job_name = jobName - regex
// Get the Job Latest Details
def job_number = getBuildNumber(jobName)
def job_result = getBuildStatus(jobName)
//echo is paragraph format with lines sepearators
mailText = mailText + " Daily Job Name => ${just_job_name} \n"
mailText = mailText + " Build number => ${job_number} \n"
mailText = mailText + " Build Status => ${job_result} \n"
mailText = mailText + " ============================================= \n\n"
}
env.mailText = mailText
}
}
}
// Get the Last Build Numnber for the job.
#NonCPS
def getBuildNumber(String jobName) {
def job = jenkins.model.Jenkins.instance.getItemByFullName(jobName)
return job.getLastBuild().getNumber()
}
// Get the Status of the Job
#NonCPS
def getBuildStatus(String jobName) {
def job = jenkins.model.Jenkins.instance.getItemByFullName(jobName)
return job.getLastBuild().getResult().toString()
}
This stage gives "env.mailText" value which has all jobs details you need. we can use this one to send in mail or chats or to any Hooks.
Important point : this would require script approval in Jenkins to execute the task. so please make sure you have right access for it.
(to avoid this happening again and again, use it without sandbox checkout)
this is how it looks in mail.

Jenkins - Can you trigger a stage/step after working hours and only once (not everyday)?

I have a pretty large repository and need to include static analysis, since it takes far too long (about 4 hours) for a normal working day we have a cron set to trigger the build automatically every morning purely to perform the static analysis stage and the way we have it set up it only does the static analysis if there has been a change in the code otherwise the static analysis becomes redundant.
The problem lies with the cron, because it is set every day we are now losing build history as well as artifacts.
I've tried to conditionally set the cron but that didn't seem to work since it should have triggered the build this morning and didn't.
triggers {
cron ( checkBuildStatus() )
}
def checkBuildStatus(){
if (currentBuild.changeSets.size() > 0){
return '0 4 * * 1-5 '
}
else {
return ''
}
}
Even if the above implementation worked I'm still not convinced that it would solve my problem of "empty" builds.
Is there a way to trigger a stage/step after working hours and only once (not everyday)?
Any advice will be greatly appreciated.
I decided to change my approach and found the best solution. I created a method, it first checks if there has been a change in the code between the current build and the one before it, and also checks that the branch name is 'master'. I then went ahead and checked the day of the week and set the cron to the following day (e.g if the build is on a Monday the cron will be set to Tuesday morning where it will then perform the static analysis stage). Now the cron will only be set if there has been a change in code and always only for the next day (of course until the next week but I'm hoping there will be changes on the master branch at least every week therefore resetting the cron)
def setCronTrigger(){
if (currentBuild.changeSets.size() > 0 && BRANCH_NAME.equals('master')){
Calendar calendar = Calendar.getInstance()
def day = calendar.get(Calendar.DAY_OF_WEEK)
cron = '* 4 * * ' + day
return cron
}
else {
return ''
}
}
well we can try to solve that problem in another way.
let's create one more job, e.g. cronTrigger. That jobs only triggers external job with static analysis.
if (currentBuild.changeSets.size() > 0) {
build(job: externalJobName, parameters: []) // run another job
}
You can keep more build. That possible to changes as well

Jenkins - if statement comparing HOUR is not working

I am trying to add a "validation" stage in Jenkinsfile based on the time. If it is later than 16, validation is required, otherwise not.
the if statement is not working
here I am declaring the variable
HOUR=sh(returnStdout: true, script: 'date +"%H"').trim().toInteger()
and here is the stage
stage('validation') {
steps {
script {
if ( HOUR > 16 ) {
echo "Validation is required, time now is $HOUR"
}
else {
echo "No validation required, time now is $HOUR"
}
}
}
}
and here is the output
Validation is required, time now is 9
the value of the variable HOUR is correct, but the if statement doesnt work correctly
thanks in advance
Try first to refer to your variable with the ${xx} syntax:
if ( ${HOUR} > 16 ) {
Actually, that would be to be defined in an environment step to be working, as ${env.HOUR}, as illustrated here.
The OP Judy1989 confirms in the comment that you can use HOUR, but in two steps:
HOUR=sh(returnStdout: true, script: 'date +"%H"').trim()
...
if ( HOUR.toInteger() > 16 )
You can see an example of such a deferred use in this question.

Send email from Jenkins about total number of builds/ deployments done

I need to send email at the end of day from Jenkins to Sr.Manager about:
(count)Number of Builds , Deployments done for each project in a day.
Eg:
Builds done for today : xx(count) along with the user details( who triggered the build).
Dev deployment done today : y(count) along with the user details( who triggered the deployments).
Stage deployment done today : z(count) along with the user details( who triggered the deployments).
you should create a groovy script to create it , here is a good examples to start with - https://gist.github.com/mubbashir/484903fda934aeea9f30
another great examples are here - https://wiki.jenkins.io/display/JENKINS/Jenkins+Script+Console
this one count all builds , you need to modify it per day and that's it
Hudson.instance.getAllItems(AbstractProject.class).each {project ->
def results = [:]
def total =0
results."$project.name" = [SUCCESS:0,UNSTABLE:0,FAILURE:0,ABORTED:0]
def build = project.getLastBuild()
while (build){
//println "$project.name;$build.id;$build.result"
results."$project.name"."$build.result" = results."$project.name"."$build.result" +1
build=build.getPreviousBuild()
total = total +1
}
if (total > 50){
println "$project.name : $total"
}
results.each{name,map->
map.each{result,count->
println "$name : $result = $count"
}
}
}
"Done"

Jenkins : Sending success email only once a day (though the job is running #hourly)

I have a jenkins job configured to run hourly. I want the success build mail to be sent as email only once a day. Email-Ext gives me the option to send emails for all success , failures etc. But what i wanted is the ability to send success email only once.
This is an old question and you have probably found your own workaround already, but I had a similar need and I thought I'd share my solution anyway. What I was trying to do was generate a once-daily summary email of jobs in a failed state. This is fundamentally very similar to sending a once-daily success report for a single job.
My solution uses a Groovy build step coupled with the Email-Ext plugin's pre-send script feature. I got the idea from the Nabble thread referenced in the comments above. See also Email-Ext Recipes on the Jenkins site.
Here's the initial groovy script that determines which builds are failed, configured under Execute System Groovy Script. You could do something similar to determine whether your build succeeded or failed:
// List the names of jobs you want to ignore for this check
ignore = [ ]
// Find all failed and unstable jobs
failed = hudson.model.Hudson.instance.getView("All").items.findAll{ job ->
job.getDisplayName() != "Daily Jenkins Job Nag" &&
!ignore.contains(job.getDisplayName()) &&
job.isBuildable() &&
job.lastCompletedBuild &&
(job.lastCompletedBuild.result == hudson.model.Result.FAILURE ||
job.lastCompletedBuild.result == hudson.model.Result.UNSTABLE)
}
// Log the job names so the build results are legible
failed.each { job ->
println(job.getDisplayName() +
" " + job.lastCompletedBuild.result +
" at build " + job.lastCompletedBuild.number +
" (" + job.lastCompletedBuild.timestamp.format("yyyy-MM-dd'T'HH:mm ZZZZ") + ")");
}
// Return failure if there are any failed jobs
return failed.size
Then, down in the Editable Email Notification section, I set the Email-Ext plugin to notify on failure. I set Content Type to Plain Text (text/plain), left Default Content empty, and set the following as the Pre-send Script:
failed = hudson.model.Hudson.instance.getView("All").items.findAll{ job ->
job.getDisplayName() != "Daily Jenkins Job Nag" &&
job.isBuildable() &&
job.lastCompletedBuild &&
(job.lastCompletedBuild.result == hudson.model.Result.FAILURE ||
job.lastCompletedBuild.result == hudson.model.Result.UNSTABLE)
}
def output = StringBuilder.newInstance()
output << "<html>\n"
output << " <body>\n"
output << "<p>Jenkins reports the following failed jobs:</p>"
output << " <ul>\n"
failed.each { job ->
url = hudson.model.Hudson.instance.rootUrl + job.url + "/" + job.lastCompletedBuild.number + "/"
output << " <li>"
output << "" + job.displayName + ""
output << " " + job.lastCompletedBuild.result
output << " at build " + job.lastCompletedBuild.number
output << " (" + job.lastCompletedBuild.timestamp.format("yyyy-MM-dd'T'HH:mm ZZZZ") + ")"
output << "</li>\n"
}
output << " </ul>\n"
output << " </body>\n"
output << "</html>"
msg.setContent(output.toString(), "text/html")
The key is that you have access to the msg object, which is a MimeMessage. You can set the content of the MIME message to whatever you want.
In this case, I'm generating a list of failed jobs, but in your case it would be whatever message you want to receive for your once-daily success report. Depending on what you need, you could have Email-Ext send a result for every build rather than just for failed builds.
How about suppressing e-mails if insufficient time has lapsed since the previous e-mail? Although not precisely what was requested, a pre-send script like this might be worth considering for its simplicity?
if (build.result != hudson.model.Result.SUCCESS) {
cancel = true;
}
else {
try {
long minEmailGap = 1000 * 60 * 60 * 16; // 16 hours in milliseconds
File file = new File("/TimestampForMyJob.txt");
if (file.exists() == false) {
file.createNewFile();
}
else {
long currentTime = (new Date()).getTime();
if (file.lastModified() + minEmailGap > currentTime) {
cancel = true;
}
else {
file.setLastModified(currentTime);
}
}
}
catch(IOException e) {
// We can't tell whether the e-mail should be sent out or not, so we do nothing
// and it just gets sent anyway - probably the best we can do with this exception.
}
}
Well, there is no plugin that can do that for you. The default email feature in Jenkins is very simple and it works fine. There is Email-ext plugin though, and this one can do lot more for you.
First of all, with Email-ext, you can configure a specific trigger to send the email notification - it can be on success or failure, which is similar to the default behaviour of Jenkins. But then you have the more refined one, like First failure and Still failing. This will give you a great deal of control on when and to whom (Recipients list, Commiter or Requester) your Jenkins will send an email. In my case a good configuration here will help a lot with email traffic generated by Jenkins. And you can send specific emails in specific situation to specific list of people - great!
The other option, if you really do not need that level of control and want to just to limit the email traffic to one summary per day is to set up a mailing list. Most mailing list engines will let you send a daily digest of all email traffic to the list. It should be enough, although I really do not feel like it is actually a good option on the long term. I would definitely give a try to Email-ext plugin.

Resources