【问题标题】:Skip Stages in Jenkins shared library based on repository基于存储库的 Jenkins 共享库中的跳过阶段
【发布时间】:2023-07-10 19:22:01
【问题描述】:

我有一个用于所有存储库的通用 Jenkins 共享库,如下所示。

vars/_publish.groovy

    pipeline {
        environment {
            abc= credentials(’abc')
            def= credentials(‘def’)
 
        }
        stages {
            stage('Build') {
                steps{
                    sh ‘docker build'
                }
            }
           stage('Unit-test') {
                steps{
                    sh ‘mvn test'
                }
            }

jenkinsfile

@Library('my-shared-library@branch') _

_publish() {
}

我有 10 个存储库,每个存储库都有自己的 Jenkinsfile,如上所示,它指的是 jenkins 共享库(vars/_publish.groovy)。我这里有一个条件,我需要通过。对于少数存储库,我想跳过单元测试并执行构建阶段。对于其他存储库,我想要两个阶段。有没有人可以根据存储库或存储库名称跳过特定阶段

【问题讨论】:

    标签: jenkins groovy environment-variables jenkins-pipeline jenkins-shared-libraries


    【解决方案1】:

    是的,你可以使用这样的表达式

    pipeline {
      agent any 
      stages {
        stage('Test') {
         when { expression { return repositoryName.contains('dev') } } <---------Add put your repository name 'dev' so whenever the repository names is ''dev' then execute this stage
          steps {
            script {
            
            }
          }
       }
      }
    }
    
    def repositoryName() {
      def repositoryName = ['dev', 'test'] <----Add here the 10 repo name
      return repositoryName 
    }
    

    在我的例子中,repo 名称是 dev 和 test,所以你可以添加你的相应

    【讨论】:

    • 我应该将 'name''another repository name' 替换为什么?有 10 个存储库共享同一个文件,所以我需要指定每个存储库名称吗?
    • 是的。您必须指定 10 个存储库名称。或者也许以某种方式动态获取 reponames 并在条件下使用它
    • 我们不断添加新的服务/存储库,添加名称将使 jenkins-shared-library 变得非常庞大和复杂。我将环境块中存储库的名称动态地导出为变量“名称”。但我不确定如何获取其他 repo 名称并设置何时条件。
    • 我应该将 YourRepositoryNamename另一个存储库名称替换成什么?
    • 您无需在共享库中硬编码 repo 名称。相反,您可以让您的共享库接受来自 Repos Jenkinsfile 的参数并决定要做什么。我添加了一个示例 - 请看一下
    【解决方案2】:

    我会像这样装饰我的共享库和 Jenkinsfile 来实现你的场景。

    vars/_publish.groovy

    def call(body={}) {
        def pipelineParams = [:]
        body.resolveStrategy = Closure.DELEGATE_FIRST
        body.delegate = pipelineParams
        body()
        pipeline {
            agent any;
            stages {
                stage('build') {
                    steps {
                        echo "BUILD"
                    }
                }
                stage('unitest') {
                    when {
                        anyOf {
                            equals expected: true, actual: pipelineParams.isEmpty();
                            equals expected: false, actual: pipelineParams.skipUnitest
                        }  
                    }
                    steps {
                        echo "UNITEST"
                    }
                }
            }
        }
    }
    

    我正在让我的共享库接受来自 Jenkinsfile 的参数,并使用 when{} DSL 决定是否跳过 unitest 阶段

    Jenkinsfile

    如果您来自 repo 的 Jenkins 文件包含以下详细信息,将跳过 unitest 阶段

    @Library('jenkins-shared-library')_
    _publish(){
        skipUnitest = true
    }
    

    在这两种情况下都将运行 unitest 阶段

    @Library('jenkins-shared-library')_
    _publish(){
        skipUnitest = false
    }
    

    @Library('jenkins-shared-library')_
    _publish(){
    }
    

    【讨论】: