当前位置: 首页 > 知识库问答 >
问题:

Jenkins管道共享库的设置

舒俊雄
2023-03-14

我们试图切换到jenkins管道,但我在groovy/java的低水平阻止了我们建立一个共享库。

这里是我的共享库(位于bitbucket中git repo的{root}/src/com/pipeline.groovy中)我必须承认,我在这里做什么都不知道,因为我不知道包裹的定义

package com.pipeline  // not sure about the package definition here

class Utils implements Serializable {  // seems I need to serialize but not sure :(

    /**
     * Execute common steps for the clean up of the workspace before the job really starts
     */
    static def preBuildCleanUp() {
        sh(script: "git clean -xdf && git remote prune origin && find . -name '*.pyc' -delete")

    }
    /**
     * commit ID is not exposed to the jenkins env in pipeline (see https://issues.jenkins-ci.org/browse/JENKINS-26100)
     *
     * These should all be performed at the point where you've
     * checked out your sources on the agent. A 'git' executable
     * must be available.
     * Most typical, if you're not cloning into a sub directory
     *
     * @return String short SHA
     */
    static def getShortCommitID() {
        gitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
        // short SHA, possibly better for chat notifications, etc.
        return gitCommit.take(6)
    }

    /**
     * Run a pip to install the package locally to the user.
     * @param String packageName name of the pip package to install
     */
    static def pipInstall(packageName) {
        sh(script: "python -m pip.__main__ install --user --quiet $packageName")
    }
    /**
     * Build a virtualenv at env.PYENV_HOME location.
     */
    static def buildVirtualEnv() {
        pipInstall("virtualenv")
        sh(script: "python -m virtualenv --no-site-packages ${PYENV_HOME} || exit 1")
    }

    /**
     * Return the list of environment variables common to all jenkins jobs
     * @set ${WORKSPACE}
     * @return List
     */
    static def getCommonEnv() {
        return ["WORKSPACE=${pwd()}"]
    }

    /**
     * Return the list of environment variables common to all python jobs
     * @set ${PYENV_HOME}
     * @set ${PYTHONDONTWRITEBYTECODE}
     * @extend ${PYTHONPATH}
     * @return List
     */
    static def getPythonEnv() {
        return [
                "PYENV_HOME=$WORKSPACE/.pyenv/",
                "PYTHONDONTWRITEBYTECODE=1",
                "PYTHONPATH=/rdo/rodeo/setup/lib/pure:$PYTHONPATH"
        ]
    }

    /**
     * Run the test using py.test inside a virtual env.
     */
    static def runTestsWithPyTest() {
        sh(script: "source ${PYENV_HOME}/bin/activate || exit 1 && /rdo/rodeo/setup/jenkins_scripts/jenkins_pytest.bash ${TEST_FOLDER} ${COVER_FOLDER}")
    }

    /**
     * Send a report to the commiter about the state of the tests
     *
     * @param Int returnCode return code to use to build the slack message.
     */
    static def sendSlackNotification(returnCode) {
        shortCommitID = getShortCommitID()
        sh(script: "export RC=$returnCode && export GIT_COMMIT=$shortCommitID && /rdo/rodeo/setup/jenkins_scripts/jenkins_slack_notification.bash")
    }

    /**
     * List of parameters to use for the coverage report.
     *
     * @param String coverageFile name of the file to parse for the coverage report
     * @return List
     */
    static def getCoberturaParameters(coverageFile) {
        return [
                $class             : 'CoberturaPublisher',
                autoUpdateHealth   : true,
                autoUpdateStability: true,
                coberturaReportFile: coverageFile,
                failUnhealthy      : true,
                failUnstable       : true,
                maxNumberOfBuilds  : 0,
                onlyStable         : false,
                sourceEncoding     : 'UTF_8',
                zoomCoverageChart  : false
        ]
    }
}

Jenkins的管道看起来

properties([
        buildDiscarder(
                logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '20')
        ),
        pipelineTriggers([
                [$class: 'BitBucketTrigger'],
                pollSCM('H/1 * * * *')
        ])
])
@Library('com.pipeline') _ 
node("linux") {
    def specificEnv = [
            "TEST_FOLDER=tests/unit_tests/",
            "COVER_FOLDER=rdo_shotgun_workflows",

    ]
    stage('SCM') {checkout scm}

    withEnv(com.pipeline.Utils.getCommonEnv() + com.pipeline.Utils.getPythonEnv() + specificEnv) {
        ansiColor('xterm') {
            try {
                stage('Pre-Build Cleanup') { com.pipeline.Utils.preBuildCleanUp() }
                stage('Set VirtualEnv') { com.pipeline.Utils.buildVirtualEnv() }
                stage('Test') { retry(3) { com.pipeline.Utils.runTestsWithPyTest() } }
                env.RC = 0
            } catch (err) {
                env.RC = 1
                throw err as java.lang.Throwable
            } finally {
                stage('Publish results') {
                    step(com.pipeline.Utils.getCoberturaParameters("coverage.xml"))
                    junit 'nosetests.xml'
                }
                stage('notification') { com.pipeline.Utils.sendSlackNotification(env.RC) }
                stage('Post-Build Cleanup') { step([$class: 'WsCleanup']) }
            }
        }
    }
}

通过所有这些设置,我最终得到了错误:

(... trimed setup of the jenkins job)
> git fetch --no-tags --progress ssh://git@bitbucket.org/rodeofx/rdo_shotgun_workflows.git +refs/heads/*:refs/remotes/origin/* --depth=20
Checking out Revision 48c78e3220a47fae9823578a1c30fa5a25349958 (RDEV-8036-jenkinsFile-slack)
> git config core.sparsecheckout # timeout=10
> git checkout -f 48c78e3220a47fae9823578a1c30fa5a25349958
> git rev-list 48c78e3220a47fae9823578a1c30fa5a25349958 # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: com for class: groovy.lang.Binding
    at groovy.lang.Binding.getVariable(Binding.java:63)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224)
    at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
    at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
    at WorkflowScript.run(WorkflowScript:121)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
    at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
    at sun.reflect.GeneratedMethodAccessor758.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
    at com.cloudbees.groovy.cps.Next.step(Next.java:74)
    at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:165)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:330)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:82)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:242)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:230)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)

我怀疑我的漂亮包裹的定义,但我坚持这样做。

非常欢迎您的反馈。

问候你乔迪

共有2个答案

夏建弼
2023-03-14

根据jenkins文档,以下是您案例中的目录结构。

(root)
+- src                       # Groovy source files
|   +- com
|       +- pipeline
|           +- Utils.groovy  # for com.pipeline.Utils class

在设置Jenkins作业时(根据您的图片),请提供易于使用的库名称,而不是com。管道,因此在您的情况下,可以将utils更改为库名称

注意:不要更改Utils.groovy文件中提到com.pipeline包名

在Jenkins文件中做以下更改

@Library('utils') _           // change the library name to utils
import com.pipeline.*         // Add this line

//change com.pipeline to pipeline
withEnv(pipeline.Utils.getCommonEnv() + pipeline.Utils.getPythonEnv() + specificEnv) {  

还可以直接使用类名而不是管道进行访问。Classname,做这个

@Library('utils') _ 
import com.pipeline.Utils

withEnv(Utils.getCommonEnv() +Utils.getPythonEnv() + specificEnv) { 

做上面的更改,它肯定会工作。

崔单弓
2023-03-14

共享库中的文件夹结构是什么样的?文档说明,即必须如下所示:

(root)
+- src                     # Groovy source files
|   +- org
|       +- foo
|           +- Bar.groovy  # for org.foo.Bar class

在您的情况下,Utils需要是src/com/管道/Utils.groovy。

 类似资料:
  • 我将我的Jenkins Pipeline存储为Jenkins共享库中的Groovy脚本。我想为不同的工作使用不同的版本。我的共享库脚本称为如下: 我已将sharedLib repo中的不同版本标记为。万一我想用v1。0,我用注释引用了它,如下所示。 在我的工作中,我通过调用groovy脚本访问了共享库,并使用了上面的注释,如图所示: 我运行这项工作时出错了。以下是我看到的错误。 当我使用。我哪里出

  • 问题内容: 我在Jenkins管道的共享库中有一个方法。想法是使用该库并将文件上传到远程主机。该库将导入到单例库中。 实例化的类如下所示: 即使我在日志中看到该行。我看不到命令正在执行。我缺少某种无法调用的功能吗? 编辑 当我直接在库中使用时,它可以工作。 但是,尝试使用时不起作用。 我得到的异常是: 问题答案: 如此处所述,您需要捕获stdout / stderr才能 _看到_任何内容。 至少:

  • 问题内容: 詹金斯版 2.89.4workflow -cps ver 2.42 当我尝试运行加载库的管道时,出现以下异常: 引用链接的Groovy类: 您可以像这样在管道或库中重现异常: 问题答案: 这是一个已知的詹金斯问题:JENKINS-45901 自2017年8月以来已开放。看起来很快不会修复: 不知道是否有详尽的文档记录了Groovy语言支持(或缺乏它),但是无论如何我都不会期望这个问题或

  • 詹金斯·弗。2.89.4 workflow-cps ver 2.42 当我尝试运行一个加载库的管道时,我得到以下异常: 链接所引用的Groovy类: 您可以在管道或库中复制异常,如下所示:

  • 由于我无法访问组织中的“管理Jenkins”菜单,我无法在“管理Jenkins”中的“全局管道库”中配置共享库。 没有在Manage Jenkins中进行配置,是否有其他方法实现此功能? (或) 是否可以通过管道脚本配置“全球管道库”部分,而不管访问权限如何? 如果可能,请您在答案中共享一些代码片段。

  • 我在Jenkins管道的共享库中有一个方法。其想法是使用此库并将文件上载到远程主机。该库导入到单例库中。 实例化的类如下所示: 尽管我在日志中看到了println行。我看不到正在执行curl命令。是否有我缺少的不调用cmd的东西。执行才能工作? 编辑 当我在库中直接使用curl时,它可以工作。 但是,当尝试使用时,它不起作用。 我得到的例外是: