12

我有一个名为 multibranch-test 的 github 存储库,其中包含两个子目录 Project1、Project2。

PS C:\Repos\multibranch-test> tree . Folder PATH listing for volume Windows Volume serial number is 2085-6D3D C:\REPOS\MULTIBRANCH-TEST ├───Project1 └───Project2

每个子目录都有一个 Jenkinsfile 和该项目的代码。

在 Jenkins 中,我有两个多分支管道作业 - 一个用于 Project1,一个用于 Project2。在 Project1 的配置中,如果在 Project2 的子目录中推送了提交,我不希望推送通知或轮询来构建 Project1。

因此,在 Project1 中,我配置了其他行为:

  • 高级克隆行为:检查浅克隆
  • 稀疏结帐路径设置为 Project1#
  • 轮询会忽略某些路径中的提交
    • 包含区域: Project1/*
    • 排除地区: *
  • 构建配置:脚本路径:Project1/Jenkinsfile

正在发生的事情是,如果我在子目录 Project2 中向 master 提交提交,Project1 和 Project2 作业都会构建。我只希望 Project2 构建。有人可以指出我做错了什么吗?

两个项目的 Jenkinsfiles 相似,如下所示:

#!groovy
node  {
    stage ('checkout') {
        checkout scm
    }

    stage ('build') {
        dir ('Project1') {
            bat 'powershell -Command gci'
            bat 'powershell -Command gci env:'
            bat 'powershell -File .\\Project1.ps1'
        }
    }
4

3 回答 3

14

这对我们来说是一个很大的麻烦,但我们能够通过一些变通方法解决它。

我们有一个由 GitHub 提交挂钩触发的主 Jenkins 作业。它找出自上次提交以来发生了什么变化,然后触发其他特定于服务的Jenkins 作业。

我们还有一些我们正在使用的其他约定(例如服务、目录和 Jenkins 作业的命名约定),这些约定没有在此处指定,但希望这会对某人有所帮助。

以下是解决方案中每个组件的细分:

  1. monorepo 中每个服务的 Jenkins 作业和相应的 Jenkinsfiles。

C:\REPOS\MULTIBRANCH-TEST\Project1\Jenkinsfile(你的构建逻辑在这里) C:\REPOS\MULTIBRANCH-TEST\Project2\Jenkinsfile(你的构建逻辑在这里)

  1. 一个 shell 脚本,它获取自上次提交以来更改的列表(改编自此博客文章)。

C:\REPOS\MULTIBRANCH-TEST\change-sets.sh

    #!/usr/bin/env bash

    changeSets=(`git diff-tree --name-status HEAD`)
    for(( i=0; i<${#changeSets[@]}; i++))
    do
      if [ ${changeSets[$i]} == "M" ]
      then
        echo ${changeSets[$i+1]}
      fi
    done
  1. 基于 GitHub 提交挂钩的 Jenkins 作业

C:\REPOS\MULTIBRANCH-TEST\Jenkinsfile

    #!/usr/bin/env groovy

    pipeline {
        agent any

        stages {

            stage('Define Services to Build') {
                steps {
                    script {

                        def SERVICES_TO_BUILD = sh script:"./change-sets.sh", returnStdout: true
                        SERVICES_TO_BUILD.split("\n").each {
                            echo "Triggering build for ${it}"
                            try {
                                build job: "${it}", propagate: false, wait: false
                            } catch (ex) {
                                echo "Failed to trigger build for ${it}: ${ex.message}"
                            }

                        }
                    }
                }
            }
        }
    }
于 2017-10-11T22:59:22.583 回答
3

默认的 Jenkins 行为是,如果项目的 repo 获得提交,项目将被重建,因此您在 repo 中的提交会为两个 Jenkins 项目生成事件并触发两个构建。看看 Jenkins 文档:https ://jenkins.io/doc/book/pipeline/

从 Jenkins 的角度来看,很难判断项目 1 或 2 是否发生了变化——立即可见的是“新提交到监视的 repo”。

简单的解决方案是将 repo 拆分为两个单独的 repos,每个项目一个。由于它们应该单独构建,因此应该不是问题。

于 2017-07-08T04:54:46.177 回答
0

您可以为整个 repo 创建一个作业,查看提交给您带来的更改,然后触发项目 1 或 2 或两者的相应 Jenkinsfile

于 2017-08-02T10:43:34.070 回答