如何在Jenkins声明式流水线重启指定阶段时保留工作空间避免构建失败
解决Jenkins声明式流水线重启阶段时工作空间丢失依赖仓库的问题
我之前也碰到过一模一样的问题,核心原因其实有两个:
- 用「Pipeline script from SCM」加载Jenkinsfile时,Jenkins会自动执行一次默认的checkout操作拉取Jenkinsfile所在的
automation.git仓库,这个操作优先级高于你流水线里定义的所有步骤,重启阶段时它会清空工作空间并只拉取automation,直接把之前拉好的devops和harness仓库覆盖掉了。 - 虽然重启时会跳过开头的
cleanWs()阶段,但Jenkins的默认checkout已经先一步把工作空间清空了,导致后续阶段找不到依赖的仓库。
下面是针对性的解决方案,修改后的Jenkinsfile可以完美解决这个问题:
pipeline { agent { label 'worker' } options { // 禁用Jenkins默认的自动拉取Jenkinsfile仓库的行为,完全由自定义checkout步骤控制 skipDefaultCheckout() } stages { stage('clean directory') { // 仅在流水线首次运行时执行清理,重启阶段直接跳过 when { not { currentBuild.isRestarted() } } steps { cleanWs() } } stage('checkout') { // 仅当依赖仓库缺失,或者流水线是首次运行时才执行完整checkout when { expression { !fileExists('devops/.git') || !fileExists('harness/.git') || !fileExists('automation/.git') || !currentBuild.isRestarted() } } steps { checkout([$class: 'GitSCM', branches: [[name: 'develop']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'devops'], [$class: 'LocalBranch', localBranch: "**"]], userRemoteConfigs: [[credentialsId: 'xxxxxx', url: 'git@github.com/test/devops.git']]]) checkout([$class: 'GitSCM', branches: [[name: 'develop']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'harness'], [$class: 'LocalBranch', localBranch: "**"]], userRemoteConfigs: [[credentialsId: 'xxxxxx', url: 'git@github.com/test/harness.git']]]) checkout([$class: 'GitSCM', branches: [[name: 'develop']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'automation'], [$class: 'LocalBranch', localBranch: "**"]], userRemoteConfigs: [[credentialsId: 'xxxxxx', url: 'git@github.com/test/automation.git']]]) } } stage('build initial commit to release train') { steps { sh '''#!/bin/bash export TASK="build_initial_commit" cd automation sh main.sh ''' } } stage('deploy application') { steps { sh '''#!/bin/bash export TASK="deploy" cd automation sh main.sh ''' } } } }
关键修改点说明:
添加
skipDefaultCheckout()选项:
彻底阻止Jenkins自动拉取automation.git的默认行为,所有仓库的拉取完全由我们自定义的checkout步骤控制,从根源上避免重启时被默认操作清空工作空间。给清理阶段加执行条件:
通过currentBuild.isRestarted()判断流水线状态,只有首次运行时才清理工作空间,重启阶段直接跳过,保留之前拉好的所有仓库内容。给checkout阶段加执行条件:
检查三个仓库的.git目录是否存在,同时判断是否是重启状态。如果是重启且所有仓库都存在,就跳过checkout步骤;如果是首次运行或者某个仓库缺失,则执行完整拉取,保证依赖仓库的完整性。
如果你担心重启时仓库代码不是最新版本,可以把checkout步骤改成脚本化的拉取+更新逻辑,比如:
sh ''' # 处理devops仓库 if [ ! -d "devops/.git" ]; then git clone git@github.com/test/devops.git -b develop devops else cd devops && git pull origin develop fi # 处理harness仓库 if [ ! -d "harness/.git" ]; then git clone git@github.com/test/harness.git -b develop harness else cd harness && git pull origin develop fi # 处理automation仓库 if [ ! -d "automation/.git" ]; then git clone git@github.com/test/automation.git -b develop automation else cd automation && git pull origin develop fi '''
这样既保证重启时仓库内容存在,又能同步到最新代码,不过要确保Jenkins agent已经配置好对应的git权限。
内容的提问来源于stack exchange,提问作者Baitanik
相关产品推荐
相关产品推荐

