How to get Slack notification from Jenkins on creating a new job? - jenkins

I have a Jenkins instance with a bunch of jobs in it. This is shared across developers at the company. Our team would like to be notified whenever someone creates a new job on this instance.
Googling this is so difficult because I'm not looking for information on a specific job, I want an instance-wide hook that alerts Slack when a new job is created on it.
Is this possible? Maybe through a plugin? Or buried in the settings somewhere?

One possibly solution to my own problem is this: https://support.cloudbees.com/hc/en-us/articles/226941767-Groovy-to-list-all-jobs#resolution
Something like this specifically in a "execute system Groovy script" block
import jenkins.model.Jenkins
import hudson.model.*
// This script will print the name of all jobs including jobs inside of a folder, but not the folders themselves
Jenkins.instance.getAllItems(Job.class).each{
println it.name + " - " + it.class
}
Then do an alert based on those results.

Related

list ALL jenkins jobs

I try to use a groovy script to list all Jenkins jobs on a server but it fails to get the jobs that are inside multibranch pipelines. I am only able to get the "freestyle projects".
I use Jenkins.instance.getAllItems(AbstractProject.class) but what I understand from the documentation is that, it will list all jobs implementing the AbstractProject class, which is not the case for the multibranch pipelines. Is there another way to proceed to get those jobs?
The ultimate goal is that sometimes, I want to launch all jobs in a folder. That folder contains over 100 multibranch pipeline with a few branches each. I don't want to trigger each one individually as it would be very time consuming.
Thank you.
I was looking for the same thing to create an extensible choice parameter listing multibranch jobs. So here's what I came up with based on this answer to a similar question: https://stackoverflow.com/a/50163644
def getBranchNames(project){
project.getItems().each { job ->
println(job.getProperty(org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty.class).getBranch().getName())
}
}
getBranchNames(jenkins.model.Jenkins.instance.getItemByFullName("/multibranch-job-name"))
Hope this helps the next person.

Jenkins declarative pipeline parameters

Is there a way to pass in a parameter to a Jenkinsfile from the organization folder instead of the job level or global level?
Essentially what I'm looking to do is have one Jenkinsfile that handles whatever situation I need, and have multiple organization folders that send it parameters. So basically I can have one organization folder that scans and grabs all of the feature branches, and when I run one of the jobs it merges them to develop. Another one that grabs all of the develop branches, and when I run one of the jobs it just builds them. etc.
I need some way to pass parameters to my Jenkinsfile to say "Hey I'm this folder, this is what you should do". I can't find a way to do so. I thought of making multiple Jenkinsfiles but it would be confusing to know which one to place in each repo. I would change the names of the Jenkinsfiles so it's obvious which one to use, but the only option I get for "Project Recognizer" in the configuration is "Pipeline Jenkinsfile" so I don't know how I can change the names and the organization folder still recognize it.
Is there something I'm missing? Any way to send a parameter to my Jenkinsfile from the folder instead of a global level? Or is there some other way to solve my problem and be able to tell my Jenkinsfile what to do depending on what organization folder it is in inside of Jenkins?
Or is there some other way to solve my problem and be able to tell my Jenkinsfile what to do depending on what organization folder it is in inside of Jenkins?
A simple way to check in which organization folder job is built is to parse it from env.JOB_NAME parameter. For example:
Jobs hierarchies:
feature/job1
feature/job2
production/job1
production/job2
To make Jenkins Pipeline to do different functionality whether they are in feature or production organization:
def topFolder = env.JOB_NAME.split('/')[0]
// In code somewhere else:
if (topFolder == 'feature') {
doSomething()
} else if (topFolder == 'production') {
doOther()
}

Setting Jenkins to email a build notification to the BitBucket user who pushed a branch

A project repository has been successfully connected to a Jenkins server using the BitBucket plugin, and a project set up such that:
Each push to a branch in BitBucket will trigger a webhook sent to the Jenkins server
When the Jenkins server receives the webhook it will build the changed branch (by specifying branch name as ** in the config)
After the build is complete a notification is sent back to BitBucket of the build status using the BitBucket notifier
Each of these has been easy to set up with just the instructions in the plugin and a few quick Googles. However I've now run into a problem which is maybe more a matter of wanting to run in an unconventional manner than anything else.
Using the normal emailer plugin or the Email-ext plugin it's possible to set emails to send to people involved in the creation of a build. For example the Email-ext plugin allows choice of:
Requester
Developers (all people who have commits in the build based off its last version)
Recipient list (a pre-set list)
Various "blame" settings for broken builds
The development process being followed involves each project being worked on by one developer in a named branch, e.g. userA/projectB. Obviously other developers could check that out and push to make changes but that's frowned upon. Even in that instance, the user who pushes the change to BitBucket should be notified.
None of the current settings support this. Requester is the closest, but that only works for manual builds. It seems a very simple requirement that the push to SCM that triggered a build should notify the user who pushed, but this is not documented anywhere that is easy to find.
After a lot of searching it seems the only way to accomplish this is by using a Pre-send script. This is added to the Advanced setting of the Email-ext post-build step, and takes the form of code written in Groovy which is a Java extension.
The script can take advantage of Environment variables, but is hard to test as there's no way to run the script with these in place. You can test simple Groovy scripts from Home -> Manage Jenkins -> Script console.
One important "gotcha" with the environment variables is that they are "included" in the script, rather than variables or constants. E.g. before the script compiles and runs, the content of the variable is pasted in place of its $NAME. In the example below the multi-line string syntax is used to include the BitBicket payload, whereas it might be expected that def payload = $BITBUCKET_PAYLOAD would simply work.
import javax.mail.Message.RecipientType
import javax.mail.Address
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeMessage
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def bitbucket = jsonSlurper.parseText('''
$BITBUCKET_PAYLOAD'''
)
switch (bitbucket.actor.username){
case "userA":
msg.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse("user.a#domain.com"));
break;
case "userB":
msg.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse("user.b#domain.com"));
break;
}
The setRecipients command overwrites any existing recipient. Thus the recipient list or other email configuration should be set as a fallback for if the user is not recognised. Additionally, if there is nobody selected to send the email to, the script won't run at all. As added debugging, including the username in the body might help.
If the script fails, stack traces should be printed to the console log output of the test, and the build pass/fail shouldn't be affected, but the normal email address setup will be used instead. In stack traces look for lines with Script() in them, as that's the container which evaluates the Groovy script.

Get the job link in groovy script

We need to update few job configurations accross all jobs and there are several instances of Jenkins running for multiple projects. We need to udpate SCM database path and the SCM password.
I am able to do the database path, but for password there is no set method. So to overcome this, I am just trying to print the link of the job for which we need to update the password. I could not find an API for job link.
Could you please help me out here, or suggest a better solution to update the password?
import hudson.model.*
jenkins = Hudson.instance
for (item in jenkins.items){
println jenkins.getRootUrl()+item.getUrl()
}
Tried this in script console. Lists all jobs absolute URLs. You just need to add the logic to get your jobs list

Jenkins - Trigger email based on input parameter

I have several Jenkins jobs where I want an email to be triggered (or not trigger) based on an input parameter.
The use case is that I have one deploy job per project, but that job is parametrized for each environment. We you run the job you can select which environment to deploy to (Dev1, Dev2, QA, etc). Ideally I would like to send out notification emails when a new build is sent to QA, but I do not want to send out notification emails when a new build is sent to Dev, because that happens all the time (with every developer commit) and would flood email boxes.
I've tried googling but haven't yet found a solution. I am currently using the email-ext plugin.
Thanks.
It is a very nasty way to solve the problem, but if you cannot do it by any other means...
Create a dependent job that exists primarily to pass / fail based on the value of the parameter, which would get passed as a parameter to the job. Then you could chain the decision the job made to the email notification.
Of course, if you were going to do this, it would probably be better to just write a small parametrized email sender using javax.mail and have Jenkins run it by "building" an ANT project that actually calls the "java" task. Then you have your own email sender (full control) and could make it a dependent job on the other tasks.
I hope someone chimes in with a simpler way...
In email-ext you can add a "Script - Before Build" or a "Script - After Build" trigger which will trigger on whether the specified groovy script returns true or false.
The help for the script reads:
Use this area to implement your own trigger logic in groovy. The last line will be evaluated as a boolean to determine if the trigger should cause an email to be sent or now.
They don't give many details of what's available in the script, but from the source code on Github, it looks like you have "build" and "project" at least, and some common imports done for you:
cc.addCompilationCustomizers(new ImportCustomizer().addStarImports(
"jenkins",
"jenkins.model",
"hudson",
"hudson.model"));
Binding binding = new Binding();
binding.setVariable("build", build);
binding.setVariable("project", build.getParent());
binding.setVariable("rooturl", JenkinsLocationConfiguration.get().getUrl());
binding.setVariable("out", listener.getLogger());
Caveat, I haven't tried this, but this should work as an example script:
build.buildVariables.get("MY_DEPLOYMENT_ENV") == "QA"
that should get the value of a String or Choice parameter you've created called "MY_DEPLOYMENT_ENV" and trigger the email if the current value is "QA"

Resources