Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins Shared Libraries: is it possible to pass arguments to shell scripts imported as 'libraryResource'?

I have the following setup:

(Stripped out) Jenkinsfile:

@Library('my-custom-library') _

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                printHello name: 'Jenkins'
            }
        }
    }
}

my-custom-library/resources/com/org/scripts/print-hello.sh:

#!/bin/bash

echo "Hello, $1"

my-custom-library/vars/printHello.groovy:

def call(Map parameters = [:]) {
    def printHelloScript = libraryResource 'com/org/scripts/print-hello.sh'
    def name = parameters.name
    //the following line gives me headaches
    sh(printHelloScript(name))
}

I expect Hello, Jenkins, but it throws the following exception:

groovy.lang.MissingMethodException: No signature of method: java.lang.String.call() is applicable for argument types: (java.lang.String) values: [Jenkins]

Possible solutions: wait(), any(), wait(long), split(java.lang.String), take(int), each(groovy.lang.Closure)

So, is it possible to do something like described above, without mixing Groovy and Bash code?

like image 804
ebu_sho Avatar asked Nov 14 '18 11:11

ebu_sho


People also ask

How does Jenkins shared library work?

A shared library in Jenkins is a collection of Groovy scripts shared between different Jenkins jobs. To run the scripts, they are pulled into a Jenkinsfile. Each shared library requires users to define a name and a method of retrieving source code.

How do you call a shared library in Jenkins?

Create a separate git repo for the Jenkins pipeline library & push the shared library code to that repo. Integrate the shared library repo in Jenkins under the Manage Jenkins section. Create Jenkinsfile in the project. In that Jenkinsfile, Import & use the shared library.

Where does Jenkins checkout shared library?

If the shared library is loaded from SCM and your workspace path is jenkins/workspaces/jobName , then a copy is checked out to jenkins/workspaces/jobName@libs or similar (might be suffixed with a number if that path is occupied by another concurrent build).

Can Jenkins run shell script?

Using Jenkins built-in "Execute shell" you can run commands using unix shell. If you need to run a job cross platform you cannot use the two standard executors provided by Jenkins. You need a "build step" that can be executed both in Windows and in Unix.


1 Answers

Yes, check out withEnv

The example they give looks like;

node {
  withEnv(['MYTOOL_HOME=/usr/local/mytool']) {
    sh '$MYTOOL_HOME/bin/start'
  }
}

More applicable to you:

// resources/test.sh
echo "HI here we are - $PUPPY_DOH --"

// vars/test.groovy
def call() {
   withEnv(['PUPPY_DOH=bobby']) {
    sh(libraryResource('test.sh'))
  }
}

Prints:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] libraryResource
[Pipeline] sh
+ echo HI here we are - bobby --
HI here we are - bobby --
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }

Using that, you can pass it in using a scoped named variable, something like

def call(Map parameters = [:]) {
    def printHelloScript = libraryResource 'com/org/scripts/print-hello.sh'
    def name = parameters.name
    withEnv(['NAME=' + name]) { // This may not be 100% syntax here ;)
    sh(printHelloScript)
}

// print-hello.sh
echo "Hello, $name"
like image 150
chrisb Avatar answered Oct 19 '22 23:10

chrisb