问题描述
正在使用Jenkins流水线,并在测试阶段中使用并行步骤,如下所示:
pipeline {
agent { label 'php' }
stages {
stage('build') {
steps {
// 构建步骤内容
}
}
stage('test') {
parallel {
stage('unit tests') {
steps {
// 单元测试步骤内容
}
}
stage('integration tests') {
steps {
// 集成测试步骤内容
}
}
}
}
stage('deploy') {
steps {
// 部署步骤内容
}
}
}
}
目前,流水线在单一代理上运行正常。但现在,用户希望添加一个需要手动输入的步骤,并且这个步骤不应该保持代理运行。代理是云服务器,根据需求启动和停止。
为了实现这一点,用户将流水线分配给了”none”代理,并且在除了请求输入的步骤外的所有步骤中指定了实际的代理,如下所示:
pipeline {
agent none
stages {
stage('build') {
agent { label 'php' }
steps {
// 构建步骤内容
}
}
stage('test') {
parallel {
stage('unit tests') {
agent { label 'php' }
steps {
// 单元测试步骤内容
}
}
stage('integration tests') {
agent { label 'php' }
steps {
// 集成测试步骤内容
}
}
}
}
stage('deploy staging') {
agent { label 'php' }
steps {
// 部署到暂存环境的步骤内容
}
}
stage('confirm release') {
steps {
input { message '发布?' }
}
}
stage('deploy production') {
agent { label 'php' }
steps {
// 部署到生产环境的步骤内容
}
}
}
}
已经使用stash
和unstash
将后续阶段需要的文件进行传递。这个方法有效,但存在两个问题:
1. 在每个单独的阶段之间执行stash
和unstash
会造成开销。用户更希望在手动输入之前的所有阶段在单个工作空间中执行。但是,agent
只允许在包含步骤的阶段中使用。
2. 每个并行阶段占用一个代理。如果只有一个空闲代理,就不会进行并行执行,与之前不同。
用户可以接受(1)的情况,如果没有其他方式的话。但对于我来说,一个代理上的并行执行非常重要。在当前的设置中,是否有可能实现这一点?如果不行,有哪些类似的选项可以达到类似的效果?
解决方案
方案
为了在Jenkins声明性流水线中在同一代理上执行并行阶段,可以按照以下步骤操作。
- 首先,可以使用嵌套的
script
块来实现在并行阶段中的不同代理。 - 使用
node
来指定一个代理,然后在script
块中定义要在该代理上运行的步骤。
下面是调整后的流水线示例代码:
pipeline {
agent none
stages {
stage('build') {
agent { label 'php' }
steps {
echo "构建"
sh "ls -lrt && touch build.txt"
}
}
stage('test') {
parallel {
stage('unit tests') {
steps {
script {
node('php') {
echo "单元测试"
sh "ls -lrt && touch ut.txt"
sleep(time:10,unit:'SECONDS')
}
}
}
}
stage('integration tests') {
steps {
script {
node('php') {
echo "集成测试"
sh "ls -lrt && touch it.txt"
sleep(time:10,unit:'SECONDS')
}
}
}
}
}
}
stage('deploy staging') {
agent { label 'php' }
steps {
echo "部署到暂存环境"
sh "ls -lrt && touch dep.txt"
}
}
stage('confirm release') {
steps {
input message: '发布?'
}
}
stage('deploy production') {
agent { label 'php' }
steps {
echo "部署到生产环境"
sh "ls -lrt && touch produ.txt"
}
}
}
}
在上述示例中,我们使用了script
块,并在其中使用node('php')
来指定了特定的代理。这样,我们可以在并行阶段中使用不同的代理,并在各个代理上运行所需的步骤。
请注意,这个示例是经过测试的,并且在日志中也可以确认可以选择不同的代理。值得注意的是,这是一个声明性流水线。
正文完