GitLab流水线release作业目录冗余及多Jar文件问题咨询
GitLab CI release作业目录冗余导致版本冲突问题排查与解决
问题描述
我配置了一套GitLab流水线,包含package和release两个核心阶段:
- package阶段:仅在tag触发时执行Maven构建,依赖
.m2缓存完成mvn clean package,只归档生成的Jar包和测试报告; - release阶段:要求以完全干净的环境启动,不执行Git克隆、不加载任何缓存,仅拉取package阶段产出的Artifacts。
但实际执行find .后发现release作业目录存在大量冗余内容:
.git目录- 完整的仓库检出文件
.m2缓存目录- package阶段构建留下的
target目录
这直接导致release作业偶尔会因为检测到历史版本的Jar包而执行失败。我已经尝试了cache: []禁用缓存、dependencies指定依赖作业,但问题仍然存在。
附当前.gitlab-ci.yml配置:
variables: MAVEN_CLI_OPTS: "-s $CI_PROJECT_DIR/.m2/settings.xml" MAVEN_VERSION_PLUGIN_VERSION: 2.11.0 MAVEN_ARTIFACT_NAME: test-component GIT_CLEAN_FLAGS: -ffd PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${MAVEN_ARTIFACT_NAME}" cache: key: primary paths: - .m2/repository stages: - package - release package: stage: package image: maven:latest script: - mvn ${MAVEN_CLI_OPTS} clean package artifacts: paths: - target/*.jar - target/surefire-reports only: - tags - merge_requests - branches except: - main release: stage: release image: alpine:latest cache: [] variables: GIT_STRATEGY: none dependencies: - package script: - | apk add curl gitlab-release-cli find . JAR_NAME=`basename target/${MAVEN_ARTIFACT_NAME}-${CI_COMMIT_TAG}.jar` curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file target/${JAR_NAME} ${PACKAGE_REGISTRY_URL}/${CI_COMMIT_TAG}/${JAR_NAME} release-cli create --name "Release $CI_COMMIT_TAG" --description "$TAG_MESSAGE" --tag-name ${CI_COMMIT_TAG} --assets-link "{\"name\":\"jar\",\"url\":\"${PACKAGE_REGISTRY_URL}/${CI_COMMIT_TAG}/${JAR_NAME}\"}" only: - tags
原因分析
- Runner工作目录未自动清理:GitLab Runner默认不会在作业间清理工作目录,如果release作业和package作业跑在同一个Runner的同一个工作目录下,上一个作业的所有文件(包括仓库代码、缓存、target目录)都会被保留。
cache: []的局限性:该配置仅禁用作业级的缓存加载,但如果Runner本身配置了共享缓存(比如宿主机挂载的缓存目录),之前的.m2缓存仍会残留。dependencies的行为特性:dependencies仅控制Artifacts的拉取,但不会阻止Runner继承全局缓存或保留历史工作目录内容。
解决办法
1. 强制清理工作目录(快速生效)
在release作业中添加before_script,手动清空当前目录的所有内容,确保环境干净:
release: # 原有配置不变 before_script: - rm -rf ./* ./.git ./.m2 # 删除所有可见文件和隐藏目录
2. 配置Runner自动清理(长期方案)
修改GitLab Runner的config.toml配置文件,开启作业前自动清理:
[[runners]] name = "你的Runner名称" url = "你的GitLab实例地址" token = "Runner令牌" executor = "docker" [runners.docker] image = "alpine:latest" cleanup = true # 开启作业执行前的工作目录清理
修改后重启Runner服务即可生效。
3. 用needs替代dependencies(推荐)
needs是GitLab CI更严格的依赖控制方式,它会确保作业仅拉取指定依赖的Artifacts,且不会继承全局缓存或历史工作目录内容:
release: # 替换原有的dependencies配置 needs: - job: package artifacts: true # 其他配置不变
4. 优化Artifacts归档路径
修改package作业的Artifacts配置,将文件归档到独立前缀目录,避免和残留文件冲突:
package: artifacts: name: "${CI_COMMIT_TAG}-build-artifacts" paths: - build-output/target/*.jar - build-output/target/surefire-reports script: - mvn ${MAVEN_CLI_OPTS} clean package - mkdir -p build-output && cp -r target build-output/ # 复制到独立目录归档
同时更新release作业中的脚本路径:
release: script: - | apk add curl gitlab-release-cli JAR_NAME=`basename build-output/target/${MAVEN_ARTIFACT_NAME}-${CI_COMMIT_TAG}.jar` curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file build-output/target/${JAR_NAME} ${PACKAGE_REGISTRY_URL}/${CI_COMMIT_TAG}/${JAR_NAME} # 后续release-cli命令同理修改路径
额外注意事项
- 确认
GIT_STRATEGY: none配置在release作业的variables下,避免拼写错误; - 如果使用Docker executor,确保Runner没有启用共享宿主机目录作为缓存;
- 检查package作业的
mvn clean package是否真正清理了target目录,避免归档冗余文件。
内容的提问来源于stack exchange,提问作者Stephen Paulin
相关产品推荐
相关产品推荐

