如何确保并行阶段使用前一阶段的工作区副本?跨平台流水线咨询
解决Jenkins并行构建复用检出代码的问题
嘿,这个问题我熟!你想让Jenkins流水线里的并行构建阶段都复用前面Checkout阶段拉下来的代码,对吧?刚好有几种实用的方法,我给你拆解清楚:
方法1:用Stash/Unstash(最常用的轻量方案)
这是Jenkins官方推荐的方式,适合代码量不大的项目,操作起来也简单:
- 先在
Checkout阶段完成代码拉取后,把整个工作区的内容“存起来”:
pipeline { agent none stages { stage('Checkout') { agent any steps { checkout([extensions: [[$class: 'CleanBeforeCheckout']], ...]]) // 把所有文件存入名为source-code的stash,includes指定要存的内容,**/*表示所有文件 stash name: 'source-code', includes: '**/*' } } stage('Build') { parallel { stage('win') { agent { label 'win' } steps { // 取出之前存好的代码到当前slave的工作区 unstash 'source-code' // 这里写你的Windows构建命令,比如msbuild、dotnet build之类的 } } stage('mac') { agent { label 'mac' } steps { unstash 'source-code' // macOS构建命令,比如xcodebuild } } stage('linux') { agent { label 'linux' } steps { unstash 'source-code' // Linux构建命令,比如make、gradle build } } } } } }
小提示:如果你的项目里有不需要的大文件(比如node_modules、build目录),可以在stash时用excludes参数排除它们,能提升速度哦。
方法2:共享工作区(适合大代码库)
如果你的代码体积很大,stash会比较慢,那可以试试用共享存储(比如NFS、SMB网络共享),让所有slave都能直接访问同一个代码目录:
- 在
Checkout阶段把代码拉到所有slave都能访问的共享目录里:
stage('Checkout') { agent any steps { // 这个路径是所有slave都能访问的共享目录,比如Windows下的\\server\shared\my-app,Linux下的/mnt/shared/my-app dir('/shared/workspace/my-app') { checkout([extensions: [[$class: 'CleanBeforeCheckout']], ...]]) } } }
- 然后每个并行构建阶段直接切换到这个共享目录执行构建:
stage('win') { agent { label 'win' } steps { // Windows slave要把共享目录映射成驱动器,比如Z:\my-app,或者直接用UNC路径 dir('Z:\\my-app') { // 执行Windows构建步骤 } } }
注意:要确保所有slave都有这个共享目录的读写权限,而且构建过程中不要修改代码(不然可能影响其他并行阶段)。
方法3:Copy Artifact插件(适合需要归档代码快照的场景)
如果需要长期保存每次构建的代码快照,那可以用Copy Artifact插件来实现:
- 先在
Checkout阶段把代码打包归档:
stage('Checkout') { agent any steps { checkout([extensions: [[$class: 'CleanBeforeCheckout']], ...]]) // 把当前目录打包成source-code.zip,不自动归档(后面手动归档) zip zipFile: 'source-code.zip', archive: false, dir: '.' } post { always { // 归档这个zip包,方便后续阶段复制 archiveArtifacts artifacts: 'source-code.zip', fingerprint: true } } }
- 然后在每个构建阶段复制这个zip并解压:
stage('win') { agent { label 'win' } steps { // 从当前任务的同一次构建中复制归档的zip包 copyArtifacts projectName: env.JOB_NAME, selector: specific(env.BUILD_NUMBER) // 解压到当前工作区 unzip zipFile: 'source-code.zip', dir: '.' // 执行构建步骤 } }
内容的提问来源于stack exchange,提问作者Nathan Osman
相关产品推荐
相关产品推荐

