Reference part of the parameter in Jenkins plugin "publish over cifs" - jenkins

ALL
Below is my jenkinsfile. I defined a parameter "SVN_TAG" for listing SVN tags. The format of SVN tag is "VERSION-Digit.Digit.Digit". Now I can only only reference the whole parameter in the cifsPublisher "RemoteDirectory" settings. But I want only reference the digit part of the parameter(like "2.2.2"), how should I do this? thanks.
// Jenkins Declarative Pipeline
def PRODUCT_VERSION
pipeline {
agent { label 'Windows Server 16 Node' }
options {
buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10'))
}
environment {
TAG = '${SVN_TAG.substring(SVN_TAG.indexOf(\'-\')+1)}'
}
stages {
stage('Initialize') {
steps {
script {
PRODUCT_VERSION = "3.2.0.1"
}
}
}
stage('Setup parameters') {
steps {
script {
properties([
parameters([
[ $class: 'ListSubversionTagsParameterDefinition',
credentialsId: 'xxxxxxxxxxx',
defaultValue: 'trunk', maxTags: '',
name: 'SVN_TAG',
reverseByDate: false,
reverseByName: true,
tagsDir: 'https://svn-pro.xxxx.net:xxxxxx',
tagsFilter: ''
],
])
])
}
}
}
stage('Build') {
steps {
cleanWs()
checkoutSource()
buildSource()
buildInstaller()
}
}
stage('Deploy') {
steps {
copyArtifacts()
}
}
}
}
def copyArtifacts() {
cifsPublisher(publishers: [[configName: 'Server', transfers: [[cleanRemote: false, excludes: '', flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'builds\\$JOB_BASE_NAME\\${SVN_TAG}', remoteDirectorySDF: false, removePrefix: '\\unsigned', sourceFiles: '\\unsigned\\*.exe']], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true]])
}

Your environment variable idea is the correct way, just use double quotes ("") instead of single ones ('') to allow string interpolation, is it only works on double quotes in groovy. You can read more in the Groovy String Documentation.
So just use something like TAG = "${SVN_TAG.split('-')[1]}".
Then use that tag wherever you need it, you can pass it to relevant functions like copyArtifact or just use it as is: "builds\\$JOB_BASE_NAME\\${TAG}".

Related

How to create custom workspace in Jenkins pipeline running in same machine

I'm upgrading my jenkins job from freestyle to a pipeline job. I have only one machine and no remote machines are being used.
In the freestyle job, I configured the custom workspace using the "use custom workspace" option. In the pipeline job, I'm not getting any option to use custom workspace. I didn't used any agents or nodes.
I'm using the below pipeline script
pipeline {
agent any
options {
disableConcurrentBuilds()
}
stages {
stage('checkout') {
steps {
// Get some code from a GitHub repository
checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'creds', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: "https://******"]], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']])
}
post {
success {
echo "checkout success"
echo "version ${BUILD_NUMBER}"
}
}
}
stage('Build') {
steps {
// Get some code from a GitHub repository
withAnt(installation: 'ant', jdk: 'jdk8') {
bat "ant -DBUILD_NUMBER = ${BUILD_NUMBER} -f AV/build.xml build"
//bat "ant -f AVANCE/build.xml build"
//bat "ant -f AVANCE/build.xml -d dist"
bat 'XCOPY %WORKSPACE%\\AV\\dist\\AV.war %WORKSPACE%\\BUILD_DEPLOYMENT\\ /H /Y'
}
}
post {
success {
echo "build success"
}
}
}
stage('Commit to SVN') {
steps {
bat '''cd %WORKSPACE%\\BUILD_DEPLOYMENT
svn add . --force
svn commit --non-interactive --trust-server-cert -m "committing AV war" --username admin --password admin AVANCE.war'''
}
post {
success {
echo "Committed to SVN"
}
}
}
stage('Copy to jumpbox') {
steps {
// Copy the war file to woodhouse folder
sshPublisher(publishers: [sshPublisherDesc(configName: 'jumpbox', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'Releases/AVPIPELINE/$BUILD_NUMBER/', remoteDirectorySDF: false, removePrefix: 'AV/dist/', sourceFiles: 'AV/dist/AV.war')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
post {
success {
echo "Successfully copied to jumpbox"
}
}
}
stage('Deploy in Dev') {
input{
message "Do you want to deploy in DEV ?"
}
steps {
echo "deploying in dev"
sshPublisher(publishers: [sshPublisherDesc(configName: 'jumpbox', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'sh /shared/BUILD_DEPLOYMENT_SCRIPTS/PUSH-Development.sh /shared/Releases/AVPIPELINE/$BUILD_NUMBER/', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}

Dynamically filling parameters from a file in a Jenkins pipeline

TL;DR:
I would like to use ActiveChoice parameters in a Multibranch Pipeline where choices are defined in a YAML file in the same repository as the pipeline.
Context:
I have config.yaml with the following contents:
CLUSTER:
dev: 'Cluster1'
test: 'Cluster2'
production: 'Cluster3'
And my Jenkinsfile looks like:
pipeline {
agent {
dockerfile {
args '-u root'
}
}
stages {
stage('Parameters') {
steps {
script {
properties([
parameters([
[$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select the Environemnt from the Dropdown List',
filterLength: 1,
filterable: false,
name: 'Env',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script:
"return['Could not get The environemnts']"
],
script: [
classpath: [],
sandbox: true,
script:
'''
// Here I would like to read the keys from config.yaml
return list
'''
]
]
]
])
])
}
}
}
stage("Loading pre-defined configs") {
steps{
script{
conf = readYaml file: "config.yaml";
}
}
}
stage("Gather Config Parameter") {
options {
timeout(time: 1, unit: 'HOURS')
}
input {
message "Please submit config parameter"
parameters {
choice(name: 'ENV', choices: ['dev', 'test', 'production'])
}
}
steps{
// Validation of input params goes here
script {
env.CLUSTER = conf.CLUSTER[ENV]
}
}
}
}
}
I added the last 2 stages just to show what I currently have working, but it's a bit ugly as a solution:
The job has to be built without parameters, so I don't have an easy track of the values I used for each job.
I can't just built it with parameters and just leave, I have to wait for the agent to start the job, reach the stage, and then it will finally ask for input.
Choices are hardcoded.
The issue I'm currently facing is that config.yaml doesn't exist in the 'Parameters' stage since (as I understand) the repository hasn't been cloned yet. I also tried using
def yamlFile = readTrusted("config.yaml")
within the groovy code but it didn't work either.
I think one solution could be to try to do a cURL to the file, but I would need Git credentials and I'm not sure that I'm going to have them at that stage.
Do you have any other ideas on how I could handle this situation?

Use Jenkins WORKSPACE environment variable in Jenkins declarative pipeline parameter

Is there a way to use Jenkins WORKSPACE environment variable in Jenkins declarative pipeline parameters?
Below attempt failed.
pipeline {
parameters {
extendedChoice description: 'Template in project',
multiSelectDelimiter: ',', name: 'TEMPLATE',
propertyFile: env.WORKSPACE + '/templates.properties',
quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_LEVEL_SINGLE_SELECT',
value: 'Project,Template', visibleItemCount: 6
...
}
stages {
...
}
propertyFile: '${WORKSPACE}/templates.properties' didn't work either.
The environment variable can be accessed in various place in Jenkinsfile like:
def workspace
node {
workspace = env.WORKSPACE
}
pipeline {
agent any;
parameters {
string(name: 'JENKINS_WORKSPACE', defaultValue: workspace, description: 'Jenkins WORKSPACE')
}
stages {
stage('access env variable') {
steps {
// in groovy
echo "${env.WORKSPACE}"
//in shell
sh 'echo $WORKSPACE'
// in groovy script
script {
print env.WORKSPACE
}
}
}
}
}
The only way that worked is putting absolute path to Jenkins master workspace where properties file is located.
pipeline {
parameters {
extendedChoice description: 'Template in project',
multiSelectDelimiter: ',', name: 'TEMPLATE',
propertyFile: 'absolute_path_to_master_workspace/templates.properties',
quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_LEVEL_SINGLE_SELECT',
value: 'Project,Template', visibleItemCount: 6
...
}
stages {
...
}
It seems that environment variables are not available during pipeline parameters definition before the pipeline actually triggered.

Active choice parameter with declarative Jenkins pipeline

I'm trying to use active choice parameter with declarative Jenkins Pipeline script.
This is my simple script:
environments = 'lab\nstage\npro'
properties([
parameters([
[$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select a choice',
filterLength: 1,
filterable: true,
name: 'choice1',
randomName: 'choice-parameter-7601235200970',
script: [$class: 'GroovyScript',
fallbackScript: [classpath: [], sandbox: false, script: 'return ["ERROR"]'],
script: [classpath: [], sandbox: false,
script: """
if params.ENVIRONMENT == 'lab'
return['aaa','bbb']
else
return ['ccc', 'ddd']
"""
]]]
])
])
pipeline {
agent any
tools {
maven 'Maven 3.6'
}
options {
disableConcurrentBuilds()
timestamps()
timeout(time: 30, unit: 'MINUTES')
ansiColor('xterm')
}
parameters {
choice(name: 'ENVIRONMENT', choices: "${environments}")
}
stages {
stage("Run Tests") {
steps {
sh "echo SUCCESS on ${params.ENVIRONMENT}"
}
}
}
}
But actually the second parameter is empty
Is it possible to use together scripted active choice parameter and declarative parameter?
UPD
Is there any way to pass list variable into script? For example
List<String> someList = ['ttt', 'yyyy']
...
script: [
classpath: [],
sandbox: true,
script: """
if (ENVIRONMENT == 'lab') {
return someList
}
else {
return['ccc', 'ddd']
}
""".stripIndent()
]
You need to use Active Choices Reactive Parameter which enable current job parameter to reference another job parameter value
environments = 'lab\nstage\npro'
properties([
parameters([
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select a choice',
filterLength: 1,
filterable: true,
name: 'choice1',
referencedParameters: 'ENVIRONMENT',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["ERROR"]'
],
script: [
classpath: [],
sandbox: true,
script: """
if (ENVIRONMENT == 'lab') {
return['aaa','bbb']
}
else {
return['ccc', 'ddd']
}
""".stripIndent()
]
]
]
])
])
pipeline {
agent any
options {
disableConcurrentBuilds()
timestamps()
timeout(time: 30, unit: 'MINUTES')
ansiColor('xterm')
}
parameters {
choice(name: 'ENVIRONMENT', choices: "${environments}")
}
stages {
stage("Run Tests") {
steps {
sh "echo SUCCESS on ${params.ENVIRONMENT}"
}
}
}
}
As of Jenkins 2.249.2 without any plugin and using a declarative pipeline,
the following pattern prompt the user with a dynamic dropdown menu (for him to choose a branch):
(the surrounding withCredentials bloc is optional, required only if your script and jenkins configuratoin do use credentials)
node {
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'user-credential-in-gitlab',
usernameVariable: 'GIT_USERNAME',
passwordVariable: 'GITLAB_ACCESS_TOKEN']]) {
BRANCH_NAMES = sh (script: 'git ls-remote -h https://${GIT_USERNAME}:${GITLAB_ACCESS_TOKEN}#dns.name/gitlab/PROJS/PROJ.git | sed \'s/\\(.*\\)\\/\\(.*\\)/\\2/\' ', returnStdout:true).trim()
}
}
pipeline {
agent any
parameters {
choice(
name: 'BranchName',
choices: "${BRANCH_NAMES}",
description: 'to refresh the list, go to configure, disable "this build has parameters", launch build (without parameters)to reload the list and stop it, then launch it again (with parameters)'
)
}
stages {
stage("Run Tests") {
steps {
sh "echo SUCCESS on ${BranchName}"
}
}
}
}
The drawback is that one should refresh the jenkins configration and use a blank run for the list be refreshed using the script ...
Solution (not from me): This limitation can be made less anoying using an aditional parameters used to specifically refresh the values:
parameters {
booleanParam(name: 'REFRESH_BRANCHES', defaultValue: false, description: 'refresh BRANCH_NAMES branch list and launch no step')
}
then wihtin stage:
stage('a stage') {
when {
expression {
return ! params.REFRESH_BRANCHES.toBoolean()
}
}
...
}

Jenkins declarative pipeline: if-else statement inside parameters directive

I'm trying to display a choice parameter if I have options to choose from, or else display an input text, something like this (which does not work):
pipeline {
agent any
parameters {
if (someOptions) {
choice(name: 'FIELD_NAME', choices: "$someOptions", description: 'Field description')
} else {
string(name: 'FIELD_NAME', defaultValue: '', description: 'Field description')
}
}
environment {
// environment params
}
stages {
// stages
}
}
Is there a way of doing this?
To expand on #Matt Schuchard's comment, here's what this might look like:
def my_param = []
if (someOptions) {
my_param = [$class: 'ChoiceParameter',
name: 'FIELD_NAME',
choiceType: 'PT_SINGLE_SELECT',
description: 'Choose the desired option',
script:
[$class: 'GroovyScript',
fallbackScript:
[classpath: [], sandbox: false, script: 'return ""'],
script:
[classpath: [], sandbox: false, script: "return $someOptions"]
]
]
} else {
my_param = [$class: 'StringParameterDefinition',
name: 'FIELD_NAME',
defaultValue: false,
description: '']
}
properties([
parameters([my_param,
// other parameters
Don't forget to approve Groovy scripts in script approval console.

Resources