首页 文章

如何处理每晚构建Jenkins声明性管道

提问于
浏览
7

我的repo中有一个带有Jenkinsfile的multibranch管道,我可以在每次提交时使用我的CI工作流程(构建和单元测试 - > deploy-dev - >批准 - > deploy-QA - >批准 - > deploy-prod) . 我想做的是在第一阶段构建和单元测试的夜间构建中添加SonarQube Analysis . 由于我的构建是由Gitlab触发的,我已经定义了我的管道触发器如下:

pipeline {
    ...
    triggers {
        gitlab(triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: 'All')
    }
    ...
}

为了设置我的夜间构建,我添加了

triggers {
    ...
    cron('H H * * *')
}

但是现在,如果我们只是在晚上构建由cron表达式触发的作业,如何执行分析步骤?

我简化的构建阶段如下所示:

stage('Build & Tests & Analysis') {
    // HERE THE BEGIN SONAR ANALYSIS  (to be executed on nightly builds)
    bat 'msbuild.exe ...'
    bat 'mstest.exe ...'
    // HERE THE END SONAR ANALYSIS (to be executed on nightly builds)
}

4 回答

  • 5

    有如何获取构建触发器信息的方法 . 它在这里描述:https://jenkins.io/doc/pipeline/examples/#get-build-cause

    你也可以查看这个:how to get $CAUSE in workflow

    对你的案例非常好的参考是https://hopstorawpointers.blogspot.com/2016/10/performing-nightly-build-steps-with.html . 以下是该来源的功能,完全符合您的需求:

    // check if the job was started by a timer
    @NonCPS
    def isJobStartedByTimer() {
        def startedByTimer = false
        try {
            def buildCauses = currentBuild.rawBuild.getCauses()
            for ( buildCause in buildCauses ) {
                if (buildCause != null) {
                    def causeDescription = buildCause.getShortDescription()
                    echo "shortDescription: ${causeDescription}"
                    if (causeDescription.contains("Started by timer")) {
                        startedByTimer = true
                    }
                }
            }
        } catch(theError) {
            echo "Error getting build cause"
        }
    
        return startedByTimer
    }
    
  • 0

    您可以像这样检查构建原因:

    stage('Build & Tests & Analysis') {
        when {
            expression {
                for (Object currentBuildCause : script.currentBuild.rawBuild.getCauses()) {
                    return currentBuildCause.class.getName().contains('TimerTriggerCause')
                }
            }
            steps {
                bat 'msbuild.exe ...'
                bat 'mstest.exe ...'
            }
        }
    }
    

    但是,这需要 script-approval.xml 中的以下条目:

    <approvedSignatures>
      <string>method hudson.model.Run getCauses</string>
      <string>method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild</string>
    </approvedSignatures>
    

    这也可以通过https://YOURJENKINS/scriptApproval/批准 .
    希望在JENKINS-41272修复后不需要这样做 .

    在此之前,解决方法可能是检查 when 表达式中的一天中的小时(请记住,这些时间是指Jenkins的时区)

    when { expression { return Calendar.instance.get(Calendar.HOUR_OF_DAY) in 0..3 } }
    
  • 2

    对我来说,最简单的方法是在构建触发器中定义一个cron并使用 when expression 验证每晚的小时:

    pipeline {
        agent any
        triggers {
            pollSCM('* * * * *') //runs this pipeline on every commit
            cron('30 23 * * *') //run at 23:30:00 
        }
    
        stages {
            stage('nightly') {
                when {//runs only when the expression evaluates to true
                    expression {//will return true when the build runs via cron trigger (also when there is a commit at night between 23:00 and 23:59)
                        return Calendar.instance.get(Calendar.HOUR_OF_DAY) in 23
                    }
                }
    
                steps {
                    echo "Running the nightly stage only at night..."
                }
            }
        }
    }
    
  • 2

    我找到了一种方法,它不使用受限制的“currentBuild.rawBuild” . 开始您的管道:

    startedByTimer = false
    def buildCauses = "${currentBuild.buildCauses}"
    if (buildCauses != null) {
        if (buildCauses.contains("Started by timer")) {
            startedByTimer = true
        }
    }
    

    测试您需要它的布尔值,例如:

    stage('Clean') {
       when {
          anyOf {
             environment name: 'clean_build', value: 'Yes'
             expression { (startedByTimer == true) }
         }
      }
      steps {
          echo "Cleaning..."
          ...
    

相关问题