How to execute a groovy script from a jenkins pipeline - jenkins

I am new to Jenkins.
I have written a groovy script, which loads a token secret from an adjacent config.properties file.
What's the best way to execute this script in a groovy pipeline ?
What I think I need to do is:
download that script from SCM
change the token in config.properties (retrieved from the stored jenkins credentials)
execute that script
I've seen various options :
loading the script with load(), but this seems to be more dedicated to loading helper functions, whereas I only need to execute the whole script
using shared libraries, but this seems to be more dedicated to code snippets reused across multiple jobs, which is not my case
using withGroovy {}
using sh groovy
using a docker image that contains a groovy sdk
I tried these, and managed to get none of them to work (in part due to the extra-difficulty of retrieving the credential), so before I go any further I'd like to know what's the best option to proceed. For example, instead of trying to change the file config.properties in my pipeline to set the correct token, should I rather try to change my groovy script so that it takes the token from an environment variable ?
Thanks

Related

Jenkins: Passing a variable between scripts, and accessing it on a post build actions

I have a Jenkins job, with SCM from bitbucket, two shell scripts, and a post build action publishing the result to Slack.
Naively I want to pass a concluded variable in the first shell script to the second, add some information to that variable in the second shell script, and then to append that variable to the Slack custom message.
I was expecting this to be a built in feature, and now spending few days on and off at it. I've tired the EnvInject, Environment Inject, Global Variable String Parameter plugins, but in any configuration I've tried it didn't work.
In some cases I got this error:
21:01:08 [EnvInject] - [ERROR] - The given properties file path 'build.properties' doesn't exist.
I know this file does not exist.. I expected the plugin to create it, so I can add new content to it in first shell script, and to be loaded in every other step of the job.
Am I missing something or misusing these plugins?
So like I've seen it happens too often, after asking the question, I was able to solve it like this:
First we create a shell script to create the file, I've already added a value:
Then we tell Jenkins to inject the variables from the build.properties file:
Then we change the value of the variable in the file:
Then AGAIN we tell Jenkins to inject the variables from the same file:
Then we can observe the value changes in the next shell:
Also in the post build action:
And success:

Environment variable in Jenkins Pipeline

Is there any environment variable available for getting the Jenkins Pipeline Title?
I know we can use $JOB_NAME to get title for a freestyle job,
but is there anything that can be used for getting Pipeline name?
You can access the same environment variables from groovy using the same names (e.g. JOB_NAME or env.JOB_NAME).
From the documentation:
Environment variables are accessible from Groovy code as env.VARNAME or simply as VARNAME. You can write to such properties as well (only using the env. prefix):
env.MYTOOL_VERSION = '1.33'
node {
sh '/usr/local/mytool-$MYTOOL_VERSION/bin/start'
}
These definitions will also be available via the REST API during the build or after its completion, and from upstream Pipeline builds using the build step.
For the rest of the documentation, click the "Pipeline Syntax" link from any Pipeline job
To avoid problems of side effects after changing env, especially using multiple nodes, it is better to set a temporary context.
One safe way to alter the environment is:
withEnv(['MYTOOL_HOME=/usr/local/mytool']) {
sh '$MYTOOL_HOME/bin/start'
}
This approach does not poison the env after the command execution.

How to re-use groovy script in Jenkins Groovy Post Build plugin?

I have some groovy code which I am planning to re-use in Jenkins Groovy Post Build plugin of multiple jobs. How can I achieve this? Is there a place I can store the script in a global variable and call that in the jobs where ever I need?
You can load any groovy file living on the Jenkins master within the groovy postbuild and execute it. For example, you could have a special directory on the c drive where all the common scripts live. I'll update my answer later with some code that shows you how to load the script in.
Update
Assuming you have a test.groovy file on your C: drive, it should be as simple as the following in Groovy Postbuild:
evaluate(new File("C:\\test.groovy"))
Please view the comment section of the Groovy Postbuild for more examples and possibly other ways.
Here is the solution that worked for me:
Installed Scriptler plugin for Jenkins and saved the Groovy script in that. Now the script is available in JENKINS_HOME/scriptler/scripts directory. This way we can avoid manual step of copying files to Jenkins master.
Used the groovy file in Post build:
def env = manager.build.getEnvironment(manager.listener) evaluate(new File(env['JENKINS_HOME'] + "\\scriptler\\scripts\\GroovyForPostBuild.groovy"))
This is a copy of my answer to this similar question on StackOverflow:
If you wish to have the Groovy script in your Code Repository, and loaded onto the Build / Test Slave in the workspace, then you need to be aware that Groovy Postbuild runs on the Master.
For us, the master is a Unix Server, while the Build/Test Slaves are Windows PCs on the local network. As a result, prior to using the script, we must open a channel from the master to the Slave, and use a FilePath to the file.
The following worked for us:
// Get an Instance of the Build object, and from there
// the channel from the Master to the Workspace
build = Thread.currentThread().executable
channel = build.workspace.channel;
// Open a FilePath to the script
fp = new FilePath(channel, build.workspace.toString() + "<relative path to the script in Unix notation>")
// Some have suggested that the "Not NULL" check is redundant
// I've kept it for completeness
if(fp != null)
{
// 'Evaluate' requires a string, so read the file contents to a String
script = fp.readToString();
// Execute the script
evaluate(script);
}

Using parameterized credentials in Jenkins

Say I've got dev, qa, and stable server environments for some web app, with corresponding git branches. Each environment should be continuously integrated. Each of these environments has a separate username/password pair used to publish the app. I would like to make a Jenkins multiconfiguration (matrix) job to publish to all of these environments. The publishing almost certainly must be done with a shell script.
My failed attempt consisted of using the Jenkins Credentials and Credentials Binding plugins. Credentials Binding provides a way to inject credentials as environment variables using a parameter. However, setting this parameter dynamically (i.e., something like if ENV == dev: CREDS = CREDS_dev) doesn't appear to be possible. Build scripts happen afterwards, and even using the Environment Script plugin doesn't work.
Is there any way for this to happen?
Had similar situation and used groovy script with parameterized build (https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin). In my case I had a choice parameter defined as "DEPLOY" and had different values, like "Test", "Release", then in the following groovy script (Evaluated Groovy script):
if ("Test".equals(DEPLOY)) {def map = [DEPLOY_URL: "http://someurl", DEPLOY_STORAGE: "testaccount"]; return map }
You should be able to specify your credentials in here or copy env variables. After that you can access these variables in windows batch command using:
echo %DEPLOY_URL%
echo %DEPLOY_STORAGE%
I also had another choice parameter defined "Deploy.Branch", with values of "dev" and "master". And used it as a parameter to Branches to Build, the value was set to (if you want to dynamically specify branch based on parameters):
*/${Deploy.Branch}
Hope this helps.
Here's what I ended up doing. It's kind of a workaround for what I would argue is a flawed design or missing use case in Jenkins.
Redid my creds so they have standard IDs (this is in the Advanced part and you can't set it after creation)
Matrix job runs a trivial script to figure out what env maps to what creds ID, then triggers...
The main job that does the deployment

Is it possible to build 5 sub modules in one single job which have different script to execute?

I want to know how can we parameterize build in jenkins. I need to create a jenkins job which will contain 5 sub jobs in it. i need to create a drop down , selelct any of the module and build it. But the script used is different for every sub build? can any1 guide on the same is it possible.
string parameters in Jenkins result in environment variables of the same name.
So, you could write a wrapper script in bash which would look for the environment variables that could be set as a result of the parameterized build (i.e. your 5 sub-jobs) in a series of if-elif statements, and within each one, you would invoke the necessary build script from there.
The build script that you would have Jenkins run would be the wrapper script.

Resources