如何配置 Jenkins 管道以通过轮询 SubVersion 触发?
How do I configure a Jenkins Pipeline to be triggered by polling SubVersion?
我们使用 Jenkins 进行持续集成已有一段时间了。
一个典型的构建作业在 "Source Code Management" 部分指定 SVN 存储库和凭据,然后在 "Build Triggers" 部分我们启用 "Poll SCM" 每 10 分钟轮询一次的计划 (H/10 * * * *)。
我们已经更新到最新版本的 Jenkins,并正在寻求建立管道构建。典型的管道脚本如下所示:
node {
stage 'Build'
build job: 'MyApplication Build'
stage 'Deploy to test environment'
build job: 'MyApplication Deploy', parameters: [
[$class: 'StringParameterValue', name: 'DatabaseServer', value: 'DatabaseServer1'],
[$class: 'StringParameterValue', name: 'WebServer', value: 'WebServer1']
]
stage 'RunIntegrationTests'
build job: 'MyApplication Test', parameters: [
[$class: 'StringParameterValue', name: 'DatabaseServer', value: 'DatabaseServer1'],
[$class: 'StringParameterValue', name: 'WebServer', value: 'WebServer1']
]
}
当手动触发管道作业时,一切 运行 都很好,但是我们希望每次将新修订签入 SVN 存储库时,此管道都是 运行。管道配置确实有一个 "poll SCM" 构建触发器选项,但没有一个 "Source Code Management" 部分,您可以在其中指定您的存储库。我们怎样才能做到这一点?
我发现有效的解决方案是:
- 将管道脚本移动到一个文件中(默认为 JenkinsFile)并将其存储在我的 SubVersion 项目的根目录中。
- 将我的管道作业定义源设置为 "Pipeline script from SCM",按照正常的 Jenkins 构建作业在 SubVersion 中输入在哪里可以找到我的项目的详细信息,并将脚本路径设置为指向包含管道的 JenkinsFile脚本。
- 将管道作业的构建触发器设置为 "Poll SCM" 并输入时间表。
- 手动运行管道作业
似乎是第 4 步,手动 运行ning 管道作业导致轮询触发器选择正确的存储库进行轮询。在那之前它似乎不知道去哪里找。
我认为您在 Build 阶段之前需要一个 Checkout 阶段,其中包含 SCM 信息。这允许作业以所需的间隔轮询 SCM 和 运行 管道。
您甚至可以使用管道脚本,而无需将管道代码存储为 SCM 中的 JenkinsFile。
下面是我的 SVN Checkout 阶段流水线代码在我的 Build 阶段之前:
stage('Checkout') {
checkout([$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: 'buildbot',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[credentialsId: 'b86bc2b6-994b-4811-ac98-0f35e9a9b114',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: "http://svn/something/trunk/"]],
workspaceUpdater: [$class: 'UpdateUpdater']])
}
虽然适用于我的管道作业。希望这有帮助。
使用 Jenkins Declarative Pipeline 脚本,您可以配置一个作业以每 10 分钟轮询一次 SVN 存储库 URL,如下所示:
pipeline {
agent any
triggers {
pollSCM 'H/10 * * * *'
}
stages {
stage('checkout') {
steps {
checkout([
$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[
credentialsId: 'mySvnCredentials',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: 'http://example.com/svn/url/trunk']],
workspaceUpdater: [$class: 'CheckoutUpdater']
])
}
}
}
}
pollSCM
触发器应自动轮询与您的构建关联的所有 SCM 存储库 URL,包括 checkout
步骤指定的 URL,URL 来自 SCM 的声明式管道脚本,以及全局管道库的 URL。但是,如果您真的希望每个修订版的管道都是 运行,则需要设置一个 post-commit hook。
作为管道脚本不是项目的一部分或在作业中定义的替代方法,您可以将 poll: true
添加到结帐阶段。
示例:
stage('checkout') {
checkout(
changelog: true,
poll: true, /*This is the important option*/
scm: [
$class: 'SubversionSCM',
filterChangelog: false,
ignoreDirPropChanges: false,
locations: [...], /*ommited for obvious reasons*/
workspaceUpdater: [$class: 'CheckoutUpdater']
])
}
在第一个 运行 之后,它将从这个 SCM 开始轮询,如果是的话,也会从管道所在的 SCM 开始轮询。
此选项记录在 https://jenkins.io/doc/pipeline/steps/workflow-scm-step/#code-checkout-code-general-scm 页面末尾,没有详细信息。
事实
- Jenkins Pipeline 没有 从 SCM 触发的选项。
- Jenkins Job 可以选择从 SCM 触发。
=> 最简单的方法是:
- 创建一个从 SCM 触发的 Jenkins JOB。
- 将 Jenkin 管道配置为在 Jenkins 作业构建后触发。
就是这样!
因此,我们遇到了 很多 的问题才能让它发挥作用。以下是我们解决问题的方法:
在 Jenkins 中,您创建了一个 管道作业。此工作所需的唯一内容是:
- POLL SCM(具有一些任意值,例如
@monthly
)
- 工作应该在哪里找到你的 Jenkinsfile
所有其他设置都会进入 Jenkinsfile。然而:
triggers {
pollSCM('@monthly')}
应该 STILL 在你的 Jenkinsfile 中指定,即使它已经在你的工作中指定。
但是,正如 所说,您需要先结帐,然后再进行任何其他操作。在我们的案例中,出于多种原因,我们希望避免这种情况。幸运的是,如果您有以下情况,它仍然有效:
depthOption: 'empty'
.
最后,您需要手动启动第一个作业运行。
我们制作了一个小功能,您或许可以使用:
def checkoutSVN(Boolean ignoreExternalsOption, String local, String remote, String updater) {
checkout([$class: 'SubversionSCM',
additionalCredentials:
[[credentialsId: 'get-this-from-your-jenkins',
realm: '<https://your-server> CollabNet Subversion Repository']],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[credentialsId: 'get-this-from-your-jenkins',
depthOption: 'empty',
ignoreExternalsOption: ignoreExternalsOption,
local: local,
remote: remote]],
quietOperation: false,
workspaceUpdater: [$class: updater]])}
我们使用 Jenkins 进行持续集成已有一段时间了。 一个典型的构建作业在 "Source Code Management" 部分指定 SVN 存储库和凭据,然后在 "Build Triggers" 部分我们启用 "Poll SCM" 每 10 分钟轮询一次的计划 (H/10 * * * *)。 我们已经更新到最新版本的 Jenkins,并正在寻求建立管道构建。典型的管道脚本如下所示:
node {
stage 'Build'
build job: 'MyApplication Build'
stage 'Deploy to test environment'
build job: 'MyApplication Deploy', parameters: [
[$class: 'StringParameterValue', name: 'DatabaseServer', value: 'DatabaseServer1'],
[$class: 'StringParameterValue', name: 'WebServer', value: 'WebServer1']
]
stage 'RunIntegrationTests'
build job: 'MyApplication Test', parameters: [
[$class: 'StringParameterValue', name: 'DatabaseServer', value: 'DatabaseServer1'],
[$class: 'StringParameterValue', name: 'WebServer', value: 'WebServer1']
]
}
当手动触发管道作业时,一切 运行 都很好,但是我们希望每次将新修订签入 SVN 存储库时,此管道都是 运行。管道配置确实有一个 "poll SCM" 构建触发器选项,但没有一个 "Source Code Management" 部分,您可以在其中指定您的存储库。我们怎样才能做到这一点?
我发现有效的解决方案是:
- 将管道脚本移动到一个文件中(默认为 JenkinsFile)并将其存储在我的 SubVersion 项目的根目录中。
- 将我的管道作业定义源设置为 "Pipeline script from SCM",按照正常的 Jenkins 构建作业在 SubVersion 中输入在哪里可以找到我的项目的详细信息,并将脚本路径设置为指向包含管道的 JenkinsFile脚本。
- 将管道作业的构建触发器设置为 "Poll SCM" 并输入时间表。
- 手动运行管道作业
似乎是第 4 步,手动 运行ning 管道作业导致轮询触发器选择正确的存储库进行轮询。在那之前它似乎不知道去哪里找。
我认为您在 Build 阶段之前需要一个 Checkout 阶段,其中包含 SCM 信息。这允许作业以所需的间隔轮询 SCM 和 运行 管道。
您甚至可以使用管道脚本,而无需将管道代码存储为 SCM 中的 JenkinsFile。
下面是我的 SVN Checkout 阶段流水线代码在我的 Build 阶段之前:
stage('Checkout') {
checkout([$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: 'buildbot',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[credentialsId: 'b86bc2b6-994b-4811-ac98-0f35e9a9b114',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: "http://svn/something/trunk/"]],
workspaceUpdater: [$class: 'UpdateUpdater']])
}
虽然适用于我的管道作业。希望这有帮助。
使用 Jenkins Declarative Pipeline 脚本,您可以配置一个作业以每 10 分钟轮询一次 SVN 存储库 URL,如下所示:
pipeline {
agent any
triggers {
pollSCM 'H/10 * * * *'
}
stages {
stage('checkout') {
steps {
checkout([
$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[
credentialsId: 'mySvnCredentials',
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
remote: 'http://example.com/svn/url/trunk']],
workspaceUpdater: [$class: 'CheckoutUpdater']
])
}
}
}
}
pollSCM
触发器应自动轮询与您的构建关联的所有 SCM 存储库 URL,包括 checkout
步骤指定的 URL,URL 来自 SCM 的声明式管道脚本,以及全局管道库的 URL。但是,如果您真的希望每个修订版的管道都是 运行,则需要设置一个 post-commit hook。
作为管道脚本不是项目的一部分或在作业中定义的替代方法,您可以将 poll: true
添加到结帐阶段。
示例:
stage('checkout') {
checkout(
changelog: true,
poll: true, /*This is the important option*/
scm: [
$class: 'SubversionSCM',
filterChangelog: false,
ignoreDirPropChanges: false,
locations: [...], /*ommited for obvious reasons*/
workspaceUpdater: [$class: 'CheckoutUpdater']
])
}
在第一个 运行 之后,它将从这个 SCM 开始轮询,如果是的话,也会从管道所在的 SCM 开始轮询。
此选项记录在 https://jenkins.io/doc/pipeline/steps/workflow-scm-step/#code-checkout-code-general-scm 页面末尾,没有详细信息。
事实
- Jenkins Pipeline 没有 从 SCM 触发的选项。
- Jenkins Job 可以选择从 SCM 触发。
=> 最简单的方法是:
- 创建一个从 SCM 触发的 Jenkins JOB。
- 将 Jenkin 管道配置为在 Jenkins 作业构建后触发。
就是这样!
因此,我们遇到了 很多 的问题才能让它发挥作用。以下是我们解决问题的方法:
在 Jenkins 中,您创建了一个 管道作业。此工作所需的唯一内容是:
- POLL SCM(具有一些任意值,例如
@monthly
) - 工作应该在哪里找到你的 Jenkinsfile
所有其他设置都会进入 Jenkinsfile。然而:
triggers {
pollSCM('@monthly')}
应该 STILL 在你的 Jenkinsfile 中指定,即使它已经在你的工作中指定。
但是,正如 depthOption: 'empty'
.
最后,您需要手动启动第一个作业运行。
我们制作了一个小功能,您或许可以使用:
def checkoutSVN(Boolean ignoreExternalsOption, String local, String remote, String updater) {
checkout([$class: 'SubversionSCM',
additionalCredentials:
[[credentialsId: 'get-this-from-your-jenkins',
realm: '<https://your-server> CollabNet Subversion Repository']],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[credentialsId: 'get-this-from-your-jenkins',
depthOption: 'empty',
ignoreExternalsOption: ignoreExternalsOption,
local: local,
remote: remote]],
quietOperation: false,
workspaceUpdater: [$class: updater]])}