一个存储库中有多个jenkinsfile

use*_*299 19 jenkins jenkins-pipeline

我们在一个包含多个Jenkins文件的Github存储库中有一个项目:

my-project
  app
    Jenkinsfile
  lib1
    Jenkinsfile
  lib2
    Jenkinsfile
Run Code Online (Sandbox Code Playgroud)

我们创建了3个Jenkins管道,每个管道都引用了一个Jenkins文件. 在此输入图像描述

问题:当"lib2"中有新的提交时,如何避免触发"app"和"lib1"管道?我们不希望每次提交时都运行N个作业.

我已经看到问题已在https://issues.jenkins-ci.org/browse/JENKINS-43749中解决,但我还没有找到解决方案.

ihe*_*nyi 9

我建议使用多分支管道插件,然后指定适当 jenkinsfile 的路径。因此,您将拥有三个管道作业,一个用于 app、lib1 和 lib2。

在此处输入图片说明

  • @RaúlSalinas-Monteagudo 我的解决方案仅触发存在影响引用路径的提交的管道。我不确定你不明白什么。您设置了三个多分支管道作业,一项用于应用程序,一项用于 lib1,一项用于 lib2。仅当有对应用程序的提交时,应用程序管道才会运行。lib1 管道仅在有对 lib1 的提交时才会运行。lib2 的行为相同。这正是问题所寻求的实现建议的工作流程。 (7认同)
  • 您没有解决问题中描述的问题,即没有在包含其他 Jenkinsfile 的同一存储库中启动所有更改作业。 (2认同)
  • @RaúlSalinas-Monteagudo 你错了。使用多分支管道可以让您只触发单个作业,尽管进行了存储库提交。这是因为在多分支管道中,您可以指定Jenkinsfile应用的路径。您读过我的答案或尝试过吗?这是我现在正在使用的工作流程(在我写答案的时候就开始使用),所以你需要解释为什么它对我有效,而对其他人不起作用。 (2认同)

Sor*_*tta 7

RECENT UPDATE:

I later fixed this issue using following code snippet: If you see the command dir('servicelayer'), using this to move into the directory, executing git command to find the difference between the commits and raising a flag. This way i have managed 3 Jenkins files in a single repository.

stage('Validation') {
steps {
        //Moving in to the directory to execute the commands
        dir('servicelayer') {
            script {
                //Using the git command to check the difference between previous successful commit. ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} is an environment variable comes with GIT Jenkins plugin
                //There is a drawback though, if it is the first time you are running this job, this variable is not available and fails the build
                //For the first time i had to use ${env.GIT_COMMIT} itself at both places to pass the build. A hack but worth it for future builds.

                def strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep servicelayer | wc -l").trim()
                if(strCount=="0") {
                    echo "Skipping build no files updated"
                    CONTINUE_BUILD = false
                } else {
                    echo "Changes found in the servicelayer module"
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

}

OLD ANSWER:

You can do it in 2 ways:

a) Configure your build jobs by adding "Additional Behaviour" -> "Polling ignore commits in certain region" This behaviour will let you add "Whitelisted regions" or "Blacklist the regions" which you do not want to poll for triggering the build job.

b)编写一个自定义的shell脚本,以验证每次提交更改的文件并验证位置。然后可以将此Shell脚本添加到您的Jenkinsfile中,无论是声明式还是脚本式,您都可以相应地调整行为。

我将推荐选项a),因为它也更易于配置和维护。希望这可以帮助。

在此处输入图片说明


cez*_*tko 5

我实现了在单个存储库中拥有多个管道(Jenkinsfile)。这不是 hacky,但也不是那么简单,需要最新版本的 Jenkins 以及更新的可锁定资源插件,并且可能需要在构建过程中执行额外的步骤。

  • 创建仅“源代码管理”的项目。在 Jenkins 术语中,它可以是一个 Freestyle 项目,只关心保持源代码更新,具有 SCM 部分和触发配置(示例名称“MyProjectSCM”)。就我而言,我有一个带有轮询时间表的 git 存储库。确保未选中“如有必要,执行并发构建”标志;

  • 在项目存储库中提交一个或多个 Jenkins 管道,例如“JenkinsfileBuild”、“JenkinsfileRelease”。确保管道:

    1. skipDefaultCheckout部分中有options

    2. 配置了 SCM 项目(“MyProjectSCM”)上的触发器;

    3. 在构建期间锁定 SCM 项目。

       pipeline {
           agent any
      
           options {
               disableConcurrentBuilds()   
               skipDefaultCheckout()
           }
      
           triggers {
               upstream(upstreamProjects: 'MyProjectSCM')
           }
      
           stages {
               stage('Build') {
                   lock('MyProjectSCM') {
                       steps {
                           echo 'Build within MyProjectSCM lock...'
                       }
                   }
               }
           }
       }
      
      Run Code Online (Sandbox Code Playgroud)
  • 创建 Pipeline 项目,每个您在存储库中提交的 Jenkinsfile 都有一个。管道应该有一个配置的“来自 SCM 的管道脚本”(在本示例中,管道可以命名为“MyProject_Build”,并配置了“JenkinsfileBuild”),并选中“轻量级签出”标志(实际上是默认设置):

在此输入图像描述

“MyProject_Build”管道中的指令skipDefaultCheckout将阻止在该工作区中检出存储库,“轻量级检出”标记本身很奇怪,它不足以阻止检出。因为“MyProject_Build”工作区实际上是空的,所以您必须通过环境变量或相对路径在构建脚本中引用仅 SCM 的项目目录。该lock指令很有用,因此在实际构建项目时不会发生新的提交。