Jenkins多分支 – 排除既是PR又是分支的分支 *除外*

huangapple go评论78阅读模式
英文:

Jenkins Multibranch - exclude branches that are also PRs *except*

问题

在设置 Jenkins 多分支流水线时,我想要“排除作为 PR 提交的分支”,但某些分支除外,我想要同时构建 PR 和原始分支。

以 MASTER 为例:

  • 为 STORY-999 打开一个 PR
    • PR 被构建
    • STORY-999 不会被构建
  • 为 MASTER 打开一个 PR
    • PR 被构建
    • MASTER 也会被构建
英文:

When setting up a Jenkins multibranch pipeline, I would like to "Exclude branches that are filed as PRs", EXCEPT for certain branches, which I want to build both the PR and the original branch simultaneously.

Example using MASTER:

  • Open a PR for STORY-999
    • PR gets built
    • STORY-999 doesn't
  • Open a PR for MASTER
    • PR gets built
    • MASTER also gets built

答案1

得分: 2

您可以在多分支作业设置中按名称筛选分支。

包括特定分支较为棘手,因为Jenkins在传统作业中没有这种设置。

但是,使用Jenkinsfile,您可以尝试以下测试:

node {
    stage('Check Branch') {
        script {
            // 检查分支是否作为PR提交
            if (env.CHANGE_ID) {
                echo "这个分支是作为PR提交的。"

                // 检查分支是否是MASTER或其他特殊分支
                if (env.BRANCH_NAME == 'MASTER' || env.BRANCH_NAME == 'special-branch') {
                    echo "这是一个特殊分支。运行构建步骤。"
                    // 在此处添加您的构建步骤
                } else {
                    echo "这不是一个特殊分支。跳过构建。"
                }
            } else {
                echo "这个分支未作为PR提交。运行构建步骤。"
                // 在此处添加您的构建步骤
            }
        }
    }
}

这仍然会触发作业,即使Jenkins配置为向git服务器报告构建情况 - 即使实际上没有发生任何事情。

确实,更高级的方法是在Jenkinsfile的逻辑之外拦截或决定作业的执行。
但似乎不支持这样的操作。

即使作业被触发,您仍然可以在没有发生任何事情时采取措施以避免报告。

node {
    stage('Check Branch') {
        script {
            // 假设如果是非特殊分支上的PR,则不希望执行任何操作
            if (env.CHANGE_ID && env.BRANCH_NAME != 'MASTER' && env.BRANCH_NAME != 'special-branch') {
                echo "这是一个非特殊分支上的PR。提前退出而不通知。"
                currentBuild.result = 'ABORTED'
                error("由于分支条件,提前退出。")
            }
        }
    }

    // 如果不满足上述条件,您的其他阶段和步骤将正常执行。
    stage('Build') {
        // 在此处添加您的构建步骤
    }

    stage('Notify') {
        // 在此处添加您的SCM通知步骤,例如githubNotify
        // 只有在前面的阶段没有错误时才会运行。
    }
}

提前的error将停止流水线,不会继续执行后续阶段。
设置currentBuild.result = 'ABORTED'将标记构建为中止,您可以将其解释为有条件跳过。
而包含通知阶段,其中包含与SCM通信的步骤,仅在前面的阶段没有错误时才会执行。

然而:

  • 作业仍然会出现在Jenkins中,状态将显示为'ABORTED'或'FAILURE'(取决于是否设置了currentBuild.result)。
  • 即使只是瞬间地触发作业并消耗资源,您仍然会有开销,只是为了决定它们不应该运行。如果分支/PR的创建频率很高,这可能会成为一个问题。
英文:

You can filter by name your branches in a multibranch job setting.

Including certain branches is trickier, since Jenkins does not have this settings in classic jobs.

But using a Jenkinsfile, you can try for testing:

node {
    stage('Check Branch') {
        script {
            // Check if branch is filed as a PR
            if (env.CHANGE_ID) {
                echo "This branch is filed as a PR."

                // Check if branch is MASTER or another special branch
                if (env.BRANCH_NAME == 'MASTER' || env.BRANCH_NAME == 'special-branch') {
                    echo "This is a special branch. Running build."
                    // Your build steps here
                } else {
                    echo "This is not a special branch. Skipping build."
                }
            } else {
                echo "This branch is not filed as a PR. Running build."
                // Your build steps here
            }
        }
    }
}

> This will still trigger job, though. And if Jenkins is configured to report about builds to git server - it will report, even if nothing actually happened.

True, a more advanced approach would be to intercept or decide on the job execution at a higher level, outside the Jenkinsfile's logic.
But that does not seem supported.

Even if the job is triggered, you can do something to avoid reporting when nothing happened, though.

node {
    stage('Check Branch') {
        script {
            // Assuming you do not want to proceed with anything if it is a PR on a non-special branch
            if (env.CHANGE_ID && env.BRANCH_NAME != 'MASTER' && env.BRANCH_NAME != 'special-branch') {
                echo "That is a PR on a non-special branch. Exiting early without notifying."
                currentBuild.result = 'ABORTED'
                error("Exiting early due to branch conditions.")
            }
        }
    }

    // If the above condition is not met, your other stages and steps will execute as normal.
    stage('Build') {
        // Your build steps here
    }

    stage('Notify') {
        // Your SCM notification step here, e.g., githubNotify
        // That will only run if the previous stages completed without erroring out.
    }
}

The early error will stop the pipeline and will not proceed to the subsequent stages.
Setting the currentBuild.result = 'ABORTED' will mark the build as aborted, which you can interpret as a conditional skip.
And the 'Notify' stage, which contains the step that communicates back to the SCM, is only executed if the pipeline did not encounter an error in the preceding stages.

However:

  • The job will still appear in Jenkins, and it will show as either 'ABORTED' or 'FAILURE' (depending on if you set the currentBuild.result or not).
  • you would still have an overhead where jobs are triggered and resources are consumed (even if momentarily) only to decide they should not run. That can become an issue if you have a high frequency of branch/PR creation.

huangapple
  • 本文由 发表于 2023年8月5日 03:27:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838692.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定