【问题标题】:Is it possible to use build user vars plugin in a Jenkins shared library?是否可以在 Jenkins 共享库中使用构建用户变量插件?
【发布时间】:2021-08-19 12:55:26
【问题描述】:

我正在实现将 Jenkins 管道的触发用户公开给我们的 CD 系统的功能,因此我获取了 build user vars 插件:https://plugins.jenkins.io/build-user-vars-plugin/

插件的工作方式似乎是你包装你需要暴露的变量的代码,像这样:

  wrap([$class: 'BuildUser']) {
    userId = env.BUILD_USER_ID
  }

我在一个通用管道上尝试了这个,只是回应它,一切都很好。

然后我尝试在我们的共享库中实现它,这样所有对 CD 的调用都会发生这种情况,但我遇到了一个错误。

wrap([$class: 'BuildUser']) {
    jobBuildUrl ="${jobBuildUrl}&USER_ID=${env.BUILD_USER_ID}"
}

[2021-08-19T10:20:22.852Z] hudson.remoting.ProxyException:groovy.lang.MissingMethodException:没有方法签名:com.company.jenkins.pipelines.BuildManager.wrap() 适用于参数类型: (java.util.LinkedHashMap, org.jenkinsci.plugins.workflow.cps.CpsClosure2) 值:[[$class:BuildUser], org.jenkinsci.plugins.workflow.cps.CpsClosure2@1c9a210c]

有没有办法在共享库中使用这个插件代码?如果有怎么办?

我不相信,但我认为值得一问。供参考,有这个悬而未决的问题:https://issues.jenkins.io/browse/JENKINS-44741

旁注,我试图在不触及每个人的管道的情况下做到这一点。如果这个插件无法做到这一点,我可能会在共享库中实现我自己的版本。

【问题讨论】:

    标签: jenkins jenkins-pipeline jenkins-plugins


    【解决方案1】:

    那个插件很难使用并且有很多问题,其中一个是共享库。
    而不是自己实现它,它相对容易,并且允许您更好地控制所做的逻辑、错误处理和返回的参数。
    您可以使用以下内容:

    /**
    * Get the last upstream build that triggered the current build
    * @return Build object (org.jenkinsci.plugins.workflow.job.WorkflowRun) representing the upstream build
    */
    @NonCPS
    def getUpstreamBuild() {
       def build = currentBuild.rawBuild
       def upstreamCause
       while (upstreamCause = build.getCause(hudson.model.Cause$UpstreamCause)) {
           build = upstreamCause.upstreamRun
       }
       return build
    }
    
    /**
    * Get the properties of the build Cause (the event that triggered the build)
    * @param upstream If true (Default) return the cause properties of the last upstream job (If the build was triggered by another job or by a chain of jobs)
    * @return Map representing the properties of the user that triggered the current build.
    *         Contains keys: USER_NAME, USER_ID
    */
    @NonCPS
    def getUserCauseProperties(Boolean upstream = true) {
       def build = upstream ? getUpstreamBuild() : currentBuild.rawBuild
       def cause = build.getCause(hudson.model.Cause$UserIdCause)
       if (cause) {
           return ['USER_NAME': cause.userName, 'USER_ID': cause.userId]
       }
       println "Job was not started by a user, it was ${build.getCauses()[0].shortDescription}"
       return [:]
    }
    

    【讨论】:

    • 或者,非优雅的解决方案是否不仅仅涉及在全局变量源代码中导入插件?
    • 我认为这是可能的,但需要将此代码移动到 src 文件夹才能使导入工作,这将使结构和用法复杂化。
    • 打算将此标记为答案,因为您得出的结论与我相似,如果没有人这么说,我将发布一个。我的做法与你略有不同,并且没有 NonCPS(不确定我是否需要),但就我而言,我只升级了一级,所以我可能会尝试使用你的递归。谢谢!
    • 在处理像 (cause) 这样的不可序列化的类时始终使用NonCPS 注释,否则在管道中使用此函数时可能会遇到序列化问题。查看更多信息Here
    • 啊,我不知道原因是不可序列化的,但这是有道理的。我会说我没有尝试过,并且确实成功了,但是根据您的建议,我会添加它。我知道这意味着管道将无法在重新启动后继续存在,并且我读到了其他内容,说除非您必须这样做,否则不要使用它。但我会试一试。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多