【问题标题】:Restricting which downstream builds are triggered on SNAPSHOT dependency限制在 SNAPSHOT 依赖项上触发哪些下游构建
【发布时间】:2014-12-04 15:57:29
【问题描述】:

我们有一个 Jenkins 服务器,只要(php 或 java)项目具有有效的 pom.xml,就使用 jenkins-build-per-branch 从 git 同步。我们使用 maven 版本控制策略来管理我们的人工制品,并使用 git-flow 作为分支策略/工具。我们还尽可能使用 jenkins 选项“在构建 SNAPSHOT 依赖项时构建”。

我们遇到的问题是在构建 -SNAPSHOT 人工制品时 - 一切都崩溃了,一切都想立即构建。 (构建“开发”-SNAPSHOT 会导致所有下游“功能”和“开发”分支启动)

理想情况下,我们希望找到一些方法,在 jenkins 启动下游作业时,我们不会在功能和开发构建之间相互交叉。

有人试过吗? Conditional+BuildStep+Plugin 之类的东西有帮助吗? https://wiki.jenkins-ci.org/display/JENKINS/Conditional+BuildStep+Plugin

【问题讨论】:

  • 我们面临同样的问题。你解决过这个问题吗?

标签: maven jenkins git-flow


【解决方案1】:

这是一个老问题,但在 6 年后仍然有意义。 Build whenever a SNAPSHOT dependency is built 设置上有一个“阈值”字段,可以控制哪些构建将触发

来自pipeline-maven-plugin README

基于在 Maven 中达到的Maven lifecycle phase 的阈值 上游作业的构建(打包、安装、部署)。默认情况下,仅 到达部署阶段的 Maven 构建将触发下游 构建。

例如,在脚本化管道的withMaven() 中,您可以设置pipelineGraphPublisherlifecycleThreshold: 'deploy',例如:

    withMaven(
      maven: MAVEN_VERSION,
      jdk: JAVA_VERSION,
      mavenOpts: MAVEN_OPTS,
      globalMavenSettingsConfig: globals.MAVEN_SETTINGS_ID,
      options: [
        pipelineGraphPublisher(
          lifecycleThreshold: 'deploy',
          includeSnapshotVersions: true
        )
      ]) {

      sh("mvn ${PHASE}")
    }

然后任何执行生命周期阶段的 SNAPSHOT 构建以下deploy(例如packageinstall)将不会触发下游作业。请注意,deploy 已经是默认设置,因此此示例并不是特别有用,但它展示了如何使用该设置,您可能希望将其设置为另一个阶段。

第一部分已经完成,但是现在您需要一种方法来有条件地为您想要触发下游构建的构建执行不同的 Maven 生命周期阶段。想要触发下游构建。我们根据分支名称执行此操作,以便 Pull Request 和 Release 分支不会触发上游包:

/**
 * Return the correct Maven goal for the current branch
 *
 * Because the pipelineGraphPublisher's lifecycleThreshold in the withMaven() call above is set to 'deploy', pipelines
 * that run the 'install' goal will not trigger downstream jobs; this helps us minimize superfluous Jenkins builds:
 *
 *   https://github.com/jenkinsci/pipeline-maven-plugin/blob/master/README.adoc#trigger-downstream-pipeline-when-a-snapshot-is-built
 */
String getGoalForCurrentBranch() {
  if ( env.BRANCH_NAME ==~ /(^PR-(\d+)$)|(^releases\/v.*)/ ) {
    echo("Pull Request or release branch detected! Executing Maven 'install' goal rather than 'deploy' goal to avoid triggering downstream Jenkins jobs")
    return 'install'
  }
  return 'deploy'
}

然后,您可以在执行mvn 的任何位置调用此getGoalForCurrentBranch() 方法以确定执行哪个生命周期阶段:

withMaven(
  ...
  sh("mvn ${getGoalForCurrentBranch()}")
)

大多数分支将执行 mvn deploy 并且触发下游 Jenkins 作业,但 Pull Request 分支将执行 mvn install 并且不会触发下游作业。

对此的警告是,您可能还有其他依赖于某些生命周期阶段的东西。在上面的示例中,Pull Request 分支工件不会部署到您的工件存储库(例如 Nexus)。在我们的例子中,这实际上是期望的行为,但您需要确定什么是您可以接受的,并相应地调整您的阈值。

【讨论】:

    【解决方案2】:

    在依赖项目中,您可以通过

    禁用“每当构建 SNAPSHOT 依赖项时构建”挂钩
    if (branchName.indexOf("mule4auto") >= 0) {
        println "for mule4auto do not build when mulestac is build";
        // for mule4auto do not build when mulestac is build, wait for
        // mule4auto-converter project has run (commited something).
    } else {
        tempPipelineTriggers += [
          snapshotDependencies()
        ];
    }
    println "triggers: tempPipelineTriggers=${tempPipelineTriggers}";
    

    此外,您可能需要禁用不应构建的特定分支的指纹(在我们的例子中是 mule4auto):

    // see https://github.com/jenkinsci/pipeline-maven-plugin/blob/master/README.adoc
    def tempMavenOptions = [];
    // disable Archiving (fingerprinting should still work)
    tempMavenOptions += artifactsPublisher(disabled: true);
    if (branchName.indexOf("mule4auto") >= 0) {
      println "Disable fingerprint for mule4auto to prevent jobs building when mulestac4 SNAPSHOT is build";
      tempMavenOptions += dependenciesFingerprintPublisher(disabled: true);
      tempMavenOptions += pipelineGraphPublisher(disabled: true);
    }
    
    // see https://plugins.jenkins.io/pipeline-maven
    withMaven(
      // Maven installation declared in the Jenkins "Global Tool Configuration"
      maven: toolMaven,
      jdk: toolJdkToBeUsed,
      options: tempMavenOptions
      ) {
        println "JAVA_HOME ${JAVA_HOME}";
        println "MAVEN_HOME ${MAVEN_HOME}";
       ....
      })
    

    (都在目标管道中)

    【讨论】:

      【解决方案3】:

      我在 Jenkins 的工作中没有看到像 “只要构建上游依赖项就构建”这样的选项。它被称为“只要构建了 SNAPSHOT 依赖项就构建”(Jenkins v1.592 及其最新插件)。是这个意思吗?

      它的内联帮助中还有最后一句:“如果这种行为有问题,请取消选中此选项。” :-)

      我不知道 Conditional BuildStep Plugin 在这种情况下是否会有所帮助。我们使用它,但不是为了达到这个目的。

      根据您的工作运行时间,我建议:

      1. 如果作业运行时间不长(让我们说几分钟)
      2. 按照建议停用 build-whenever-all-and-everywhere 并使用 Post-build ActionsBuild other projectsTrigger parameterized build on other project 如果您的作业运行时间更长,则建立真正的上游/下游构建流程

      【讨论】:

      • 是的,你是对的,我的错误 - 我已经编辑了问题以显示正确的“每当构建 SNAPSHOT 依赖项时构建”文本。感谢您指出这一点!
      • 一些优点,尽管它的问题不足以保证禁用它。它很有用(我们可以使用 pom 来更新依赖管理,而不是手动配置数百个作业),但是由于我们有一个 cloudbees Enterprise Jenkins 许可证和有限数量的构建从站,这确实意味着我们有时会被不需要的作业阻塞,并且没有尽可能有效地使用资源。不过,您已经给了我一个想法,如果我们在开发时停止使用 -SNAPSHOT 版本,这可能会缓解问题。我会尝试一些事情:-)
      猜你喜欢
      • 1970-01-01
      • 2010-12-23
      • 2016-02-18
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 2011-07-11
      • 2017-11-09
      • 2020-06-15
      相关资源
      最近更新 更多