A bit new to Jenkins and inherited this project that already has a pipeline. I am trying to make some improvements to it, and part of that is adding variables, however I cannot seem to access those variables.
The Jenkinsfile looks something like this:
def pipelineName(String variable1) {
pipeline {
// some code
stage('Run shell command'){
steps {
sh '''
echo "${variable1}"
'''
}
}
// some more code
}
}
pipelineName(variable1='Hello World')
However, when I run this I can see that echo ran but it doesn't actually print anything. I tried different combinations on the variable input, from removing the key to just having Hello World in there but it still did not work. What exactly can I do to have that String used in the shell command?
Related
Problem
I want to modify the path in a docker container to control tool selection without the need to modify existing pipeline code. I've a shared library and client builds call runAnsible which then runs pipeline DSL within a docker container via the docker-workflow-plugin.
However, when I use withEnv docker.inside, I cannot modify path
docker.inside() {
withEnv("PATH=${env.PATH}:/ansible2.10/bin") {
sh 'echo PATH=$PATH'
}
}
When results in PATH= the old path value and not containing my modification. According to JENKINS-45916 that's not a bug but how it works and we all we told - don't do that, use different images etc
So, what options do I have to alter the path beyond making a bunch of very similar images with different paths?
Docker workflow plugin allows args to be passed to the docker run command which creates the container. These args are just a string and its integrity appears respected by the pluign whereas withEnv has some kind of filter in this context.
Therefore, this works but it does assume that I know or can determine the original path. I could run the container without path modification and use a sh(script: 'echo $PATH', returnStdout: true).trim() via docker.inside to get the knownOriginalPath in an earlier step to fee the code below
// hardcoded because I own the image or have determined what the image's path normally is
def knownOriginalPath="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
// my change to the path - in this case, a custom tool location used because I don't want to have to modify a bunch of existing pipeline code.
def pathModification="/ansible2.10/bin"
def desiredPath="${pathModification}:${knownOriginalPath}"
docker.withRegistry(...) {
// for now, the plugin seems to respect the integrity of the inside option string.
docker.image(..)inside("-e PATH=${desiredPath}") {
sh 'echo PATH = $PATH'
}
}
i have configured a Jenkins pipeline job as follows
and env.WORKSPACE works fine
steps {
script
{
echo "${env.WORKSPACE}"
}
}
during build ouput is /home/mach1/workspace
but when i added some lines in post build stage in jenkins pipeline job.
it is returning the following error ${FILE,path="echo "${env.WORKSPACE}"/dir1/file2.html"}
script
{
echo "${env.WORKSPACE}"
}
}
post{
success{
script{
body:'${FILE,path="${env.WORKSPACE}/dir1/file2.html"}'
}
}
}
may i know where its getting wrong, or how do i correct so that in post step it takes /home/mach1/workspace/dir1/file2.html
A shell environment variable is referenced as a key within the env Map within Jenkins Pipeline Groovy, and as a string within the shell step method. In your original example, you referenced the variable as a Groovy variable, and interpolated it within the pipeline with the correct " syntax. However, in your second example, you are still referencing the variable as a Groovy variable, but attempting to interpolate it within the executed shell command from the step method. This will not work, as you will pass a literal string of the env Map variable.
You can fix this either by referencing the environment variable as a shell environment variable by removing the env Map key:
body:'${FILE,path="${WORKSPACE}/dir1/file2.html"}'
or by interpolating the Groovy variable within the pipeline:
body:"\${FILE,path=\"${env.WORKSPACE}/dir1/file2.html\"}"
where characters are properly escaped to denote a shell variable FILE as opposed to a Groovy variable, and for the embedded ".
The first correction is, of course, easier to read, and probably what you will prefer.
In my pipeline, I would like to source a file, setting environment variables like . ./file.sh and keep them set for the rest of the pipeline.
I think this is not implemented given there's an issue opened for some years already https://issues.jenkins-ci.org/browse/JENKINS-10773
At the moment, I tested doing:
stage("Stage") {
steps {
sh ". ./file.sh && env"
sh "env"
}
}
The 2 env output different values. I expect Jenkins to create a new shell every time. Is there an option to not invoke a new shell?.
With what I know, I see 3 possibilities:
Execute all my commands in one sh statement or wrap the execution in a script. The problem is that it makes debugging quite hard.
Source the file at each sh command.
Create a custom groovy function wrapping the call.
The 2 last solutions sound dirty, any suggestion is welcome.
Looks like we can follow environment directive feature to handle both global variable and also stage specific variables.
So in your instance if you define all variables from file.sh within Global scope, then printing will give desired result.
pipeline {
agent any
environment {
myGlobVar = '2020'
}
stages {
stage('Example') {
environment {
myStgeSpecificVar = 2020.2
}
steps {
sh 'printenv'
}
}
}
}
I need to get GitVersion.exe variables in my Jenkins pipeline.
The GitVersion documentation gives a hint on how to do that. Essentially call gitversion /output buildserver.
This call does add the variables to the current step and they are lost once the step completes. I can show this call executes when combining a set command in the same bat execution. The second set shows the variables are gone from the environment.
bat 'nuget install GitVersion.CommandLine -OutputDirectory c:/packages -Version 3.6.5'
bat 'c:/packages/GitVersion.CommandLine.3.6.5/tools/GitVersion.exe /output buildserver && set'
bat 'set'
The documentation of GitVersion is aware of that and suggests to use EnvInject.
Installing the plugin and executing the same pipeline did not change the result. I read that the Plugin is not made for pipelines so that may have something to do with it.
Pipelines support a syntax for environment.
Following that syntax I can set static variables at the top of my pipeline like this:
environment {
ASuperVariable = 'MySuperVariable'
}
What I need is combining those calls so that I can add run time variables to the Jenkinsfile pupeline.
environment {
bat 'gitversion /output buildserver'
}
Now obviously the above call is not even syntax correct. Is there a way to mark a section so that the contained environment changes are available for other steps?
EDIT:
This is still unsolved. At the moment I need to create a batch script and pass the tool into it as an argument. Inside the batch I can call the tool to add to the environment of the batch script and use that wile the batch is running. A Multi line batch in the Jenkins file could be a solution if the process remains the same over all the multiple lines.
Not sure whether you would be able to use scripted pipeline or at least a script block inside declarative. It'd be quite easy doing so:
withEnv(['ASuperVariable=MySuperVariable']) {
echo env.ASuperVariable
}
Or when calling a windows cmd script:
node('win') {
withEnv(['ASuperVariable=MySuperVariable']) {
bat 'echo %ASuperVariable%'
}
}
In my Jenkinsfile, I'm trying to add a environment variable to a file, however not able to do so - seems like some small syntax thing, however I've tried so many different variations.
So the parameter I want is "${params.Spec}", currently used like:
environment {
SPECTORUN = "${params.Spec}"
}
Then in my script block i'm trying:
sh "echo Run:\"${params.Spec}\" >> allure-results/environment.properties"
Any help would be appreciated.
FOUND THE ANSWER HERE:
How to pass variables from Jenkinsfile to shell command