Jenkins Copy Artifacts from Upstream Job to Downstream and back - jenkins

I have Job A that call to another Job B
Job B know copy from Job A the artifact.
How I can do copy back of another artifact from Job B to Job A?
Job A
//////////
stage('Validation'){
'Binary Scan':{
build job: 'JOB_B'
},
)
}
Job B
/////////
stage('Copy Artifacts from Job A'){
copyArtifacts filter: 'testz.zip',
fingerprintArtifacts: true,
projectName: currentBuild.upstreamBuilds[0].fullProjectName,
selector: upstream()
}
stage('Do something'){
}
stage('Copy Artifacts back to Job A'){
/////?????????
}

From within a project, you can't normally execute arbitrary code into a different project.
What you can do is for the Job B to use archiveArtifacts, and when it completes, the calling job (Job A) can retrieve the artifacts from the instance of Job B it triggered.
The build command will return a job 'handle' that has enough information to let you build a copyArtifacts command.
job A
//////////
stage('Produce artifacts'){
// First, produce some artifacts for Job B and archive them so that they are available to Job B
archiveArtifacts artifacts: "testz.zip"
}
stage('Validation'){
// Invoke Job B (blocks until job B completes)
def jobB = build job: "JOB_B"
// Retrieve artifacts from Job B after it completes
final String artifactsFilter = "build/*.csv"
copyArtifacts filter: artifactsFilter, projectName: "JOB_B", selector: specific("${jobB.number}")
// re-attach the same artifacts to Job A (now that they have been copied back into Job A workspace)
archiveArtifacts artifacts: artifactsFilter
}
Job B
/////////
stage('Copy Artifacts from Job A'){
copyArtifacts filter: 'testz.zip', fingerprintArtifacts: true,
projectName: currentBuild.upstreamBuilds[0].fullProjectName,
selector: upstream()
}
stage('Do something'){
}
stage('Archive Artifacts for Job A'){
// Archive desired artifacts
archiveArtifacts artifacts: "build/**.csv"
}

Related

Use workspace location in the post build script in jenkins

I am trying to use the artifacts created in the workspace post jenkins build in a postbuild shell script.
I am not able to use them as workspace artifacts are automatically getting deleted before it comes postbuild script.
Could anyone help me to address this?
When the post-build stage is running, your workspace is already removed. When you think of it, your regular stage and post-build stage may even be running on different nodes, so there can't be any expectation that the files are in your workspace.
To access your artifacts in the post-build stage, you need to fetch them manually, e.g. by using Copy Artifact plugin:
post {
always {
// fetch artifacts of this job and this number to $WORKSPACE
step([
$class: 'CopyArtifact',
filter: '*',
fingerprintArtifacts: true,
optional: true,
projectName: "${JOB_NAME}",
selector: [$class: 'SpecificBuildSelector',
buildNumber: "${BUILD_NUMBER}"]
])
script {
try {
for(file in findFiles(glob: "*")) {
println "Found file ${file}"
}
} catch(error) {
println "Failed to find files"
}
}
}
}

Copy artifacts from an upstream multi-branch pipeline

I have the following Jenkins setup:
A multi-branch pipeline which sometimes (on certain tag builds) triggers
a pipeline that builds an installer from the upstream artifacts.
In the upstream MB-pipeline, I have the following fragments:
options {
copyArtifactPermission('my-downstream-project');
}
post {
success {
script {
if (isRelease()) {
build job: 'my-downstream-project'
}
}
}
}
The downstream pipeline, I then try to grab the artifacts:
copyArtifacts projectName: 'my-upstream-project',
selector: upstream(),
filter: '*.jar',
fingerprintArtifacts: true
While the downstream build is started, it fails with:
ERROR: Unable to find project for artifact copy: hds-access-code-cache
This may be due to incorrect project name or permission settings; see help for project name in job configuration.
My understanding so far:
While I can't configure the Copy Artifact permission via the configuration UI for the MB-pipeline, the option is accepted and should work.
The examples I can find would use projectName: 'my-upstream-project/tag-name' as that's the actual job. I don't have a fixed branch or tag, though.
How can I correctly access the upstream artifact?
It is possible to pass down the job name as parameter.
Change the upstream pipeline to:
build job: 'my-downstream-project',
parameters: [string(name: 'upstreamJobName', value: env.BRANCH_NAME)]
Add the parameter to the downstream pipeline:
parameters {
string(name: 'upstreamJobName',
defaultValue: '',
description: 'The name of the job the triggering upstream build'
)
}
And change the copy directive to:
copyArtifacts projectName: "my-upstream-project/${params.upstreamJobName}",
selector: upstream(),
filter: '*.jar',
fingerprintArtifacts: true
Et voila:
Copied 1 artifact from "My Upstream Project ยป my-tag" build number 1

How to Copy Artifacts from other Jenkins Job from a Pipeline?

I want to copy a build artifact from another Jenkins Job using the CopyArtifact plugin.
The artifact is created using the following command:
archiveArtifacts artifacts: '_Builds/BuildRelease/**', fingerprint: true
build 'Release Installer'
Within the 'Release Installer' job, I try the obtain the archived artifacts
using the following command within the Pipeline:
stages {
stage('Get Artifacts') {
steps {
step([ $class: 'CopyArtifact',
projectName: "MyBuildJob",
filter: "_Builds/BuildRelease/archive.zip"
])
}
}
When the "Release Installer" Job is executed, the artifact is not found.
Both jobs are executed on the same Build node.
I think my filter rule is missing something. Unfortunately the available Jenkins documentation is a little thin on details and examples.
I believe that the default is to copy from the last successful job. However, it looks like you currently want the upstream job. Here is a snippet:
copyArtifacts fingerprintArtifacts: true, projectName: 'MyBuildJob', selector: upstream()
I generated this code using the snippet generator. It should exist on the left panel of the classic view of a job. The button text reads "Pipeline Syntax" and the url is "my.jenkins.instance.com/pipeline-syntax/"
Specifying an artifact filter is not required, it will copy all of them. However if you want to keep the filter:
copyArtifacts filter: '_Builds/BuildRelease/archive.zip', fingerprintArtifacts: true, projectName: 'MyBuildJob', selector: upstream()

Jenkins Pipeline use parameters from one job to another between stages

We Have a Jenkins pipeline with several stages (powershell).
each stage has one or more jobs to be executed.
I need to use the results of the first job and pass them to the next job at the next stage.
except the pipeline all jobs are powershell.
example:
node('one'){
stage ('Get Info from DB'){
build job: 'test1'
}
stage ('Do Something'){
build job: 'test2' parameters: [string(name: 'PARAM1', value: $PARAM_FROM_test1 )]
}
}
Assuming that you want to retrieve the outputs of the first job test1 and use these outputs in a second job, you can simply in the second job use the copyArtifact class :
step([$class: 'CopyArtifact', projectName: 'test1'])
This is achieved, assuming that in test1 job, you use the ArtifactArchiver class like (for instance):
step([$class: "ArtifactArchiver", artifacts: "*.tgz", fingerprint: true])

How can I trigger another job from a jenkins pipeline (jenkinsfile) with GitHub Org Plugin?

How can I trigger build of another job from inside the Jenkinsfile?
I assume that this job is another repository under the same github organization, one that already has its own Jenkins file.
I also want to do this only if the branch name is master, as it doesn't make sense to trigger downstream builds of any local branches.
Update:
stage 'test-downstream'
node {
def job = build job: 'some-downtream-job-name'
}
Still, when executed I get an error
No parameterized job named some-downtream-job-name found
I am sure that this job exists in jenkins and is under the same organization folder as the current one. It is another job that has its own Jenkinsfile.
Please note that this question is specific to the GitHub Organization Plugin which auto-creates and maintains jobs for each repository and branch from your GitHub Organization.
In addition to the above mentioned answers: I wanted to start a job with a simple parameter passed to a second pipeline and found the answer on http://web.archive.org/web/20160209062101/https://dzone.com/refcardz/continuous-delivery-with-jenkins-workflow
So i used:
stage ('Starting ART job') {
build job: 'RunArtInTest', parameters: [[$class: 'StringParameterValue', name: 'systemname', value: systemname]]
}
First of all, it is a waste of an executor slot to wrap the build step in node. Your upstream executor will just be sitting idle for no reason.
Second, from a multibranch project, you can use the environment variable BRANCH_NAME to make logic conditional on the current branch.
Third, the job parameter takes an absolute or relative job name. If you give a name without any path qualification, that would refer to another job in the same folder, which in the case of a multibranch project would mean another branch of the same repository.
Thus what you meant to write is probably
if (env.BRANCH_NAME == 'master') {
build '../other-repo/master'
}
You can use the build job step from Jenkins Pipeline (Minimum Jenkins requirement: 2.130).
Here's the full API for the build step: https://jenkins.io/doc/pipeline/steps/pipeline-build-step/
How to use build:
job: Name of a downstream job to build. May be another Pipeline job, but more commonly a freestyle or other project.
Use a simple name if the job is in the same folder as this upstream Pipeline job;
You can instead use relative paths like ../sister-folder/downstream
Or you can use absolute paths like /top-level-folder/nested-folder/downstream
Trigger another job using a branch as a param
At my company many of our branches include "/". You must replace any instances of "/" with "%2F" (as it appears in the URL of the job).
In this example we're using relative paths
stage('Trigger Branch Build') {
steps {
script {
echo "Triggering job for branch ${env.BRANCH_NAME}"
BRANCH_TO_TAG=env.BRANCH_NAME.replace("/","%2F")
build job: "../my-relative-job/${BRANCH_TO_TAG}", wait: false
}
}
}
Trigger another job using build number as a param
build job: 'your-job-name',
parameters: [
string(name: 'passed_build_number_param', value: String.valueOf(BUILD_NUMBER)),
string(name: 'complex_param', value: 'prefix-' + String.valueOf(BUILD_NUMBER))
]
Trigger many jobs in parallel
Source: https://jenkins.io/blog/2017/01/19/converting-conditional-to-pipeline/
More info on Parallel here: https://jenkins.io/doc/book/pipeline/syntax/#parallel
stage ('Trigger Builds In Parallel') {
steps {
// Freestyle build trigger calls a list of jobs
// Pipeline build() step only calls one job
// To run all three jobs in parallel, we use "parallel" step
// https://jenkins.io/doc/pipeline/examples/#jobs-in-parallel
parallel (
linux: {
build job: 'full-build-linux', parameters: [string(name: 'GIT_BRANCH_NAME', value: env.BRANCH_NAME)]
},
mac: {
build job: 'full-build-mac', parameters: [string(name: 'GIT_BRANCH_NAME', value: env.BRANCH_NAME)]
},
windows: {
build job: 'full-build-windows', parameters: [string(name: 'GIT_BRANCH_NAME', value: env.BRANCH_NAME)]
},
failFast: false)
}
}
Or alternatively:
stage('Build A and B') {
failFast true
parallel {
stage('Build A') {
steps {
build job: "/project/A/${env.BRANCH}", wait: true
}
}
stage('Build B') {
steps {
build job: "/project/B/${env.BRANCH}", wait: true
}
}
}
}
The command build in pipeline is there to trigger other jobs in jenkins.
Example on github
The job must exist in Jenkins and can be parametrized.
As for the branch, I guess you can read it from git
Use build job plugin for that task in order to trigger other jobs from jenkins file.
You can add variety of logic to your execution such as parallel ,node and agents options and steps for triggering external jobs. I gave some easy-to-read cookbook example for that.
1.example for triggering external job from jenkins file with conditional example:
if (env.BRANCH_NAME == 'master') {
build job:'exactJobName' , parameters:[
string(name: 'keyNameOfParam1',value: 'valueOfParam1')
booleanParam(name: 'keyNameOfParam2',value:'valueOfParam2')
]
}
2.example triggering multiple jobs from jenkins file with conditionals example:
def jobs =[
'job1Title'{
if (env.BRANCH_NAME == 'master') {
build job:'exactJobName' , parameters:[
string(name: 'keyNameOfParam1',value: 'valueNameOfParam1')
booleanParam(name: 'keyNameOfParam2',value:'valueNameOfParam2')
]
}
},
'job2Title'{
if (env.GIT_COMMIT == 'someCommitHashToPerformAdditionalTest') {
build job:'exactJobName' , parameters:[
string(name: 'keyNameOfParam3',value: 'valueOfParam3')
booleanParam(name: 'keyNameOfParam4',value:'valueNameOfParam4')
booleanParam(name: 'keyNameOfParam5',value:'valueNameOfParam5')
]
}
}

Resources