简体   繁体   English

在多个同时上游作业成功后,如何开始 Jenkins 作业?

[英]How do I make a Jenkins job start after multiple simultaneous upstream jobs succeed?

In order to get the fastest feedback possible, we occasionally want Jenkins jobs to run in Parallel.为了获得尽可能最快的反馈,我们偶尔希望 Jenkins 作业并行运行。 Jenkins has the ability to start multiple downstream jobs (or 'fork' the pipeline) when a job finishes. Jenkins 能够在作业完成时启动多个下游作业(或“分叉”管道)。 However, Jenkins doesn't seem to have any way of making a downstream job only start of all branches of that fork succeed (or 'joining' the fork back together).但是,詹金斯似乎没有任何方法可以使下游工作仅在该分叉的所有分支成功启动(或将分叉重新“连接”在一起)。

Jenkins has a "Build after other projects are built" button, but I interpret that as "start this job when any upstream job finishes" (not "start this job when all upstream jobs succeed"). Jenkins 有一个“在构建其他项目后构建”按钮,但我将其解释为“在任何上游工作完成时开始这项工作”(而不是“在所有上游工作成功时开始这项工作”)。

Here is a visualization of what I'm talking about.这是我正在谈论的内容的可视化。 Does anyone know if a plugin exists to do what I'm after?有谁知道是否有插件可以做我所追求的事情?构建管道


Edit:编辑:

When I originally posted this question in 2012, Jason's answer (the Join and Promoted Build plugins) was the best, and the solution I went with.当我最初在 2012 年发布这个问题时,Jason 的回答(Join 和 Promotiond Build 插件)是最好的,也是我采用的解决方案。

However, dnozay's answer (The Build Flow plugin) was made popular a year or so after this question, which is a much better answer.然而,在这个问题一年左右之后,dnozay 的答案(The Build Flow 插件)变得流行起来,这是一个更好的答案。 For what it's worth, if people ask me this question today, I now recommend that instead.对于它的价值,如果今天有人问我这个问题,我现在建议改为。

Pipeline plugin管道插件

You can use the Pipeline Plugin (formerly workflow-plugin ).您可以使用流水线插件(以前的workflow-plugin )。

It comes with many examples , and you can follow this tutorial .它带有许多示例,您可以按照本教程进行操作

eg例如

// build
stage 'build'
...

// deploy
stage 'deploy'
...

// run tests in parallel
stage 'test'
parallel 'functional': {
  ...
}, 'performance': {
  ...
}

// promote artifacts
stage 'promote'
...

Build flow plugin构建流插件

You can also use the Build Flow Plugin .您还可以使用Build Flow Plugin It is simply awesome - but it is deprecated (development frozen).它简直太棒了 - 但它已被弃用(开发冻结)。

Setting up the jobs设置作业

Create jobs for:为以下人员创建工作:

  • build建造
  • deploy部署
  • performance tests性能测试
  • functional tests功能测试
  • promotion晋升

Setting up the upstream设置上游

  1. in the upstream (here build ) create a unique artifact, eg:在上游(这里是build )创建一个独特的工件,例如:

     echo ${BUILD_TAG} > build.tag
  2. archive the build.tag artifact.归档build.tag工件。

  3. record fingerprints to track file usage;记录指纹以跟踪文件使用情况; if any job copies the same build.tag file and records fingerprints, you will be able to track the parent.如果任何作业复制相同的build.tag文件并记录指纹,您将能够跟踪父级。
  4. Configure to get promoted when promotion job is successful.配置为在promotion作业成功时获得升级。

Setting up the downstream jobs设置下游作业

  1. I use 2 parameters PARENT_JOB_NAME and PARENT_BUILD_NUMBER我使用 2 个参数PARENT_JOB_NAMEPARENT_BUILD_NUMBER
  2. Copy the artifacts from upstream build job using the Copy Artifact Plugin使用Copy Artifact Plugin从上游build作业复制工件

    • Project name = ${PARENT_JOB_NAME}项目名称 = ${PARENT_JOB_NAME}
    • Which build = ${PARENT_BUILD_NUMBER}哪个版本 = ${PARENT_BUILD_NUMBER}
    • Artifacts to copy = build.tag要复制的工件 = build.tag
  3. Record fingerprints;记录指纹; that's crucial.这很关键。

Setting up the downstream promotion job设置下游推广作业

Do the same as the above, to establish upstream-downstream relationship.同上,建立上下游关系。 It does not need any build step.它不需要任何构建步骤。 You can perform additional post-build actions like "hey QA, it's your turn".您可以执行其他构建后操作,例如“嘿 QA,轮到您了”。

Create a build flow job创建构建流程作业

// start with the build
parent = build("build")
parent_job_name = parent.environment["JOB_NAME"]
parent_build_number = parent.environment["BUILD_NUMBER"]

// then deploy
build("deploy")

// then your qualifying tests
parallel (
    { build("functional tests",
          PARENT_BUILD_NUMBER: parent_build_number,
          PARENT_JOB_NAME: parent_job_name) },
    { build("performance tests",
          PARENT_BUILD_NUMBER: parent_build_number,
          PARENT_JOB_NAME: parent_job_name) }
)

// if nothing failed till now...
build("promotion",
    PARENT_BUILD_NUMBER: parent_build_number,
    PARENT_JOB_NAME: parent_job_name)

// knock yourself out...
build("more expensive QA tests",
    PARENT_BUILD_NUMBER: parent_build_number,
    PARENT_JOB_NAME: parent_job_name)

good luck.祝你好运。

There are two solutions that I have used for this scenario in the past:我过去曾在此场景中使用过两种解决方案:

  1. Use the Join Plugin on your "deploy" job and specify "promote" as the targeted job.在您的“部署”作业上使用加入插件,并将“提升”指定为目标作业。 You would have to specify "Functional Tests" and "Performance Tests" as the joined jobs and start them via in some fashion, post build.您必须将“功能测试”和“性能测试”指定为加入的作业,并通过后期构建以某种方式启动它们。 The Parameterized Trigger Plugin is good for this. 参数化触发器插件对此很有用。

  2. Use the Promoted Builds Plugin on your "deploy" job, specify a promotion that works when downstream jobs are completed and specify Functional and Performance test jobs.在您的“部署”作业上使用提升构建插件,指定在下游作业完成时起作用的提升,并指定功能和性能测试作业。 As part of the promotion action, trigger the "promote" job.作为提升操作的一部分,触发“提升”作业。 You still have to start the two test jobs from "deploy"您仍然必须从“部署”开始这两个测试作业

There is a CRITICAL aspect to both of these solutions: fingerprints must be correctly used.这两种解决方案都有一个关键方面:必须正确使用指纹。 Here is what I found:这是我发现的:

  1. The "build" job must ORIGINATE a new fingerprinted file. “构建”作业必须创建一个新的指纹文件。 In other words, it has to fingerprint some file that Jenkins thinks was originated by the initial job.换句话说,它必须对 Jenkins 认为是由初始作业发起的某个文件进行指纹识别。 Double check the "See Fingerprints" link of the job to verify this.仔细检查作业的“查看指纹”链接以验证这一点。
  2. All downstream linked jobs (in this case, "deploy", "Functional Tests" and "Performance tests") need to obtain and fingerprint this same file.所有下游链接的作业(在这种情况下,“部署”、“功能测试”和“性能测试”)都需要获取并指纹同一文件。 The Copy Artifacts plugin is great for this sort of thing. Copy Artifacts 插件非常适合这类事情。
  3. Keep in mind that some plugins allow you change the order of fingerprinting and downstream job starting;请记住,某些插件允许您更改指纹识别和下游作业启动的顺序; in this case, the fingerprinting MUST occur before a downstream job fingerprints the same file to ensure the ORIGIN of the fingerprint is properly set.在这种情况下,指纹识别必须发生在下游作业对同一文件进行指纹识别之前,以确保正确设置指纹的 ORIGIN。

Jenkins 最近宣布了对工作流的一流支持。

The Multijob plugin works beautifully for that scenario. Multijob 插件非常适合这种情况。 It also comes in handy if you want a single "parent" job to kick off multiple "child" jobs but still be able to execute each of the children manually, by themselves.如果您希望单个“父”作业启动多个“子”作业,但仍然能够自己手动执行每个子作业,它也会派上用场。 This works by creating "phases", to which you add 1 to n jobs.这是通过创建“阶段”来实现的,您可以向其中添加 1 到 n 个作业。 The build only continues when the entire phase is done, so if a phase as multiple jobs they all must complete before the rest are executed.只有在整个阶段完成后,构建才会继续,所以如果一个阶段作为多个作业,它们都必须在执行其余部分之前完成。 Naturally, it is configurable whether the build continues if there is a failure within the phase.当然,如果阶段内出现故障,构建是否继续是可配置的。

I believe the Workflow Plugin is now called the Pipeline Plugin and is the (current) preferred solution to the original question, inspired by the Build Flow Plugin.我相信 Workflow Plugin 现在被称为Pipeline Plugin并且是原始问题的(当前)首选解决方案,受到 Build Flow Plugin 的启发。 There is also a Getting Started Tutorial in GitHub. GitHub 中还有一个入门教程

Answers by jason & dnozay are good enough. jason 和 dnozay 的回答已经足够好了。 But in case someone is looking for easy way just use JobFanIn plugin .但如果有人正在寻找简单的方法,只需使用JobFanIn 插件

This diamond dependency build pipeline could be configured with the DepBuilder plugin .这个菱形依赖构建管道可以使用DepBuilder 插件进行配置。 DepBuilder is using its own domain specific language, that would in this case look like: DepBuilder 使用自己的领域特定语言,在这种情况下看起来像:

_BUILD {
    // define the maximum duration of the build (4 hours)
    maxDuration: 04:00 
}

// define the build order of the existing Jenkins jobs
Build -> Deploy
Deploy -> "Functional Tests" -> Promote
Deploy -> "Performance Tests" -> Promote

DepBuilder 插件 UI 的屏幕截图

After building the project, the build visualization will be shown on the project dashboard page:构建项目后,构建可视化将显示在项目仪表板页面上:

构建管道可视化

If any of the upstream jobs didn't succeed, the build will be automatically aborted.如果任何上游作业没有成功,构建将自动中止。 Abort behavior could be tweaked on a per job basis, for more info see the DepBuilder documentation .可以在每个作业的基础上调整中止行为,有关更多信息,请参阅DepBuilder 文档

失败构建的屏幕截图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM