Display HTML page content into Jenkins email - jenkins

I'm trying to display HTML page content into the body of the Jenkins email, i added the following code to the default content section in Editable Email plugin:
${FILE,path="/target/surefire-reports/html/index.html"}
also i tried to add the following code to Pre-send Script in the Email plugin:
def reportPath = build.getWorkspace().child("HealthTestResults.html")
msg.setContent(reportPath.readToString(), "text/html");
both of the two way didn't work and i'm still receiving empty mails.

What about have a try with DSL, if you don't bother have one more Jenkins job
You can:
Add a new build step "Process Job DSLs" (You will need Job DSL Plugin)
Add this Groovy script to "Use the provided DSL script" field
Groovy script
job(jobname_to_your_email_job) {
publishers {
extendedEmail {
recipientList(your_email_list)
defaultSubject(your_subject)
defaultContent(your_default_content)
contentType('text/html')
triggers {
always {
subject(your_subject)
//read your html file and put it in the content field
content(readFileFromWorkspace(path_to_your_html_file))
sendTo {
recipientList()
}
}
}
}
}
}
//This will put your email job to the build queue so your email job will run automatically
queue("Email Report")
And of course, you can customize this part according to the Docs

Tried ${FILE,path="target/surefire-reports/html/index.html"}? ie without the /

Related

How can i stop a remote build in Jenkins if a parameter in the url is not valid?

I run remote builds in Jenkins as follows:
JENKINS_URL/job/JOBNAME/build?token=TOKEN
If i add an extra parameter on the query string as follows:
JENKINS_URL/job/JOBNAME/build?token=TOKEN&User=test#test.com&Key=Wxfder$324
As the first step in the build I want to extract these values ie token, User and Key and do some validation and if not valid , then stop the job.
Is there a Build Step i can use, how can i do this ?
One way to do this is by passing the data you need appending to the build cause. Refer to the following example.
The URL
Note the content assigned to cause= parameter
http://localhost:8080/job/Scripted/build?token=12345678&cause=User:test#test.com,Key:Wxfder$324
The Pipeline
pipeline {
agent any
stages {
stage('Test') {
steps {
script {
def cause = currentBuild.getBuildCauses()[0]
def note = cause.getString("note")
echo "${note}"
}
}
}
}
}
Above will give you the following Output.
[Pipeline] echo
User:test#test.com,Key:Wxfder$324

Show custom form then trigger a job

I want to show a dynamically generated form (for example with a list of currently existing branches) then trigger a job with the selected parameters.
There is Pipeline Input Step but:
You can optionally request information back, hence the name of the step. The parameter entry screen can be accessed via a link at the bottom of the build console log or via link in the sidebar for a build.
I need after clicking "Build" to show the custom form immediately.
A solution I see is to have a third party web-server which generates the form then remotely triggers the job, but I would rather use something available inside Jenkins, so that I would have access to Jenkins internals when rendering the form template (using Groovy).
Is there a solution?
Have you tried the git Parameter Plugin ??
https://wiki.jenkins.io/display/JENKINS/Git+Parameter+Plugin
The final result will populate the list of branches from your repo and you can select the branch you would like to build
Configuration
It's straight forward and it will build the branch that you have selected :)
This will build only 1 branch i.e. no multiple option
IF you want to do the multiple option then it gets tricky....
You have to get the Active Choices Plug-in
https://wiki.jenkins.io/display/JENKINS/Active+Choices+Plugin
Create a shell script(provide permissions)-- get_git_branches.sh
add the following in the shell
#!/bin/bash
GIT_URL=$1
git ls-remote --heads --tags ${GIT_URL} | awk -F" " '{print $NF}'
Configuration
Add the following
tags = []
text = "get_git_branches.sh https://user:pass#bitbucket.org/project/repo_name.git".execute().text
text.eachLine { tags.push(it) }
return tags
Pipeline
node {
echo States
def values = Branches.split(',')
for(value in values)
println value //build them 'mvn build value'
}
I have given the example based on your "e.g. requirement" but if you wish to do something different like you mentioned creating a form Active choice plugin is the best bet as you can create your custom script with choice,textbox,multiple select (basically do a javascript page rendering) the wiki which I have posted above has great examples.
Hope it helps :)
You can write your own Jenkinsfile in groovy syntax and generate your parameters for the build. You can even create your own HTML files with that. It is part of the Pipeline Multibranch Plugin
You can get a view like this:
With following Jenkinsfile:
#!/usr/bin/env groovy
def buildInfo
def gitEnv
pipeline {
agent any
options {
timeout(time: 1, unit: 'HOURS')
}
tools {
nodejs 'NodeJS LTS 8.9.4'
}
parameters {
choice(
choices: 'BUILD_AND_DEPLOY\nBUILD\nDEPLOY_ONLY',
description: '''
Sets the desired build and deployment level
<table>
<thead>
<tr>
<th>Level</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td>BUILD_AND_DEPLOY</td>
<td>BUILD and DEPLOY afterwards</td>
</tr>
<tr>
<td>BUILD</td>
<td>Builds the project and uploads the resulting artifact(s)</td>
</tr>
<tr>
<td>DEPLOY_ONLY</td>
<td>Fetches the latest service artifact and deploys it. Replaces existing service on the agent if present.</td>
</tr>
</tbody>
''',
name: 'deploymentLevel'
)
}
stages {
stage ('Preparation') {
steps {
script {
// maybe do something special with a tag
gitEnv = checkout scm
}
}
}
stage ('Install Dependencies') {
when {
anyOf {
expression { return params.deploymentLevel == 'BUILD' }
expression { return params.deploymentLevel == 'BUILD_AND_DEPLOY' }
}
}
steps {
bat 'npm install'
}
}
stage ('and more ...')
{
// build and ...
}
}
There is also a nice tutorial how to generate the choices from a json: Jenkins dynamic parameters using Extended Choice Parameter Plugin and Groovy
As far as I know ,there is no direct solution for this . What you can try (if it is extremely required ) is you can break this step into two jobs :
A
B
In job A you can hit build and then send a confirmation mail or slack with a form and you can fill the variables from the build . Then in that mail you have to give a url on submit which also passes the required parameters as a GET or POST request .
This url will point to a server side script where with the help of these parameters you can build the job B .If you decide to go with this and get stuck somewhere I can further elaborate .
I see in JENKINS-46971 there is a choice parameter:
def environmentChoices = ['blue', 'green'].join('\n')
def stagingEnvironmentInpit = input( message: "apistaging.evolution-software.com is currently pointed to ${currentEnvironment}. Where do you want to promote to?", ok: 'Deploy', parameters: [choice(choices: environmentChoices, name: 'RELEASE_ENVIRONMENT')] )
echo env.RELEASE_ENVIRONMENT
You could adapt that to your case, defining a branches variable with the list of Git branches:
def branches = sh(returnStdout: true, script: "git for-each-ref --format='%(refname:short)' refs/heads/")
And use that in your input step.

Set the pipeline name and description from Jenkinsfile

I am trying to do a poc of jenkins pipeline as code. I am using the Github organization folder plugin to scan Github orgs and create jobs per branch. Is there a way to explicitly define the names for the pipeline jobs that get from Jenkinsfile? I also want to add some descriptions for the jobs.
You need to use currentBuild like below. The node part is important
node {
currentBuild.displayName = "$yournamevariable-$another"
currentBuild.description = "$yourdescriptionvariable-$another"
}
Edit: Above one renames build where as Original question is about renaming jobs.
Following script in pipeline will do that(this requires appropriate permissions)
item = Jenkins.instance.getItemByFullName("originalJobName")
item.setDescription("This description was changed by script")
item.save()
item.renameTo("newJobName")
I'm late to the party on this one, but this question forced me in the #jenkins chat where I spent most of my day today. I would like to thank #tang^ from that chat for helping solve this in a graceful way for my situation.
To set the JOB description and JOB display name for a child in a multi-branch DECLARATIVE pipeline use the following steps block in a stage:
steps {
script {
if(currentBuild.rawBuild.project.displayName != 'jobName') {
currentBuild.rawBuild.project.description = 'NEW JOB DESCRIPTION'
currentBuild.rawBuild.project.setDisplayName('NEW JOB DISPLAY NAME')
}
else {
echo 'Name change not required'
}
}
}
This will require that you approve the individual script calls through the Jenkins sandbox approval method, but it was far simpler than anything else I'd found across the web about renaming the actual children of the parent pipeline. The last thing to note is that this should work in a Jenkinsfile where you can use the environment variables to manipulate the job items being set.
I tried to used code snippet from accepted answer to describe my Jenkins pipeline in Jenkinsfile. I had to wrap code snippet into function with #NonCPS annotation and use def for item variable. I have placed code snippet in root of Jenkinsfile, not in node section.
#NonCPS
def setDescription() {
def item = Jenkins.instance.getItemByFullName(env.JOB_NAME)
item.setDescription("Some description.")
item.save()
}
setDescription()

How to send an email to requester only if the build is triggered manually?

I would like to configure a project in Jenkins to send emails to the recipients group for regular scheduled builds, but only to the requester in case the build is triggered manually. Is this possible?
You should be able to accomplish this by using the "Script - After Build" trigger of the Editable Email Notification post-build action. You can run a groovy script, with the last line evaluating to a Boolean, which determines whether or not to send the email. The screenshot below shows the trigger section that checks to see if the build was initiated by a user (manually).
This script will only tell you whether or not the IMMEDIATE cause of the build was a manual user action, though. Depending on how your build pipeline is setup, one of your upstream jobs may have been initiated manually, so I'm not sure if you want an email sent in that case. If you do, you will have to iterate through all the build causes and look for a manual cause.
def boolean wasStartedManually(causes) {
boolean manuallyStarted = false
causes.each { cause ->
if (cause.class == hudson.model.Cause$UserIdCause) {
manuallyStarted = true
}
if (!manuallyStarted) {
if (cause.class == hudson.model.Cause$UpstreamCause) {
manuallyStarted = wasStartedManually(cause.upstreamCauses)
}
}
}
return manuallyStarted
}
wasStartedManually(build.getCauses())
You will need to add 2 post-build Email actions to your job, one for when the job is triggered manually, and then another if the job was not submitted manually. For the latter, you would run the same script, but just negate the results.

Quickly testing Jelly templates in email-ext of Jenkins

The Email-ext of Jenkins allows you to write a Jelly email template. How do you write and test one without triggering a build every time? Basically, I'm looking for a 1 second iteration where I can modify a Jelly script, hit refresh on a browser, and it will automatically render the template based upon a hard-code project and build result.
Open Jenkins script console at _http://server/script/ (Stackoverflow is having issues saving an edit when this is an actual URL).
Enter the following code and replace your-project-name with the name of your project and me#me.com with your email address:
import hudson.model.StreamBuildListener
import hudson.plugins.emailext.ExtendedEmailPublisher
import java.io.ByteArrayOutputStream
def projectName = "your-project-name"
def project = Jenkins.instance.getItem(projectName)
try
{
def testing = Jenkins.instance.copy(project, "$projectName-Testing")
def build = project.lastUnsuccessfulBuild
// see the javadoc for the Job class for other ways to get builds
def baos = new ByteArrayOutputStream()
def listener = new StreamBuildListener(baos)
testing.publishersList.each() { p ->
println(p)
if(p instanceof ExtendedEmailPublisher) {
// modify the properties as necessary here
p.recipientList = 'me#me.com' // set the recipient list while testing
// run the publisher
p.perform((AbstractBuild<?,?>)build, null, listener)
// print out the build log from ExtendedEmailPublisher
println(new String( baos.toByteArray(), "UTF-8" ))
}
}
}
finally
{
if (testing != null)
{
testing.delete()
}
}
SOURCE: https://earl-of-code.com/2013/02/prototyping-and-testing-groovy-email-templates/
There is also an issue that tracks making this easier:
JENKINS-9594 - Should be able to send test e-mail based on previous build
There is now an option to test templates against builds in the more recent versions of the plugin. When you are on a job's screen, there should be a link on the left side that says Email Template Testing. It will let you select a build to test again and it will render the template right there.

Resources