如何在Jenkins中将Git子模块签出到自定义公共目录?
问题
我的项目在GitLab上包含3个子模块,构建时需要全部用到。我想在Jenkins中为每个子模块创建独立流水线,用来监听各自的合并请求并拉取代码。但默认情况下,Jenkins会以流水线项目名称创建工作区文件夹,比如jenkins_home/workspace/submodule1、jenkins_home/workspace/submodule2、jenkins_home/workspace/submodule3。我希望把所有子模块都签出到同一个jenkins_home/workspace/common_folder目录下,最终让这个目录包含submodule1、submodule2、submodule3这三个子目录。
补充:我试过用bat 'cd common_folder',但这个cd命令一直挂起无法执行;也尝试过用dir (**subdir**){},但它只会在子模块自己的流水线目录里创建新目录,比如jenkins_home/workspace/submodule1/**subdir**/code_from_git,达不到我要的效果。
解决方案
要实现将子模块签出到指定的公共目录,核心是使用Jenkins GitSCM插件的RelativeTargetDirectory扩展,直接指定代码的签出路径。以下是修改后的Jenkinsfile:
#!/usr/bin/env groovy pipeline { agent { label 'master' } environment { gbuild = 'true' DB_ENGINE = 'sqlite' // 每个子模块流水线需修改此值,对应自己的子模块名称 SUBMODULE_NAME = 'submodule1' // 公共目录的绝对路径 COMMON_DIR = "${JENKINS_HOME}/workspace/common_folder" } options{ skipDefaultCheckout() } stages { stage('Checkout') { steps { script { // 提前创建目标目录,已存在则不报错 bat "mkdir \"${COMMON_DIR}\\${SUBMODULE_NAME}\" || exit 0" checkout([ $class: 'GitSCM', branches: scm.branches, extensions: scm.extensions + [ [$class: 'GitLFSPull'], [$class: 'CleanCheckout'], // 指定代码签出到公共目录下的对应子模块文件夹 [$class: 'RelativeTargetDirectory', relativeTargetDir: "${COMMON_DIR}/${SUBMODULE_NAME}"] ], userRemoteConfigs: scm.userRemoteConfigs ]) } } } } }
关键说明
- 目录预创建:通过
bat "mkdir ..."提前生成目标目录,避免Git签出时因目录不存在抛出错误;|| exit 0保证目录已存在时步骤不会失败。 - 指定签出路径:添加
RelativeTargetDirectory扩展,直接传入公共目录下的子模块绝对路径,让Git将代码签出到指定位置,而非流水线默认工作区。 - 流水线适配:每个子模块的流水线需要修改
SUBMODULE_NAME变量为对应的子模块名称(如submodule2、submodule3),确保各自的代码签出到common_folder下的对应子目录。
之前尝试的问题说明
bat 'cd common_folder'挂起是因为Jenkins的bat步骤在独立命令行会话中执行,cd仅影响当前会话,无法改变后续步骤的工作目录,且无后续命令时会进入交互状态导致挂起。dir (**subdir**){}是在当前流水线的默认工作区内创建子目录,无法突破流水线专属工作区的限制,自然无法实现跨流水线的公共目录共享。
内容的提问来源于stack exchange,提问作者Ruslan Sinyavsky
相关产品推荐
相关产品推荐

