You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

原因分析

  1. Runner工作目录未自动清理:GitLab Runner默认不会在作业间清理工作目录,如果release作业和package作业跑在同一个Runner的同一个工作目录下,上一个作业的所有文件(包括仓库代码、缓存、target目录)都会被保留。
  2. cache: []的局限性:该配置仅禁用作业级的缓存加载,但如果Runner本身配置了共享缓存(比如宿主机挂载的缓存目录),之前的.m2缓存仍会残留。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:05:46