Trigger deployment job from Multibranch pipeline Jenkinsfile - jenkins

So, we are currently using Multibranch pipeline to run our Continuous Integration process and the last stage is publish the deployable artifact in our JFrog Artifactory "dev" repository and this works!
My problem is that, if I want to automatically trigger a new Jenkins job to take that deployable artifact and deploy it into an integration server and run functional tests then I imagine I would do something like this at the end of my Jenkinfile:
stage("trigger artifact deployment") {
build job: deploymentPipeline,
parameters: [[$class: 'StringParameterValue', name: 'deployableArtifactId', value: "${name}-${version}"],
[$class: 'StringParameterValue', name: 'projectName', value: name],
[$class: 'StringParameterValue', name: 'projectVersion', value: version]],
...
wait: false
}
This approach works! However and because it's a Multibranch pipeline, I would have to hardcode the Jenkins job I want to trigger which I really rather not do but I don't know what else to try as I don't think there would be another way to get the info I need to find the artifact to deploy (ID, version, name, etc.), right?

If you just published it to artifactory, why do you need to find it again? I would add Artifactory properties to the file on upload to enable easier retrieval again.
https://www.jfrog.com/confluence/display/RTF/Properties

Related

How to get build number as a parameter for downstream job from upstream job with declarative pipeline code

I have Two jobs like one is CI jod & another one is CD. I want CI build number should use on CD number.. Can you please help me with declarative pipeline script to get build number as a parameter. here CI job is calling CD job.
Jenkins already provides a simple means to access the number of the current build using env.BUILD_NUMBER. So if you wanted to pass the build number of CI to the downstream job CD, you could do
build([
job : 'CD',
parameters: [
string(name: 'MAIN_BUILD_NUMBER', value: "${env.BUILD_NUMBER}")
]
])
Then in the CD job, declare a parameter like this:
parameters {
string(defaultValue: null, description: 'Build No', name: 'MAIN_BUILD_NUMBER')
}
You should then be able to use ${env.MAIN_BUILD_NUMBER} anywhere in your CD jobs' Jenkinsfile.

Build a Jenkins pipeline (job) from another repo on another branch

What I am trying to do doesn't seem so complex but not so easy, but what I've read by now seems to make it look like I am launching rockets.
Basically let's say I have
my-deploys-repo with branches: master, develop
my-tools-repo with whatever branches
Inside my-tools-repo I have: Jenkinsfile-push-events ( jenkins pipeline )
Inside my-deploys-repo I have ON DEVELOP BRANCH: Jenkinsfile-deploy (which also gets some params, if it matters )
How can I trigger Jenkinsfile-deploy job from my-deploys-repo's develop branch FROM Jenkinsfile-push-events on my-tools-repo?
I understood that normally I'd do something like (inside Jenkinsfile-push-events)
stage('Deploy') {
steps {
script {
build job: '../my-deploys-repo/Jenkinsfile-deploy'
}
}
But it laying on another branch seems like a problem.
A Job in Jenkins has its definition in its properties and that already includes Jenkinsfile, so you cannot trigger a "Jenkinsfile" without defining a Job that uses that Jenkinsfile first.
If you have two branches, you need a Multibranch Pipeline job.
Let's say you created a new Multibranch Pipeline job — say MyJob is its name — that is configured to use your repo (my-deploys-repo.git) and your path to Jenkinsfile (Jenkinsfile-deploy.groovy). You can then trigger that job by:
build job: "MyJob/develop", wait: false, propagate: false,
parameters: [
string(name: 'PARAM_1', value: "1"),
string(name: 'PARAM_2', value: "maybe"), //etc.
]

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.

Can a Jenkins Pipeline write/configure a separate Jenkins job?

I've got a Jenkins pipeline that builds docker images and tags them with the git hash. I also have another parameterized Jenkins pipeline that takes in a couple of string/choice parameters for deployment of the docker images. I'd love for the build pipeline to append some strings to the choice parameters in the deployment pipeline, so that when a user runs the deployment pipeline, he/she is just presented with a list of recently successfully built docker images to choose from.
Anyone know how to do this?
One way would be for your first job to set an environment variable with the list of recent built image tabs (one per line).
See declarative pipeline environment directive.
Then, following "Dynamic Parameter in Jenkinsfile?", you can use an external function like:
#!/bin/groovy
def envs = loadEnvs();
properties([
parameters([
choice(choices: envs, description: 'Please select an image tag', name: 'Env')
])
])
That should be enough to build a choice parameter list.
"Pipeline: How to manage user inputs " (May 10th, 2017, two weeks ago) shows an alternative command, but not valid in the Declarative Pipeline syntax:
You have to use the input step to achieve it.
It will give you something like this :
stage 'promotion'
def userInput = input(
id: 'userInput', message: 'Let\'s promote?', parameters: [
[$class: 'TextParameterDefinition', defaultValue: 'uat', description: 'Environment', name: 'env'],
[$class: 'TextParameterDefinition', defaultValue: 'uat1', description: 'Target', name: 'target']
])
echo ("Env: "+userInput['env'])
echo ("Target: "+userInput['target'])

Jenkins pipeline with folder plugin. How to build a job located different folder

I'm using jenkins 2.0 with Cloudbees Folder plugin as this allow me to create multiple similar projects. The jobs in each folder can be factored out leaving a top level job that can then call a parameterised job.
I want to place the parameterised job in a Generic folder and then call them from a pipeline script.
So within the jenkins browser I would have 3 folder : ProjA, ProjB and Generic. Under ProjA I have a pipeline job that needs to build a job called TestJib in the generic folder.
My pipeline is like this this :
node('master'){
stage ('Run job'){
build job: "../Generic/TestJob",
parameters: [[$class: 'StringParameterValue', name: 'testa', value: tests]]
}
}
Running this gives : 'ERROR: No parameterized job named ../TestJob'
I have tried many variations on build job: "../Generic/TestJob" but I always get the same error.
This works fine if I put the TestJob in the same folder as the pipeline job.
You have only to set the folder without slash before.
If you have a JobA in folder FolderA, your job will look something like:
stage ('My Stage'){
build job: "FolderA/JobA",
}
So for you, your solution will be:
node('master'){
stage ('Run job'){
build job: "Generic/TestJob",
parameters: [[$class: 'StringParameterValue', name: 'testa', value: tests]]
}
}
No matter where your job is located, you just need to indicate the full path.

Resources