I have a Jenkins pipeline, it imports a shared library which in turn "grabs" a dependency. I want to call a method on the class which takes a File parameter.
But the file doesn't exist when I try to access it in the shared library.
The Pipeline
#Library('my shared library')
pipeline {
// ...
stages {
stage {
steps {
script {
f = new File("foo.txt")
libFn(myFile: f)
}
}
}
}
}
The Jenkins Shared Library
// ./vars/libFn.groovy
#Grab("3rd party java library")
import LibraryClass
def call(Map params) {
LibraryClass libraryClass = new LibraryClass();
libraryClass.processFile(params.myFile);
}
The 3rd Party Java Library
public class LibraryClass {
public void processFile(File file) {
// do something with a file
}
}
Related
I have a groovy class which I am attempting to import from a folder-level shared library.
Here is the groovy class -
package abc.esmm
#Singleton
class JiraCommands implements Serializable
{
def steps
def jiraCommandsTool
def Initialize(steps)
{
this.steps = steps
jiraCommandsTool = "${steps.WORKSPACE}/JenkinsPipeline/UtilityScripts/bin/JiraCommands"
}
def AddFixVersionToJiraIssues(jiraIssues, fixVersion, overwriteFixVersionParam=false)
{
def overwriteFixVersion = "False"
if(overwriteFixVersionParam)
{
overwriteFixVersion = "True"
}
steps.sh(returnStdout: true, script: "${jiraCommandsTool} -command addFixVersionToJira -jiraIssues \"${jiraIssues}\" -fixVersion ${fixVersion} -overwriteFixVersion ${overwriteFixVersion}").trim()
}
}
I try to create an instance of this class with this pipeline code :
#Library('LotteryFolderPipelineLibs')
import abc.esmm.JiraCommands
node('All_LinuxBuildPool')
{
JiraCommands.instance.Initialize(this)
}
This works ok when called from a Jenkins Global shared library, but not when called from a folder-level shared library. The global shared library and the folder-level shared library point to the same code. When called from a folder-level shared library I receive this error :
CpsCallableInvocation{methodName=getInstance, call=null, receiver=class abc.esmm.JiraCommands, arguments=[]}
Finished: FAILURE
Does anyone know why this is happening ?
I want to add timestamps() and colorizeOutput() features to our pipeline libraries. I find the wrappers {} in Jenkins documentation:
job('example') {
wrappers {
colorizeOutput()
timestamps()
}
}
I don`t get how to add wrappers to out library which looks like that:
// file ..src/helpers/Builder.groovy
package helpers.sw_main
def doSomething() {
// some Groovy stuff here
}
def doSomethingElse() {
// do something else
}
Our job pipeline looks like that:
#!/usr/bin/env groovy
// this is our library with custom methods
#Library('ext-lib')
def builder = new helpers.Builder()
node {
try {
stage('Some Stage') {
builder.doSomething()
}
}
catch (err) {
throw err
}
}
So, I want to add timestamps and ansi-colors to every function from library. Of course, I can do it with wrapping every function with
timestamps() {
colorizeOutput() {
// function body
}
}
But its a little stupid.
So can I easily wrap pipeline or library?
One solution to your problem is to use Global Variables (/vars/xxxxx.groovy).
To create an own build step, add a Global Variable like /vars/myOwnStep.groovy:
def call(STAGE_NAME, Closure closure) {
// do something
// return something if you like to
}
whcih you can call like this
myOwnStep("Step-name") {
// what ever you want to do
}
in your pipeline script.
Another possibility is to "overwrite" the sh step. Therefore create a file called /vars/sh.groovy with this code:
def call(String script, String encoding=null, String label=null, boolean returnStatus=null, boolean returnStdout=null) {
timestamps {
return steps.sh(script: script, endoding: encoding, label: label, returnStatus: returnStatus, returnStdout: returnStdout)
}
}
def call(Map params = [:]) {
return call(params.script, params.get('encoding', null), params.get('label', null), params.get('returnStatus', false), params.get('returnStdout', false))
}
(This can be done for other steps too, but he parameters have to match.)
I just added a GitHub repository with some examples: https://github.com/datze/jenkins_shared_library (untested!)
I recently started with Jenkins shared libraries in Jenkins pipeline.
I created a "func.groov" class and located it under "src/org/prj/func.groovy" :
package org.prj
import jenkins.model.
class func implements Serializable {
def steps
func(steps) {
this.steps = steps
}
def sh(args) {
steps.sh "echo ${args}"
}
def setLBL(CurrentNodeName,newLabelName){
jenkins.model.Jenkins.instance.slaves.each{ slave ->
if (slave.getNodeName() == CurrentNodeName){
slave.setLabelString(newLabelName)
}
}
}
Jenkinsfile (scripted) looks like:
#Library('prj') import org.prj.func
def utils = new func(steps)
node(lbl)
{
stage("A"){
Build_node_lbl = env.NODE_NAME+System.currentTimeMillis()
utils.setLBL(env.NODE_NAME,Build_node_lbl)
}
}
so currently it works. my question is how to create a full stage (like "A") as a function in func.groovy shared lib which will include, for example:
GIT checkout step
sh compilation step
Artifactory deploy step
Im actually looking to create a "building blocks" (a "Build" in my example) with Jenkins pipeline and shard libraries.
1. With Class Instantiation
You can create a class like you would do in Java. Then in your Jenkinsfile you instantiate the class and call its function.
src/org/prj/MyPipeline.groovy:
package org.prj
class MyPipeline {
def steps
MyPipeline(steps) {this.steps = steps}
public def build() {
steps.node('lbl') {
steps.stage('A') {
// Do build stuff
// steps.sh(..)
}
}
}
}
Jenkinsfile:
import org.prj.MyPipeline
def pipeline = new MyPipeline(this)
pipeline.build()
2. With Static Functions
You may also work with static contexts, without instantiation. However, this would require to hand over the caller context to the pipeline:
src/org/prj/MyPipeline.groovy:
package org.prj
class MyPipeline {
public static def build(caller) {
caller.node('lbl') {
caller.stage('A') {
// Do build stuff
caller.sh(..)
}
}
}
}
Jenkinsfile:
import org.prj.MyPipeline
MyPipeline.build(this)
I'm writing my own shared library. Now I want to use global variable in my code. How can I make that happen ?
I.E. I write a class.
class MyWork {
build() {
// here I want to use global docker(which is docker-plugin)
docker.doSomething {
}
}
}
enable the library in 'Global Pipeline Libraries' (i add the library 'pipeline-shared-lib')
create a shared-library (with the necessary structure)
src/net/kukinet/Utils.groovy
package net.kukinet;
def myVar = 1
def sayHello() {
print ('hello')
}
create a pipeline job and create the object
JenkinsJob.groovy
#!groovy
// this need to be enabled in jenkins configuration ( in: manage jenkins)
#Library('pipeline-shared-lib') import net.kukinet.*
node (){
u = new net.kukinet.Utils();
stage('preperations') {
print(u.myVar)
u.sayHello()
}
}
I have my GParsPool.withPool implemented in 'PreVerifymanager.groovy' as below.
import groovyx.gpars.GParsPool
public class PreVerifyManager {
static final THREADS = 3;
public void callMe() {
PreVerifyManager pf = new PreVerifyManager()
def apps = ["App1","App2","App3"]
GParsPool.withPool(PreVerifyManager.THREADS) {
apps.eachParallel {
pf.CreateFile(it)
}
}
}
public void CreateFile(String path){
path = "D:\\"+path+".txt";
println(path)
File file = new File(path)
file.write("Some text")
}
}
This works fine in my IDE with main method of PreVerifyManager. But when I remove the main method and call the method callMe on the object of PreVerifyManager created in Pipeline script, its not working.
Pipeline script as below:
node {
def PreVerifyManagerObj
stage 'TibcoConfig'
echo 'Reading Tibco configuration!'
println "****************INSIDE PIPELINE****************"
def parent = getClass().getClassLoader()
def loader = new GroovyClassLoader(parent)
PreVerifyManagerObj = loader.parseClass(new File("D://Tibco_Automation//src//com//meet//PreVerifyManager.groovy")).newInstance()
PreVerifyManagerObj.callMe()
}
Its basically, I'm integrating the GParsPool.withPool implementation with Pipeline scripting. Any input is appreciated.
The issue got resolved. You have to load all objects referred in your class into Pipeline script box, before you call your actual method.