How can I use the value from "Run Parameter" in "Copy artifacts from another project" for our Jenkins job? - jenkins

I have a Jenkins job I want to use to run automation on a build created in another job. I want the user to specify that build job's build number using the drop-down box created by the Run Parameter plug-in and then have the automation job copy the artifacts from the user-specified build job.
These are the settings for Run Parameter:
Name: BUILD_SELECTOR
Project: Foo
Filter: All Builds
The user then selects a build like which is saved to BUILD_SELECTOR like "https://blah.com/job/Foo/4/"
Then later in my job, I have Copy artifacts from another project and I want to copy the artifact from the job selected above:
Project Name: Foo
Which build: ?
This is where I get stumped. I have tried the URL above as a permanent link and also tried stripping out the "4" above for Specific build, but nothing seems to work. How can I use that value to do what I need to do?

As stated in https://issues.jenkins-ci.org/browse/JENKINS-21519
You can use ${BUILD_SELECTOR_NUMBER} to get just the build number which you can use with specific build.

Related

Jenkins pipeline share information between jobs

We are trying to define a set of jobs on Jenkins that will do really specific actions. JobA1 will build maven project, while JobA2 will build .NET code, JobB will upload it to Artifactory, JobC will download it from Artifactory and JobD will deploy it.
Every job will have a set of parameters so we can reuse the same job for any product (around 100).
The idea behind this is to create black boxes, I call a job with some input and I get always some output, whatever happens between is something that I don't care. On the other side, this allows us to improve each job separately, adding the required complexity, and instantly all products will get benefit.
We want to use Jenkins Pipeline to orchestrate the execution of actions. We are going to have a pipeline per environment/usage.
PipelineA will call JobA1, then JobB to upload to artifactory.
PipelineB will download package JobC and then deploy to staging.
PipelineC will download package JobC and then deploy to production based on some internal validations.
I have tried to get some variables from JobA1 (POM basic stuff such as ArtifactID or Version) injected to JobB but the information seems not to be transfered.
Same happens while downloading files, I call JobC but the file is in the job workspace not available for any other and I'm afraid that"External Workspace Manager" plugin adds too much complexity.
Is there any way rather than share the workspace to achieve my purpose? I understand that share the workspace will make it impossible to run two pipelines at the same time
Am I following the right path or am I doing something weird?
There are two ways to share info between jobs:
You can use stash/unstash to share the files/data between multiple jobs in a single pipeline.
stage ('HostJob') {
build 'HostJob'
dir('/var/lib/jenkins/jobs/Hostjob/workspace/') {
sh 'pwd'
stash includes: '**/build/fiblib-test', name: 'app'
}
}
stage ('TargetJob') {
dir("/var/lib/jenkins/jobs/TargetJob/workspace/") {
unstash 'app'
build 'Targetjob'
}
In this manner, you can always copy the file/exe/data from one job to the other. This feature in pipeline plugin is better than Artifact as it saves only the data locally. The artifact is deleted after a build (helps in data management).
You can also use Copy Artifact Plugin.
There are two things to consider for copying an artifact:
a) Archive the artifacts in the host project and assign permissions.
b) After building a new job, select the 'Permission to copy artifact' → Projects to allow copy artifacts: *
c) Create a Post-build Action → Archive the artifacts → Files to archive: "select your files"
d) Copy the artifacts required from host to target project.
Create a Build action → Copy artifacts from another project → Enter the ' $Project name - Host project', which build 'e.g. Lastest successful build', Artifacts to copy '$host project folder', Target directory '$localfolder location'.
The first part of your question(to pass variables between jobs) please use the below command as a post build section:
post {
always {
build job:'/Folder/JobB',parameters: [string(name: 'BRANCH', value: "${params.BRANCH}")], propagate: false
}
}
The above post build action is for all build results. Similarly, the post build action could be triggered on the current build status. I have used the BRANCH parameter from current build(JobA) as a parameter to be consumed by 'JobB' (provide the exact location of the job). Please note that there should be a similar parameter defined in JobB.
Moreover, for sharing the workspace you can refer this link and share the workspace between the jobs.
You could use the Pipelines shared groovy libraries plugin. Have a look at its documentation to implement libraries that multiple pipelines share and define shared global variables.

Get build number of triggering project in Jenkins

I configured a Jenkins project B to run when project A completes succesfully.
How can I find the buildnumber of A in the project B pipeline?
If you just need the last successful build of A you can just read it from Jenkins:
http://JenkinsMaster:Port/job/MyJob/lastSuccessfulBuild/buildNumber
If you need the build the triggered B you can use the Parametized Trigger Plugin and use :
TRIGGERED_BUILD_NUMBER_MyJob="Last build number triggered"
You can do the following:
Use the Execute windows batch or Execute shell build step to store the build version in a file during the build of project A - e.g. from a windows batch:
echo "VARIABLEA=%BUILD_NUMBER%" > %WORKSPACE%\myartifact.properties:
Use the Archive the artifacts post build step to store the file against that build in project A
At the start of project B use the Copy artifacts from another project build step, point to project A and use the Artifacts to copy field to filter down to the file you created and choos Last successful build for the Which build field
Read the file in a shell script during the build of project A to pickup the build number
If you output the artifact in the format:
VARIABLEA=${BUILD_NUMBER}
VARIABLEB=${BUILD_NUMBER}
and you're using Linux on the Jenkins server, you could use the source command to make VARIABLEA and VARIABLEB available in that shell session, e.g.:
source "${WORKSPACE}/myartifact.properties"
echo ${VARIABLEA}
You could then do something with that variable in the shell script.
Alternately, you could simply use the Trigger parameterized build on other projects post build step (which I believe requires the Parameterized Trigger Plugin) on project A and setup project B to accept those parameters.

Triggering the same jenkins job after the build is finished in Jenkins

Is there a way to trigger the same job when the build is finished. I have one job that needed to be run until I aborted it manually. Is there a way to accomplish this?
The easiest way to do this is to add a post build step that builds the same project. Set "Post-build Actions" - "Build other projects" - "Projects to build" to the name of your project and it will loop forever.
This is a pretty crazy request. Are you sure that's what you want to do? If you just want to keep up to date you could just have the job build when the SCM system changes- even down to using the filesystem as an SCM.
If you really want to do it though, it is possible. You can't just tell it to trigger itself, but you can use the REST api.
Add a shell build step with the line
curl -X POST http://localhost:8080/job/Tester/build
and a new job will get scheduled each time you run build.
There is "Build after other projects are built" under "Build Triggers" in job configuration page in which you can specify which project to build after which project. So if you want to continuously run a particular job, you can add Project name i.e your job name in "Projects to watch" field under "Build after other projects are built" and can run it with options :- Trigger only if build is stable
Trigger even if the build is unstable
Trigger even if the build fails
you can try
add build step to create few files - file per condition set
add build step Trigger/call builds on other projects with add parameter factories with For every matching file, invoke one build
the called project might have input file as a parameter - it would be passed from the parent project from #2.

Parameter List in Jenkins to display list of build numbers from another build

I have two Jenkins builds, one for compiling and one for deploying.
The developer wants to be able to choose a build from the compiler build when running the deploy build, not always run the most recent build.
What I am after is a method of populating a choice parameter for the deploy build with a list of successful\unstable builds from the compile build.
I will then use the the option listed in the parameter to deploy that artifact.
Using the Dynamic Parameters plugin
In your promote job:
[x] This build is parameterized
Add Parameter
Dynamic Choice Parameter
Set Name to whatever
Paste below into Choices Script
import jenkins.model.Jenkins
import hudson.model.AbstractProject
import hudson.model.Result
import hudson.util.RunList
AbstractProject<?, ?> otherJob = Jenkins.getInstance().getItemByFullName("otherJobName", AbstractProject.class)
RunList<?> builds = otherJob.getBuilds().overThresholdOnly(Result.SUCCESS)
def list = builds.limit(5).collect { it.number }
Screenshot from wiki page:
As Dynamic Parameters plugin is no more accessible. You can use Active Choice parameter plugin in Jenkins.
Now you can list all successful Jenkins builds as parameterized option in Jenkins Job/pipeline
Follow below steps to access the list of successful jobs [as dropdown list]
In job configuration [General section] select this project is parameterized
Select add parameter as "Active choice parameter"
Give name for parameter
Select groovy script and paste below code in groovy script text box
return jenkins.model.Jenkins.instance.getJob('<Jenkins-job>').builds.findAll{ it.result == hudson.model.Result.SUCCESS }.collect{ "$it.number" }
It worked awesome without without powershell and BASH
No need to process Jenkins API and filter JSON output
One option is to use the Promoted Builds plugin to mark a specific build to be deployed. This moves the choice from the deployment build into the compilation build. Select the Promote builds when... option in the compilation build and set up how you want promotion to work. The developer could choose (or automate) the build to promote. In the deployment build, the Copy Artifact plugin can grab the appropriate build (based on a permalink to the latest promoted build).
As far as I know, it is not possible to populate the choice parameter. However, you don't need to always use the newest build. I assume that you use the copy artifact plugin. This plugin provides the "Build selector for Copy Artifact" parameter. You still need to enter the build number manually, but when deploying you have all the standard choices, like "Latest successful build", but also "Specific Build". You need to enter the number and don't have a drop down, but I got my deployers trained well enough to enter the build number.

Copying artifacts from multiple upstream jobs at join in Jenkins

Is it possible to have a Jenkins Job with has been triggered by the Join plugin copy artifacts from multiple upstream jobs?
I'm trying to set-up a Jenkins configuration with a "diamond" of jobs: my-trigger runs and spawns two jobs, my-fork1 and my-fork2, that can run concurrently and take varying amounts of time, and the Join plugin sets off the job my-join once both forks have completed.
Each of my-trigger, my-fork1 and my-fork2 creates and fingerprints artifacts (say, text files).
I want to copy the artifacts from each of the upstream jobs in my-join using the "Copy artifacts from another project" tool, with the "Which build" parameter set to "Upstream build that triggered this job". However, I see output like this in the console of my-join:
Building remotely on build-machine in workspace /path/to/workspace/my-join
Copied 1 artifact from "my-trigger" build number 63
Copied 1 artifact from "my-fork1" build number 63
Unable to find a build for artifact copy from: my-fork2
and the job fails. In this case, my-fork2 finished first, so my-fork1 triggered the join step. I believe that that means that my-join only has record of my-fork1 and my-trigger as being upstream. If my-fork1 finishes first, then my-fork2 kicks off the join, and the job fails when trying to copy from my-fork1.
If I change the configuration to copy the artifact from the build "Latest successful build" then the build succeeds, but my-trigger may run many times in succession so there would be no guarantee that my-join is joining related artifacts.
How can I get the join step to copy artifacts from multiple forks upstream?
Note: the second point of this question seems to be asking the same thing, but the only answer there doesn't address it, and has been accepted.
Thanks
tensorproduct
If your builds are parameterized with a unique parameter for each run of the join-diamond, you can use that parameter in the CopyArtifact plugin to determine which build to copy from. You would want to specify "Latest successful build" and qualify it with the parameter and value.
We have a similar situation where I work; multiple simultaneous runs of a join-diamond. The parameter in the build allows the downstream jobs to get the correct artifacts from the upstream jobs.
Step by Step settings of the provided solution from Jason Swager:
Project dependencies:
diamond->fork->diamond_ready
Project "fork":
String parameter "UNIQUE_ID" (only dummy not used inside)
(Creates an artifcat and Archive the artifacts)
Project "diamond_ready"
String parameter: UNIQUE_ID
Copy artifacts from another project
Project name: fork
Parameter filters: UNIQUE_ID=${UNIQUE_ID}
Project "diamond":
Trigger parameterized build on other project
Projects to build: fork
Predefinded parameters: UNIQUE_ID=${BUILD_TAG}
Join Trigger:
Post-Join Actions:
Trigger parameterized build on other projects
Projects to build: diamond_ready
Predefined Generator parameters: UNIQUE_ID=${BUILD_TAG}

Resources