【问题标题】:Make Jenkins with declarative pipeline work with SVN trunk as well as branches让 Jenkins 使用声明式管道与 SVN 主干和分支一起工作
【发布时间】:2022-11-08 21:19:37
【问题描述】:

我想使用来自 Jenkinsfile 的声明性管道设置 Jenkins 作业,使用 Subversion 作为 SCM,这应该

  • 执行计划的 SCM 轮询以检测树干
  • 可手动启动以构建树干或者任何选择的分支

所以我已经设置了 Jenkins 的工作列出 Subversion 标签(以及更多)从 SVN url 收集现有 SVN 分支并让用户选择一个的参数。选定的值存储在一个变量中,例如$svnBranch,我将“trunk”定义为其默认值。

然后这个变量用于构建生成的 SCM url,例如

svn+ssh://svn.mydomain.org/Reponame/projectname/$svnBranch/componentname

现在问题来了:

只要手动启动作业,此设置就可以工作。但如果它是由 cron 计划启动的,Jenkins 每次都会不断检测 SCM 的变化,并总是启动一个新的构建。 SCN 轮询日志显示

Workspace doesn't contain Reponame/projectname/$svnBranch/componentname. Need a new build.

所以这个问题显然是由于 Jenkins 在轮询 SCM 以进行更改时没有解析变量引起的。为了验证这个假设,我改变了工作以使用一个固定的字符串变量,同样的事情又发生了。

我想知道是否可以通过将轮询和签出逻辑移动到 Jenkinsfile 来解决问题。这个想法是总是轮询树干,但是基于 $svnBranch 签出和构建,但我不确定如何执行此操作。是否可以为轮询和结帐定义不同的 SCM url?根据我的研究,Jenkinsfile 中的所有结帐 url 都会自动用于轮询,那么如何实现呢?

任何其他可行的解决方案也将受到欢迎。

请注意,有一个类似的问题Jenkins Pipeline - SVN polling 偶然发现了同样的问题,但没有适合我的方案的解决方案。

另请注意,JENKINS-10628: SCM build trigger not working correctly with variables in SVN URL 报告了一个问题,描述了我的问题,但据说自 2015 年以来使用新版本的 Subversion 插件解决了这个问题。我已更新到最新版本 2.16.0,但它没有解决问题。

【问题讨论】:

    标签: jenkins svn jenkins-pipeline


    【解决方案1】:

    这是我找到的解决方案(我愿意接受更好的解决方案 - 例如,我不满意在两个不同的地方配置相同的 SCM url):

    首先,在 Jenkins 作业中,在来自 SCM 的 Pipeline 下,我配置了树干不包含变量的 url。此 url 将用于轮询树干.

    svn+ssh://svn.mydomain.org/Reponame/projectname/trunk/componentname
    

    其次,我创建了一个函数来用分支名称替换“主干”部分:

    def call(Map param = [ : ]) {
        if ( param.branch == null ) {
            return param.trunkUrl                                     
        }
        url = param.trunkUrl.replaceAll('/trunk(?=/|$)', '/'+param.branch)  // replaces /trunk if followed by / or if at end of url
        return url
    }
    

    我已将此函数移至共享库,因此我可以从任何管道中使用它。

    然后使用在用户界面中选择 svnBranch 来派生结帐 url:

        environment {
            // Set actual checkout url, because SVN_URL_1 will always contain the fixed url of the trunk used for polling
            checkoutUrl = composeSvnUrl(trunkUrl: env.SVN_URL_1, branch: env.svnBranch)
        }
    

    最后,我在我的 Jenkinsfile 中添加了一个结帐阶段(作为第一阶段):

            stage('Checkout') {
                steps {
                    /* Checkout for actual build (may be different if started manually) */
                    checkout(
                        poll: false, changelog: false, // = do not use this for polling 
                        scm: [
                            $class: 'SubversionSCM', 
                            quietOperation: false,
                            additionalCredentials: [], 
                            excludedCommitMessages: '', 
                            excludedRegions: '', 
                            excludedRevprop: '', 
                            excludedUsers: '', 
                            filterChangelog: false, 
                            ignoreDirPropChanges: false, 
                            includedRegions: '', 
                            locations: [[
                                credentialsId: 'id.from.jenkins.credentials', 
                                depthOption: 'infinity',
                                ignoreExternalsOption: true, 
                                local: '.', 
                                remote: checkoutUrl, 
                            workspaceUpdater: [$class: 'CheckoutUpdater']               
                        ]
                         
                    )
                    
                }
            }
    

    重要的部分是:

    poll: false, changelog: false 表示 Jenkins 不应使用这些结帐信息进行轮询。如页面底部Pipeline: SCM Step - checkout: Check out from version control 所述:

    如果禁用“包含在轮询中”并且禁用“包含在更改日志中”,则在进行轮询时,将从该存储库检测到的更改将被忽略。

    workspaceUpdater: [$class: 'CheckoutUpdater'] 可能也很重要,因为这会在再次签出之前擦除工作区。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      相关资源
      最近更新 更多