仅在主节点上签出和 运行 SCM 管道
Checkout and run SCM pipeline only on master node
我编写了一个接受多个参数的通用管道,以便将预定义 GitHub 存储库中的版本部署到特定节点。我想在 GitHub 上的 Jenkinsfile 上托管此管道,因此我将作业配置为使用“来自 SCM 的管道脚本”。事实是 - 当我尝试构建作业时 - Jenkinsfile 在每个节点上都被检出。是否可以按预期仅在主节点和 运行 管道上检出并执行 Jenkinsfile?
编辑:正如我之前所说,管道工作得很好,并且按照预期将作业设置为与管道脚本一起工作。 问题是,当我尝试将其更改为“来自 SCM 的管道脚本”时,Jenkinsfile 会在每个代理上得到检查,这是一个问题,因为我没有 git 安装在除 master 以外的任何代理上。我希望仅在主代理上检出 Jenkinsfile 并按预期执行。仅供参考,下面的管道:
def agents = "$AGENTS".toString()
def agentLabel = "${ println 'Agents: ' + agents; return agents; }"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
if (agents == null || agents == "") {
println "Skipping build"
skipBuild = true
}
if (!skipBuild) {
println "Agents set for this build: " + agents
}
}
}
}
stage('Powershell deploy script checkout') {
agent { label 'master' }
when {
expression {
!skipBuild
}
}
steps {
git url: 'https://github.com/owner/repo.git', credentialsId: 'git-credentials', branch: 'main'
stash includes: 'deploy-script.ps1', name: 'deploy-script'
}
}
stage('Deploy') {
agent { label agentLabel }
when {
expression {
!skipBuild
}
}
steps {
unstash 'deploy-script'
script {
println "Execute powershell deploy script on agents set for deploy"
}
}
}
}
}
您可以找到有关 jenkins 代理部分的所有信息 here。
很快:您可以通过名称或标签呼叫任何代理。
pipeline {
agent {
label 'master'
}
}
如果它不适合你,那么你需要在主节点上设置任何标签并通过标签调用它
pipeline {
agent {
label 'master_label_here'
}
}
我认为你在要求不可能的事情。
现在:
你的 Jenkinsfile 在你的 jenkins 配置中,并被发送给你的每个代理。您的代理不需要 git
。
SCM 管道脚本:
由于您使用 git
,SCM = git
。所以你是说:我的管道需要从 git
存储库中获取。您在 agent { label agentLabel }
上将 Deploy
步骤声明为 运行,因此该步骤应该在除主代理之外的另一个代理上 运行。
您如何想象代理可以获取 Jenkinsfile 的内容来知道要做什么,但不使用 git
?
詹金斯会发生什么?
- 您的主代理被触发需要构建
- 主代理使用
git
检查 Jenkinsfile(因为它是来自 SCM 的 管道脚本)
- jenkins 读取 Jenkinsfile 并查看必须完成的操作。
- 对于 Prep 阶段,我不太确定没有代理会发生什么,我猜 运行s 在主代理上。
- Powershell 部署脚本检查 在主代理上被标记为 运行,所以它在主代理上 运行s(注意 Jenkinsfile 将得到用
git
签出两次:
- 在开始阶段之前,因为jenkins需要知道要执行什么
- 因为您指定
git url: 'https://github.com/owner/repo.git'...
,所以又结帐了一次
- Deploy 阶段在
agentLabel
上标记为 运行,因此 jenkins 会尝试在该代理上检出您的 Jenkinsfile(使用 git
)...
你可以使用Scripted Pipeline来做到这一点,它基本上应该是这样的
node('master') {
checkout scm
stash includes: 'deploy-script.ps1', name: 'deploy-script'
}
def stepsForParallel = [:]
env.AGENTS.split(' ').each { agent ->
stepsForParallel["deploy ${agent}"] = { ->
node(agent) {
unstash 'deploy-script'
}
}
parallel stepsForParallel
我认为 skipDefaultCheckout
是您要找的:
pipeline {
options {
skipDefaultCheckout true
}
stages {
stage('Prep') {
steps {
script {
........................
}
}
}
}
}
查看文档:
skipDefaultCheckout
在 agent 指令中默认跳过从源代码管理中检出代码。
我编写了一个接受多个参数的通用管道,以便将预定义 GitHub 存储库中的版本部署到特定节点。我想在 GitHub 上的 Jenkinsfile 上托管此管道,因此我将作业配置为使用“来自 SCM 的管道脚本”。事实是 - 当我尝试构建作业时 - Jenkinsfile 在每个节点上都被检出。是否可以按预期仅在主节点和 运行 管道上检出并执行 Jenkinsfile?
编辑:正如我之前所说,管道工作得很好,并且按照预期将作业设置为与管道脚本一起工作。 问题是,当我尝试将其更改为“来自 SCM 的管道脚本”时,Jenkinsfile 会在每个代理上得到检查,这是一个问题,因为我没有 git 安装在除 master 以外的任何代理上。我希望仅在主代理上检出 Jenkinsfile 并按预期执行。仅供参考,下面的管道:
def agents = "$AGENTS".toString()
def agentLabel = "${ println 'Agents: ' + agents; return agents; }"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
if (agents == null || agents == "") {
println "Skipping build"
skipBuild = true
}
if (!skipBuild) {
println "Agents set for this build: " + agents
}
}
}
}
stage('Powershell deploy script checkout') {
agent { label 'master' }
when {
expression {
!skipBuild
}
}
steps {
git url: 'https://github.com/owner/repo.git', credentialsId: 'git-credentials', branch: 'main'
stash includes: 'deploy-script.ps1', name: 'deploy-script'
}
}
stage('Deploy') {
agent { label agentLabel }
when {
expression {
!skipBuild
}
}
steps {
unstash 'deploy-script'
script {
println "Execute powershell deploy script on agents set for deploy"
}
}
}
}
}
您可以找到有关 jenkins 代理部分的所有信息 here。 很快:您可以通过名称或标签呼叫任何代理。
pipeline {
agent {
label 'master'
}
}
如果它不适合你,那么你需要在主节点上设置任何标签并通过标签调用它
pipeline {
agent {
label 'master_label_here'
}
}
我认为你在要求不可能的事情。
现在:
你的 Jenkinsfile 在你的 jenkins 配置中,并被发送给你的每个代理。您的代理不需要 git
。
SCM 管道脚本:
由于您使用 git
,SCM = git
。所以你是说:我的管道需要从 git
存储库中获取。您在 agent { label agentLabel }
上将 Deploy
步骤声明为 运行,因此该步骤应该在除主代理之外的另一个代理上 运行。
您如何想象代理可以获取 Jenkinsfile 的内容来知道要做什么,但不使用 git
?
詹金斯会发生什么?
- 您的主代理被触发需要构建
- 主代理使用
git
检查 Jenkinsfile(因为它是来自 SCM 的 管道脚本) - jenkins 读取 Jenkinsfile 并查看必须完成的操作。
- 对于 Prep 阶段,我不太确定没有代理会发生什么,我猜 运行s 在主代理上。
- Powershell 部署脚本检查 在主代理上被标记为 运行,所以它在主代理上 运行s(注意 Jenkinsfile 将得到用
git
签出两次:- 在开始阶段之前,因为jenkins需要知道要执行什么
- 因为您指定
git url: 'https://github.com/owner/repo.git'...
,所以又结帐了一次
- Deploy 阶段在
agentLabel
上标记为 运行,因此 jenkins 会尝试在该代理上检出您的 Jenkinsfile(使用git
)...
你可以使用Scripted Pipeline来做到这一点,它基本上应该是这样的
node('master') {
checkout scm
stash includes: 'deploy-script.ps1', name: 'deploy-script'
}
def stepsForParallel = [:]
env.AGENTS.split(' ').each { agent ->
stepsForParallel["deploy ${agent}"] = { ->
node(agent) {
unstash 'deploy-script'
}
}
parallel stepsForParallel
我认为 skipDefaultCheckout
是您要找的:
pipeline {
options {
skipDefaultCheckout true
}
stages {
stage('Prep') {
steps {
script {
........................
}
}
}
}
}
查看文档:
skipDefaultCheckout 在 agent 指令中默认跳过从源代码管理中检出代码。