如何使用GitHub Org插件在Jenkins流水线(Jenkinsfile)中触发另一个作业?

222

我该如何在Jenkinsfile内部触发另一个作业的构建?

我假设这个作业是同一GitHub组织下的另一个仓库,它已经拥有自己的Jenkins文件。

同时,我希望只在分支名为master时执行此操作,因为对于任何本地分支触发下游构建都没有意义。

更新:

stage 'test-downstream'
node {
     def job = build job: 'some-downtream-job-name'
}

然而,当我执行时出现错误。

找不到名为 some-downtream-job-name 的参数化作业

我确定这个作业存在于Jenkins中,并且与当前作业在同一个组织文件夹下。它是另一个拥有自己的 Jenkinsfile 的作业。

请注意,这个问题特定于GitHub Organization Plugin,该插件会为您的GitHub组织中的每个存储库和分支自动创建和维护作业。

5个回答

184

14
构建任务必须嵌入一步骤中(从版本0.5开始)。 - rhoerbe
7
在执行“build”命令时,Jenkins作业的BUILD_NUMBER是否被返回?如何在以下阶段之一访问BUILD_NUMBER?有人知道那个命令在哪里有记录吗? - user909481
11
现在常见的是这种类型的构建作业:build job: 'freestyle', parameters: [string(name: 'param1', value:'test_param'), string(name:'dummy', value: "${index}")]。来源为:https://jenkins.io/doc/pipeline/examples/#jobs-in-parallel。 - BartBiczBoży
但是如何使用传递给第二个作业的这些参数呢? - Gentle
6
有趣的是,对我来说build job: 'RunArtInTest', parameters: [[$class: 'StringParameterValue', name: 'systemname', value: systemname]]没有起作用,但是build job: 'RunArtInTest', parameters: [string(name: 'systemname', value: "${VALUE}")]却有效。 - Alberto C
显示剩余3条评论

170
首先,将 build 步骤包装在 node 中是浪费执行器插槽。你的上游执行器没有任何原因会闲置。
其次,在多分支项目中,您可以使用环境变量 BRANCH_NAME 使逻辑条件基于当前分支。
第三,job 参数采用绝对或相对作业名称。如果您提供一个没有任何路径限定的名称,则指的是同一文件夹中的另一个作业,这在多分支项目的情况下意味着同一存储库的另一个分支。
因此,你可能想要写的是:
if (env.BRANCH_NAME == 'master') {
    build '../other-repo/master'
}

2
谢谢!如果你知道如何在不等待构建完成的情况下触发此构建,那就太棒了 :) - sorin
64
检查_Snippet Generator_:build job: '../other-repo/master', wait: false该代码意思为在_Snippet Generator_中生成的代码片段中,执行一个构建任务(build job)去编译另一个仓库(other-repo)中的主要代码(master),并且不等待(wait: false)该任务完成。 - Jesse Glick
3
有没有一种方法可以使用动态分支名称来调用构建步骤?类似于 build job: '../other-repo/$BRANCH_NAME',其中 $BRANCH_NAME 是与运行多分支项目的分支相关的 Jenkins 环境变量? - msteppe91
4
如果${BRANCH_NAME}作为环境变量存在,那么简单的字符串替换就可以了。只需切换引用字符串的引号从单引号 ' 到双引号 " 即可。例如:build job: "../other-repo/${BRANCH_NAME}" - Cinderhaze
10
build job 的 API 链接为:https://jenkins.io/doc/pipeline/steps/pipeline-build-step/。 - Katie
显示剩余2条评论

89

您可以使用 Jenkins Pipeline 中的build job 步骤 (最低 Jenkins 要求: 2.130)。

这里是 build 步骤的完整 API: https://jenkins.io/doc/pipeline/steps/pipeline-build-step/

如何使用 build:

  • job: 构建下游作业的名称。可以是另一个 Pipeline 作业,但更常见的是 freestyle 或其他项目。
    • 如果作业位于此上游 Pipeline 作业的同一文件夹中,请使用简单名称;
    • 您可以使用相对路径,例如 ../sister-folder/downstream;
    • 或者您可以使用绝对路径, 如 /top-level-folder/nested-folder/downstream

使用分支作为参数触发另一个作业

在我们公司中,许多分支包括“/”。您必须将任何“/”实例替换为“%2F”(因为它出现在作业的 URL 中)。

在此示例中,我们正在使用相对路径

    stage('Trigger Branch Build') {
        steps {
            script {
                    echo "Triggering job for branch ${env.BRANCH_NAME}"
                    BRANCH_TO_TAG=env.BRANCH_NAME.replace("/","%2F")
                    build job: "../my-relative-job/${BRANCH_TO_TAG}", wait: false
            }
        }
    }

使用构建编号作为参数触发另一个作业

build job: 'your-job-name', 
    parameters: [
        string(name: 'passed_build_number_param', value: String.valueOf(BUILD_NUMBER)),
        string(name: 'complex_param', value: 'prefix-' + String.valueOf(BUILD_NUMBER))
    ]

同时触发多个作业

来源:https://jenkins.io/blog/2017/01/19/converting-conditional-to-pipeline/

有关并行处理的更多信息,请参见:https://jenkins.io/doc/book/pipeline/syntax/#parallel

    stage ('Trigger Builds In Parallel') {
        steps {
            // Freestyle build trigger calls a list of jobs
            // Pipeline build() step only calls one job
            // To run all three jobs in parallel, we use "parallel" step
            // https://jenkins.io/doc/pipeline/examples/#jobs-in-parallel
            parallel (
                linux: {
                    build job: 'full-build-linux', parameters: [string(name: 'GIT_BRANCH_NAME', value: env.BRANCH_NAME)]
                },
                mac: {
                    build job: 'full-build-mac', parameters: [string(name: 'GIT_BRANCH_NAME', value: env.BRANCH_NAME)]
                },
                windows: {
                    build job: 'full-build-windows', parameters: [string(name: 'GIT_BRANCH_NAME', value: env.BRANCH_NAME)]
                },
                failFast: false)
        }
    }

或者,另一种选择:

    stage('Build A and B') {
            failFast true
            parallel {
                stage('Build A') {
                    steps {
                            build job: "/project/A/${env.BRANCH}", wait: true
                    }
                }
                stage('Build B') {
                    steps {
                            build job: "/project/B/${env.BRANCH}", wait: true
                    }
                }
            }
    }

1
这太棒了,代码片段生成器实际上会为您提供所有参数作为字段,并为您执行任务。对我来说,我想使用不同的参数运行相同分支的新构建,所以只需 build job: BRANCH_NAME, ...。我用这个启用了一个基本的CD流程 :) - Max Cascone

30

build命令用于在Jenkins中触发其他作业。

示例在github上

该作业必须存在于Jenkins中,并且可以进行参数化设置。至于分支,我想您可以从Git中读取它。


3
我尝试添加build job: 'jobname',但是出现错误找不到名为jobname的参数化作业。我可以保证,在组织文件夹中有一个同级别命名为jobname的作业存在。 - sorin
1
有一个工作,但这个工作没有参数化。虽然如此,我正在努力理解如何对GitHub组织插件创建的工作进行参数化。 - yiwen
7
工作名称格式为:构建任务:"${ORGANISATION_NAME}/${REPO_NAME}/master" - Sahil Ahuja
2
@SahilAhuja 这完全是基于你的Jenkins布局而定的,如果你想使用绝对路径,你需要以“/”开头。相对路径也可以;sorin的问题可能是调用“build”的作业是一个多分支作业,这意味着像“jobname”这样的路径会尝试构建同一作业的分支“jobname”;它需要改为“../jobname/branchname”。 - Michael Mrozek
1
这个运行良好,但是如果指定的分支不存在会发生什么? - Jaime Alcántara Arnela
try { build(job:jobname, wait:false, parameters:params) } catch (Exception ex) { println("Job ${jobname} not triggered: ${ex}") } - Ed Randall

12

使用构建作业插件来执行此任务,以便从Jenkins文件触发其他作业。您可以添加各种逻辑以执行并行、节点和代理选项和步骤来触发外部作业。我提供了一些易于阅读的示例菜谱。

1.在Jenkins文件中触发外部作业的示例,附带条件示例:

if (env.BRANCH_NAME == 'master') {
  build job:'exactJobName' , parameters:[
    string(name: 'keyNameOfParam1',value: 'valueOfParam1')
    booleanParam(name: 'keyNameOfParam2',value:'valueOfParam2')
 ]
}

2. 在Jenkins文件中使用条件语句触发多个作业的示例:

 def jobs =[
    'job1Title'{
    if (env.BRANCH_NAME == 'master') {
      build job:'exactJobName' , parameters:[
        string(name: 'keyNameOfParam1',value: 'valueNameOfParam1')
        booleanParam(name: 'keyNameOfParam2',value:'valueNameOfParam2')
     ]
    }
},
    'job2Title'{
    if (env.GIT_COMMIT == 'someCommitHashToPerformAdditionalTest') {
      build job:'exactJobName' , parameters:[
        string(name: 'keyNameOfParam3',value: 'valueOfParam3')
        booleanParam(name: 'keyNameOfParam4',value:'valueNameOfParam4')
        booleanParam(name: 'keyNameOfParam5',value:'valueNameOfParam5')
     ]
    }
}

但是如何接收和使用第二个作业中的参数? - Gentle
2
@Gentle。您可以通过params.systemname访问传递的参数。 - Pankaj Shinde
触发的作业是否有可能返回一个返回代码,指示它是否成功完成或失败?如果是,请举个例子。 - anar chipur
在这个例子中,我该如何开始“ def jobs”? - elulcao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接