use of copyArtifactPermission for multibranch pipeline - jenkins

I am using more than one agents in my declarative pipeline. i am trying copy artifacts (input.txt) from agent1 to agent2 in same pipeline from last stage? in below code you can see i am giving permission by using copyArtifactPermission to main branch but as i am using multi branch pipeline, i need to give permission to all my branches. how can we define that ?
agent none
options {
copyArtifactPermission('main');
}
stages {
stage('Build') {
agent { label 'agent1' }
steps {
sh 'echo arjun > input.txt'
}
post {
always {
archiveArtifacts artifacts: 'input.txt', fingerprint: true
}
}
}
stage('Test') {
agent { label 'agent2' }
steps {
// this brings artifacts from job named as this one, and this build
step([
$class: 'CopyArtifact',
filter: 'input.txt',
fingerprintArtifacts: true,
optional: true,
projectName: env.BRANCH_NAME,
selector: [$class: 'SpecificBuildSelector',
buildNumber: env.BUILD_NUMBER]
])
sh 'cat input.txt'
}
}
}
}

Related

Jenkins CopyArtifact plugin not working for multibranch pipeline

I have a multi branch pipeline job which is being started by another jenkins pipeline job. I want to copy the artifacts to the upstream (calling) job. When I make simple pipelines it works, but as soon as I have a jobname like PHPDummyApp/feature%2FnewDeploySetup I get an error like
ERROR: Failed to copy artifacts from PHPDummyApp/feature%2FnewDeploySetup with filter: backend.zip
I have tried several variations:
PHPDummyApp/feature/newDeploySetup
PHPDummyApp%2Ffeature%2FnewDeploySetup
feature%2FnewDeploySetup
but they give another error:
Unable to find project for artifact copy: PHPDummyApp%2Ffeature%2FnewDeploySetup
PHPDummyApp/feature%2FnewDeploySetup seems to be actually finding the proper job but not finding the artifact.
I have ensured that the artifact exists:
Working: createartifact Job
pipeline {
agent { label 'php8' }
options {
disableConcurrentBuilds()
copyArtifactPermission('fetchartifact');
}
stages {
stage('Hello') {
environment {
BUILD_DIR="dist"
}
steps {
sh "mkdir ${BUILD_DIR}"
sh "head -c 100000 /dev/urandom >${BUILD_DIR}/dummy1.txt"
sh "head -c 100000 /dev/urandom >${BUILD_DIR}/dummy2.txt"
//archiveArtifacts artifacts: '*.txt', fingerprint: true
zip archive: true, defaultExcludes: false, dir: "${BUILD_DIR}", exclude: '', glob: '', zipFile: 'backend.zip'
}
}
}
}
Working: fetchartifact Job
pipeline {
agent { label 'php8' }
options {
disableConcurrentBuilds()
buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '4')
}
triggers {
upstream 'createartifact'
}
environment {
SOURCE_DIR = "${WORKSPACE}/src"
}
stages {
stage('Fetch Artifact') {
steps {
build 'Artifacttest/createartifact'
step ([$class: 'CopyArtifact',
projectName: 'createartifact',
filter: "backend.zip",
target: 'dist']);
//copyArtifacts(projectName: 'createartifact', target: 'dist');
sh "unzip dist/backend.zip"
sh "ls dist"
}
}
}
}

Jenkins : Copy artifacts from one agent to another from last stage

I am using more than one agents in my declarative pipeline. Is there anyway to copy artifacts (input.txt) from agent1 to agent2? here is my declarative pipeline,
pipeline {
agent none
stages {
stage('Build') {
agent {
label 'agent1'
}
steps {
sh 'echo arjun > input.txt'
}
post {
always {
archiveArtifacts artifacts: 'input.txt',
fingerprint: true
}
}
}
stage('Test') {
agent {
label 'agent2'
}
steps {
sh 'cat input.txt'
}
}
}
}
You can use Copy Artifact Plugin that can do exactly that.
Given your Jenkinsfile, it then turns into this:
pipeline {
agent none
stages {
stage('Build') {
agent { label 'agent1' }
steps {
sh 'echo arjun > input.txt'
}
post {
always {
archiveArtifacts artifacts: 'input.txt', fingerprint: true
}
}
}
stage('Test') {
agent { label 'agent2' }
steps {
// this brings artifacts from job named as this one, and this build
step([
$class: 'CopyArtifact',
filter: 'input.txt',
fingerprintArtifacts: true,
optional: true,
projectName: env.JOB_NAME,
selector: [$class: 'SpecificBuildSelector',
buildNumber: env.BUILD_NUMBER]
])
sh 'cat input.txt'
}
}
}
}
Use stash and unstash.
example from:
https://www.jenkins.io/doc/pipeline/examples/
// First we'll generate a text file in a subdirectory on one node and stash it.
stage "first step on first node"
// Run on a node with the "first-node" label.
node('first-node') {
// Make the output directory.
sh "mkdir -p output"
// Write a text file there.
writeFile file: "output/somefile", text: "Hey look, some text."
// Stash that directory and file.
// Note that the includes could be "output/", "output/*" as below, or even
// "output/**/*" - it all works out basically the same.
stash name: "first-stash", includes: "output/*"
}
// Next, we'll make a new directory on a second node, and unstash the original
// into that new directory, rather than into the root of the build.
stage "second step on second node"
// Run on a node with the "second-node" label.
node('second-node') {
// Run the unstash from within that directory!
dir("first-stash") {
unstash "first-stash"
}
// Look, no output directory under the root!
// pwd() outputs the current directory Pipeline is running in.
sh "ls -la ${pwd()}"
// And look, output directory is there under first-stash!
sh "ls -la ${pwd()}/first-stash"
}

Jenkins: Trigger another job with branch name

I am using Jenkins Pipeline via declarative and I would like to trigger another job with branch name.
For instance, I have two different pipeline(PipelineA -PipelineB) with stages JobA and JobB.
One of the stage for JobA should trigger the JobB via paramater using env.GIT_BRANCH. What I mean, if we trigger the JobA via origin/develop, then it should trigger the 'JobB' and run the stages where it has origin/develop condition.
Meanwhile, we also making some separate changes on JobB and it also has its own GIT_BRANCH expression.Thus I could not able to find a way to manage this separately without affecting JobA. To be clarify, when JobA trigger JobB with origin/stage parameter, due to latest changes on JobB is origin/development whereas GIT_BRANCH is origin/development, I can not able to run the stages which has stage condition.
Here is my script.
stage ('Job A') {
steps {
script {
echo "Triggering job for branch ${env.GIT_BRANCH}"
ret = build(job: "selenium_tests",
parameters: [
string(name: "projectName", value: "Project1"),
string(name: "branchName", value: "env.GIT_BRANCH")
],
propagate: true,
wait: true)
echo ret.result
currentBuild.result = ret.result
}
}
}
parameters {
string(defaultValue: "project1", description: 'Which project do you want to test?', name: 'projectName')
string(defaultValue: "origin/development", description: 'Environment for selenium tests', name:'branchName')
}
stage ('Job B') {
when {
beforeAgent true
expression { params.projectName == 'Project1' }
expression { params.branchName == "origin/stage"}
expression{ return env.GIT_BRANCH == "origin/stage"}
}
steps {
script {
//Do something
}
}
}
Pass down one more param for branch when trigger Job B
stage('Trigger Job A') {}
stage('Trigger Job B') {
when {
allOf {
beforeAgent true
expression { params.projectName == 'Project1' }
expression{ return env.GIT_BRANCH == "origin/stage"}
}
}
steps {
build(job: "selenium_tests/Job B",
parameters: [
string(name: "projectName", value: "Project1")
strint(name: "branchName", value: "${env.GIT_BRANCH}")
],
propagate: true,
wait: true)
}
}
In Job B' Jenkinsfile add one stage as the first stage to switch to desired branch
pipeline {
parameters {
string(name: 'branchName', defaultValue: 'develop')
}
stages {
stage('Switch branch') {
steps {
sh "git checkout ${params.branchName}"
}
}
// other stages
}
}

Different triggers for parallel stages in Jenkins pipeline

I am trying to create a pipeline where there are multiple triggers for it - cron, pull request opened and manual. Hence, I wanted to visualize it accordingly.
This is my code with no triggers applied.
pipeline {
agent any
environment {
CI = 'true'
TRIGGER = 'PULL_REQUEST'
}
stages {
stage('Trigger')
{
parallel{
stage('Daily') {
when {
environment name: 'TRIGGER', value: 'DAILY'
}
steps {
sh 'echo "daily build"'
}
}
stage('Pull Request') {
when {
environment name: 'TRIGGER', value: 'PULL_REQUEST'
}
steps {
sh 'echo "pull request trigger"'
}
}
stage('Manual') {
when {
environment name: 'TRIGGER', value: 'MANUAL'
}
steps {
sh 'echo "Manual"'
}
}
}
}
stage('Build') {
steps {
sh 'echo "build step"'
}
}
stage('Test') {
steps {
sh 'echo "test step"'
}
}
stage('Deliver for development') {
when {
environment name: 'CI', value: 'true'
}
steps {
sh 'echo "delivery for development"'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'echo proceeded'
}
}
stage('Deploy for production') {
when {
environment name: 'CI', value: 'false'
}
steps {
sh 'echo "deploy for production"'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'echo proceeded'
}
}
}
}
I am able to achieve this with the above code :
Now, my objective is to put the triggers in those parallel stages - Daily, Pull Request and Manual. However, I am not able to do so, as trigger is for the complete pipeline and perhaps expected to appear only once in the pipeline. How can I achieve this effect?
These 3 parallel triggers will set some environment variables which will be used in further stages to modify the pipeline flow accordingly, depending on the type of trigger.

Store current workspace path in variable for a later stage

I am using the declarative syntax for my pipeline, and would like to store the path to the workspace being used on one of my stages, so that same path can be used in a later stage.
I have seen I can call pwd() to get the current directory, but how do I assign to a variable to be used between stages?
EDIT
I have tried to do this by defining by own custom variable and using like so with the ws directive:
pipeline {
agent { label 'master' }
stages {
stage('Build') {
steps {
script {
def workspace = pwd()
}
sh '''
npm install
bower install
gulp set-staging-node-env
gulp prepare-staging-files
gulp webpack
'''
stash includes: 'dist/**/*', name: 'builtSources'
stash includes: 'config/**/*', name: 'appConfig'
node('Protractor') {
dir('/opt/foo/deploy/') {
unstash 'builtSources'
unstash 'appConfig'
}
}
}
}
stage('Unit Tests') {
steps {
parallel (
"Jasmine": {
node('master') {
ws("${workspace}"){
sh 'gulp karma-tests-ci'
}
}
},
"Mocha": {
node('master') {
ws("${workspace}"){
sh 'gulp mocha-tests'
}
}
}
)
}
post {
success {
sh 'gulp combine-coverage-reports'
sh 'gulp clean-lcov'
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: false,
reportDir: 'test/coverage',
reportFiles: 'index.html',
reportName: 'Test Coverage Report'
])
}
}
}
}
}
In the Jenkins build console, I see this happens:
[Jasmine] Running on master in /var/lib/jenkins/workspace/_Pipelines_IACT-Jenkinsfile-UL3RGRZZQD3LOPY2FUEKN5XCY4ZZ6AGJVM24PLTO3OPL54KTJCEQ#2
[Pipeline] [Jasmine] {
[Pipeline] [Jasmine] ws
[Jasmine] Running in /var/lib/jenkins/workspace/_Pipelines_IACT-Jenkinsfile-UL3RGRZZQD3LOPY2FUEKN5XCY4ZZ6AGJVM24PLTO3OPL54KTJCEQ#2#2
The original workspace allocated from the first stage is actually _Pipelines_IACT-Jenkinsfile-UL3RGRZZQD3LOPY2FUEKN5XCY4ZZ6AGJVM24PLTO3OPL54KTJCEQ
So it doesnt look like it working, what am I doing wrong here?
Thanks
pipeline {
agent none
stages {
stage('Stage-One') {
steps {
echo 'StageOne.....'
script{ name = 'StackOverFlow'}
}
}
stage('Stage-Two'){
steps{
echo 'StageTwo.....'
echo "${name}"
}
}
}
}
Above prints StackOverFlow in StageTwo for echo "${name}"
You can also use sh "echo ${env.WORKSPACE}" to get The absolute path of the directory assigned to the build as a workspace.
You could put the value into an environment variable like described in this answer
CURRENT_PATH= sh (
script: 'pwd',
returnStdout: true
).trim()
Which version are you running? Maybe you can just assign the WORKSPACE variable to an environment var?
Or did i totally misunderstand and this is what you are looking for?

Resources