Getting the github webhook payload information inside Jenkins pipeline - jenkins

I need to access the github webhook payload information in my pipeline job through Jenkinsfile. I am able to print the payload using the below snippet:
properties ( [[$class: 'ParametersDefinitionProperty', parameterDefinitions: [[$class: 'StringParameterDefinition', defaultValue: '', description: '', name: 'payload']]]] )
echo ("This build is built with the payload: $payload")
But this works only when I have defined the webhook for that specific job as below:
http://<jenkins url>/job/Demo_GitHubOrg/job/DemoRepo/branch/master//buildWithParameters
My pipeline job scans the given organization and automatically creates jobs/repo/branch.
Is there a way to write a more generic webhook that will work for all jobs in my pipeline folder instead of writing one for every job as shown above?

Is there a way to write a more generic webhook that will work for all
jobs in my pipeline folder instead of writing one for every job as
shown above?
Yes, the Generic Webhook Trigger Plugin.

Related

Jenkins: How to start, in a Jenkinsfile, a multibranch job inside a Bitbucket folder?

In a Jenkinsfile, to start a parameterized pipeline job from another job, I have this code snippet:
build job: 'build-sharpen-branch', parameters: [
[$class: 'StringParameterValue', name: 'BRANCHNAME', value: mergeBranchname]
]
This already works as expected, and it will start a job at URL https://$JENKINS_URL/job/build-sharpen-branch/.
Now I want to start a job, that is one branch of a multibranch project inside a Bitbucket folder. The URL of the job is https://$JENKINS_URL/job/iText%207%20.NET/job/sharpen/job/feature%2FQA-10738/.
iText%207%20.NET is the name of the Bitbucket project.
sharpen is the name of the Multibranch job.
feature%2FQA-10738 is the name of the branch, urlencoded.
I read the following questions about starting a multibranch job NOT inside a folder:
Trigger Multibranch Job from another
Triggering a multibranch pipeline job from an other multibranch pipeline
How to trigger Multibranch Pipeline Jenkins Job within regular pipeline job?
From the answers there, I gather that the syntax is $JOB/$BRANCH (where $BRANCH is URL-encoded to rename branches like feature/foo to feature%2Ffoo).
From Jenkins pipeline with folder plugin. How to build a job located different folder I gather that the syntax for a job inside a folder is $FOLDER/$JOB.
Combining the two, I conclude that the syntax for folder+job+branch is most likely $FOLDER/$JOB/$BRANCH.
So I tried with this code:
build job: "iText%207%20.NET/sharpen/${java.net.URLEncoder.encode branchName, 'UTF-8'}"
with
folder = iText%207%20.NET
job = sharpen
branch = ${java.net.URLEncoder.encode branchName, 'UTF-8'} (URLEncoder to change / in the branch name to %2F)
To my surprise, when I ran this, I got an error:
ERROR: No item named iText%207%20.NET/sharpen/feature%2FQA-10738 found
As already stated above, a job exists on URL https://$JENKINS_URL/job/iText%207%20.NET/job/sharpen/job/feature%2FQA-10738/.
What is the correct syntax for a multibranch job inside a Bitbucket folder?
The problem was with the folder name iText%207%20.NET, which is an urlencoded version of iText 7 .NET. Apparently Jenkins can't handle urlencoded spaces in folder names.
I renamed the folder to itext_7_dotnet and then used
build job: "itext_7_dotnet/sharpen/${java.net.URLEncoder.encode branchName, 'UTF-8'}"
This works.
Moral of the story: never use spaces in your folder names!
For us, this works:
build job: "${folder}/${repo}/${branch.replace('/','%2F')}", wait: false, propagate: false
You can also trigger build by using curl, with crumbs and all that.

How to retrieve job name in parameterized Jenkins Pipeline Project

I have a parameterized pipeline project with active choices parameter, where choice list is dynamically populated by groovy script. I need to retrieve and use current job name in the script. The following line works for me in Freestyle Projects:
def jobName = this.binding.jenkinsProject.name
However when I try to use it in Pipeline Project I get:
No such property: jenkinsProject for class: groovy.lang.Binding
In Retrieving Jenkins job name using groovy script in Active Choice Reactive Parameter it's stated that this has been resolved in Active Choices plugin v1.4. I'm using version 2.2.1 and the issue still persists. Is this property not available in Pipeline Project? Is there a workaround or an alternative?
If you trying to get the current build job name inside running job
There is a builtin env variable for it:
JOB_BASE_NAME
You can see list of available env variable in your Jenkins at
http://{hostname}/job/{jobname}/pipeline-syntax/globals
Jest replace hostname with your Jenkins address and jobname with some job you have in your Jenkins.
My Jenkins
Jenkins version: 2.176.2
Active Choices Plug-in: 2.2.1
Worked with pipeline job.
If you trying to do it in the parameters script I'm not sure that possible.
I faced the same issue and came up with a solution.
You can use Jenkins pipeline currentBuild variable, more about its properties - open page jenkins-server-url/jenkins/pipeline-syntax/globals on your Jenkins server
String currentJobParentFolderName = currentBuild.fullProjectName.split('/')[0]
String currentJobName = currentBuild.projectName
String paramValue = getParamValue(currentJobName)
properties([
buildDiscarder(logRotator(daysToKeepStr: '10')),
disableResume(),
parameters([
[$class: 'CascadeChoiceParameter',
name: 'PARAM',
choiceType: 'PT_SINGLE_SELECT',
description: 'param1',
filterLength: 1,
filterable: false,
randomName: 'choice-parameter-99999999999',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script:
'return ["Failed to get values"]'
],
script: [
classpath: [],
sandbox: false,
script:
"""return ['$paramValue']"""
]
]
]
])
])
timestamps {
job's main logic
}
private static def getParamValue(String jobName) {
Map paramValMapping = [
'jobName1': 'value1',
'jobName2': 'value2',
]
String paramValue = paramValMapping.get(jobName)
if (!paramValue) {
throw new Exception("Failed to get value")
}
return paramValue
}
currentBuild.fullProjectName - job name including upper level folders (I needed exactly this)
currentBuild.projectName - just a job name
Unfortunately I didn't manage to place all this logic inside of CascadeChoiceParameter script section.
Also I needed only one value, but this approach can be used for a list of values as well, just don't forget about quotes for string values.
Pay attention that such script changes may require script approve from Jenkins admin in jenkins/scriptApproval for EACH incoming value paramValue
So for everyone who's still looking for a solution to this problem, there are actually three ways you could go about solving this.
The reason why the jenkinsProject variable is not available in Pipeline jobs is due to an issue with the active choices plugin itself. You can read more about this in the following ticket: https://issues.jenkins.io/browse/JENKINS-29407. There's a separate feature branch in the Active Choices project on GitHub that (kinda) solves this issue: https://github.com/jenkinsci/active-choices-plugin/tree/pipeline-support. It wasn't merged into master (and it looks like it never will be), because adding this to Pipeline jobs breaks this functionality for the Freestyle jobs. What you can do is you can compile the plugin from the source yourself and install it on your Jenkins. Pipeline jobs will have the binding variables available in their active choice parameters, however Freestyle jobs will no longer have them. Only use this if the following two options are for some reason not possible in your case.
You can use the properties{} step to configure job parameters from the pipeline run. During pipeline run you could simply use the JOB_BASE_NAME environment variable as an expression of the GString that you'd pass as a script text. The only disadvantage here is that the parameters will only become available after the first build. So if you have a new job you'd need to trigger it once before it becomes parameterized.
You could just use the input() step. Your job won't be parametrized, but users will be able to provide their input to the build during its run. It's not very convenient if you need it to be triggered by some other job or an external webhook, but for cases where the job is expected to only be triggered manually it's probably the best option.

How do I access the payload from a generic webhook in my Jenkinsfile?

I have a multibranch job using a generic webhook and I want to access the JSON payload the Jenkins receives. I unfortunately cannot seem to access it, I cannot define parameters for the multibranch job and I am at a loss.
I would like to determine the cause of the trigger, whether it be from a pull request, a push, a commit, etc. Multibranch pipelines don't allow for me to specify any variables in Jenkins, so I'm a bit confused.
Configure a JSONPath variable with the JSONPath $ and it will be resolved to the entire received JSON.
See also: https://github.com/jenkinsci/generic-webhook-trigger-plugin/blob/master/src/test/resources/org/jenkinsci/plugins/gwt/bdd/jsonpath.feature
And to do this in a multibranch pipeline, your pipeline can look something like this:
properties([
pipelineTriggers([
[$class: 'GenericTrigger',
genericVariables: [
[key: 'everything', value: '$']
],
...
]
])
])
The readme has complete examples on how to use it with Multibranch.
You can access the payload by configuring build triggers in the configure section of the jenkins job.enter image description here

How to make a parameterized multibranch pipeline trigger?

Can you please give me an example of how should the Jenkinsfile config look to be triggered by a curl http trigger-buildwithparameters? I have tried:
properties([parameters(
[string(defaultValue: 'nothing',
description: 'gitcommit',
name: 'somecommit')])])
but it seems that this pipeline won't be triggered by buildwithparameters with a #somecommit parameter. Can bitbucket branch source/multibranch pipelines be triggered by a remote http calls with passed parameters?

How can I pass “build-step parameters” to a downstream project (freestyle project with parameterized triggers)?

I have a Jenkins setup with two freestyle-projects linked via Jenkins upstream/downstream post-build triggers (Jenkins Parameterized Trigger plugin). The upstream project builds something that is uploaded somewhere. And the downstream project picks that new thing up and tests it.
At the moment the downstream project finds the build by date by looking for “the latest”. I want to change that.
I would like to change upstream to generate a random string as filename in the build step and pass that to downstream as parameter. How can I do that?
(I know how to generate a random string – the point is: how to pass build-step information down to the “downstream job”?)
In your upstream pipeline script, add this:
build job: 'your-downstream-job', parameters: [[$class: 'StringParameterValue', name: 'YOUR_STRING_PARAM', value: "${yourRandomGeneratedStringVariable}" ]]
And your your-downstream-job should be e.g. a normal job which is parameterized (check the tick at This project is parameterized), with the StringParameter YOUR_STRING_PARAM.
Then just read the value of this environment variable and you can go on.

Resources