简体   繁体   English

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

[英]How to load bash script in Jenkins pipeline?

We have some complex bash script which is now in our managed files section in Jenkins.我们有一些复杂的 bash 脚本,现在位于 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.我们尝试将作业迁移到管道,但我们不知道将 bash 脚本转换为 groovy,因此我们希望将其保留在 bash 中。 We have a jenkins-shared-library in Git in which we store our pipeline templates.我们在 Git 中有一个 jenkins-shared-library,我们在其中存储我们的管道模板。 Inside the job we add the right environment variables.在作业中,我们添加了正确的环境变量。

We want to keep our bash script in git instead of in the managed files.我们希望将 bash 脚本保存在 git 中而不是托管文件中。 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.我们尝试了libraryResource一些东西,但我们没有设法让它工作。 Where do we have to put the test.sh script in git and how can we call it?我们必须将test.sh脚本放在 git 中的什么位置,我们如何调用它? (or is it completely wrong to run a shell script here) (或者在这里运行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()
            }

        }

    }
}

In my company we also have complex bash scripts in our CI and libraryResource was a better solution.在我的公司,我们的 CI 中也有复杂的 bash 脚本,而libraryResource是一个更好的解决方案。 Following your script, you can perform some changes in order to use a bash script stored into libraryResource :按照您的脚本,您可以执行一些更改以使用存储在libraryResourcebash脚本:

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.我想详细说明@Barizon 的答案,这为我指明了正确的方向。

My need was to execute the script on a remote service with ssh.我的需要是使用 ssh 在远程服务上执行脚本。

I created a groovy script inside the /var folder of the shared library project, let's call it my_script.groovy .我在共享库项目的/var文件夹中创建了一个 groovy 脚本,我们称之为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 :例如,在库的 vars 目录中创建一个名为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.这是有效的,因为共享库被检出到以作业的工作空间命名的目录中,后缀为@libs。 If you'd prefer, you can move do-something.sh to the library's resources directory or whatever.如果您愿意,可以将do-something.sh移动到库的资源目录或其他目录。

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 .我不知道这对于 OP 是否不可能,但我发现将我的实用程序脚本保存在与 Jenkinsfile 相同的 git 存储库中要简单得多,我从来libraryResource使用libraryResource Then you can just call them directly with the sh directive, and you can even pass variables defined in the environment block.然后你可以直接用sh指令调用它们,你甚至可以传递environment块中定义的变量。 For example, inside a script or steps block, within a pipeline stage :例如,在scriptsteps块内,在管道stage

sh "./build.sh $param1"

You could also put a bunch of bash functions in its own file, say " scripts/myfuncs.sh ".你也可以把一堆 bash 函数放在它自己的文件中,比如“ scripts/myfuncs.sh ”。 You can even have a groovy function that calls such scripts, essentially being a wrapper, see below:你甚至可以有一个调用这些脚本的 groovy 函数,本质上是一个包装器,见下文:

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 .尽管在我的终端上我可以使用source scripts/myfuncs.sh ,但在 Jenkins 上我需要使用. shorthand for source (as shown above) otherwise it complains that it cannot find source ! source简写(如上所示)否则它会抱怨它找不到source

You must make ./scripts/myfuncs.sh executable, eg chmod 755 ./scripts/myfuncs.sh before pushing it to the repository.在将其推送到存储库之前,您必须使./scripts/myfuncs.sh可执行,例如chmod 755 ./scripts/myfuncs.sh

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.在上面的示例中,“Jenkinsfile”和“build.sh”都在存储库的根目录中。

you can use from bitbucket or git .您可以从 bitbucket 或 git 使用。 create a repository in bitbucket or git and config in jenkins job .and write body of sh in script block in pipeline在 bitbucket 或 git 中创建一个存储库,并在 jenkins 作业中进行配置。并在管道的脚本块中写入 sh 的主体

在此处输入图片说明

then you can config jenkins file and used test.sh然后你可以配置 jenkins 文件并使用 test.sh

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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