简体   繁体   中英

How to load bash script in Jenkins pipeline?

We have some complex bash script which is now in our managed files section in Jenkins. We try to migrate the job to a pipeline but we don't know enough to translate the bash script to groovy so we want to keep this in bash. We have a jenkins-shared-library in Git in which we store our pipeline templates. Inside the job we add the right environment variables.

We want to keep our bash script in git instead of in the managed files. What is the right way to load this script in the pipeline and execute it? We tried some stuff with libraryResource , but we didn't manage to make it work. Where do we have to put the test.sh script in git and how can we call it? (or is it completely wrong to run a shell script here)

def call(body) {
    // evaluate the body block, and collect configuration into the object
    def pipelineParams= [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = pipelineParams
    body()

    pipeline {
        agent any

        options {
            buildDiscarder(logRotator(numToKeepStr: '3'))
        }

        stages {

            stage ('ExecuteTestScript') {
                steps {
                    def script = libraryResource 'loadtestscript?'

                    script {
                        sh './test.sh'
                    }
                }
            }

        }

        post {
            always {
                cleanWs()
            }

        }

    }
}

In my company we also have complex bash scripts in our CI and libraryResource was a better solution. Following your script, you can perform some changes in order to use a bash script stored into libraryResource :

stages {
    stage ('ExecuteTestScript') {
        steps {
            // Load script from library with package path
            def script_bash = libraryResource 'com/example/loadtestscript'

            // create a file with script_bash content
            writeFile file: './test.sh', text: script_bash

            // Run it!
            sh 'bash ./test.sh'
        }
    }
}

I want to elaborate on @Barizon answer, that pointed me in the right direction.

My need was to execute the script on a remote service with ssh.

I created a groovy script inside the /var folder of the shared library project, let's call it my_script.groovy .

Inside the script i defined the funciton:

def my_function(String serverIp, String scriptArgument) {
    def script_content = libraryResource 'my_scripts/test.sh'
    // create a file with script_bash content
    writeFile file: './test.sh', text: script_content
    echo "Execute remote script test.sh..."
    def sshCommand = "ssh username@${serverIp} \'bash -xs\' < ./test.sh ${scriptArgument}"
    echo "Ssh command is: ${sshCommand}"
    sh(sshCommand)
}

From the pipeline I can invoke it like this:

@Library('MySharedLibrary')_
pipeline {
  agent any
  stages {
    stage('MyStage') {
        steps {
            script {
                my_script.my_function("192.168.1.1", "scriptArgumentValue")
            }
        }
    }
  }
}

Instead of copying the script to your workspace, you can call the script directly from a custom step. For example, create a file in the library's vars directory named doSomething.groovy :

#!/usr/bin/env groovy

def call(args) {
    def scriptDir = WORKSPACE + '@libs/my-shared-library'
    sh "$scriptDir/do-something.sh $args"
}

This works because the shared library is checked out to a directory named after the job's workspace suffixed with @libs. If you'd prefer, you can move do-something.sh to the library's resources directory or whatever.

I don't know if this is not possible for the OP but I find it much simpler to just keep my utility scripts in the same git repository as the Jenkinsfile, I never had to use libraryResource . Then you can just call them directly with the sh directive, and you can even pass variables defined in the environment block. For example, inside a script or steps block, within a pipeline stage :

sh "./build.sh $param1"

You could also put a bunch of bash functions in its own file, say " scripts/myfuncs.sh ". You can even have a groovy function that calls such scripts, essentially being a wrapper, see below:

def call_func() {
  sh"""
    #!/bin/bash

    . ./scripts/myfuncs.sh
    my_util_func "$param1"
  """
}

A few things to note:

Although on my terminal I can use source scripts/myfuncs.sh , on Jenkins I need to use the . shorthand for source (as shown above) otherwise it complains that it cannot find source !

You must make ./scripts/myfuncs.sh executable, eg chmod 755 ./scripts/myfuncs.sh before pushing it to the repository.

Example with full pipeline:

pipeline {
  agent any
  stages {
    stage('Build') {
      steps {
        sh '''
          ./build.sh
        '''
      }
    }
  }
  post {
    always {
      sh '''
        ./scripts/clean.sh
      '''
    }
    success {
      script {
        if (env.BRANCH_NAME == 'master') {
          sh "./scripts/master.sh"
        } else if (env.BRANCH_NAME.startsWith('PR')) {
          sh "./scripts/mypr.sh"
        } else {
          // this is some other branch
        }
      }
    }
  }
}

In the above example, both "Jenkinsfile" and "build.sh" are in the root of the repository.

you can use from bitbucket or git . create a repository in bitbucket or git and config in jenkins job .and write body of sh in script block in pipeline

在此处输入图片说明

then you can config jenkins file and used test.sh

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM