如何在Jenkins管道中加载bash脚本?

时间:2017-11-23 12:50:25

标签: bash jenkins jenkins-pipeline

我们有一些复杂的bash脚本现在位于Jenkins的托管文件部分。我们尝试将作业迁移到管道但我们不知道将bash脚本转换为groovy,因此我们希望将其保留在bash中。 我们在Git中有一个jenkins-shared-library,用于存储我们的管道模板。在工作中我们添加了正确的环境变量。

我们希望将bash脚本保存在git中而不是托管文件中。在管道中加载此脚本并执行它的正确方法是什么? 我们用libraryResource尝试了一些东西,但我们没有设法让它工作。我们在哪里将test.sh脚本放在git中,我们如何调用它? (或者在这里运行shell脚本是完全错误的)

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()
            }

        }

    }
}

5 个答案:

答案 0 :(得分:1)

在我的公司中,我们的CI中也有复杂的bash脚本,libraryResource是更好的解决方案。 按照您的脚本,您可以执行一些更改,以便使用存储在bash中的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'
        }
    }
}

答案 1 :(得分:0)

我想详细说明@Barizon的答案,这为我指明了正确的方向。

我需要使用ssh在远程服务上执行脚本。

我在共享库项目的/var文件夹内创建了一个普通脚本,我们称之为my_script.groovy

在脚本中我定义了功能:

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)
}

从管道中,我可以这样调用它:

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

答案 2 :(得分:0)

您可以直接从自定义步骤调用脚本,而不是将脚本复制到工作区。例如,在库的vars目录中创建一个名为doSomething.groovy的文件:

#!/usr/bin/env groovy

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

之所以有用,是因为共享库已检出到以作业的工作空间后缀@libs命名的目录。如果愿意,可以将do-something.sh移至库的资源目录或其他任何内容。

答案 3 :(得分:0)

我不知道这对于OP是否可行,但是我发现将实用程序脚本与Jenkinsfile放在同一个git存储库中要容易得多,我从来不必使用libraryResource。然后,您可以直接使用sh指令来调用它们,甚至可以传递在environment块中定义的变量。例如,在scriptsteps块内,在管道stage内:

sh "./build.sh $param1"

您还可以在自己的文件中放置一堆bash函数,例如“ scripts / myfuncs.sh ”。您甚至可以使用一个groovy函数来调用此类脚本,本质上是一个包装器,请参见下文:

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

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

一些注意事项:

尽管我可以在终端上使用source scripts/myfuncs.sh,但在詹金斯上,我需要使用.的简写形式source(如上所示),否则它会抱怨找不到{{1 }}!

您必须使source可执行,例如./scripts/myfuncs.sh,然后将其推送到存储库。

具有完整管道的示例:

chmod 755 ./scripts/myfuncs.sh

在上面的示例中,“ Jenkinsfile”和“ build.sh”都在存储库的根目录中。

答案 4 :(得分:0)

您可以从bitbucket或git中使用。在jenkins job中使用bitbucket或git和config创建一个存储库,并在管道中的脚本块中写入sh正文

enter image description here

然后您可以配置jenkins文件并使用test.sh

enter image description here