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

GitLab CI无代码变更时突发流水线artifacts无法上传故障

故障背景

此前流水线运行一直正常,未对流水线代码做任何修改,当日运行时出现artifacts无法上传的问题。
作业脚本末尾通过cat命令验证s3url.txt文件确实存在且内容写入正常,但artifacts阶段始终无法完成该文件的上传,日志截图可佐证cat命令执行成功:
gitlab cat of s3url

涉及的build-rpm流水线作业配置
build-rpm:
  stage: build_preconfig
  image: ubuntu:latest
  rules:
    #- if: '$PACKAGE_URL && $PACKAGE_URL != ""'
    #  when: never
    - if: "$ACTION && $BUILDRPMREQUIRED" # 匹配条件时运行
    - when: never # 默认跳过
  variables:
    RPMVERSION: nightlye2e
  cache:
    key: apt-cache
    paths:
      - apt-cache/
  before_script:
    - *install_build_dependencies
    - *configure_aws_cli
  script:
    - ./build.py --version ${RPMVERSION} --all --profile default --dev
    - echo "RPM file generated for version $RPMVERSION "
    - mv ./dist/*.rpm ./dist/pipeline.rpm
    - aws s3 ls --profile $ACCOUNT_NAME
    - account_id=`aws sts get-caller-identity --profile $ACCOUNT_NAME --query "Account" --output text`
    - bucketstatus=$(aws s3api head-bucket --bucket "projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA}" --profile $ACCOUNT_NAME 2>&1) || true
    - echo $bucketstatus
    - |+
      #if [ $(aws s3 ls "s3://projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA}" --profile $ACCOUNT_NAME | grep 'NoSuchBucket' &> /dev/null) == 0 ]
      if echo "${bucketstatus}" | grep 'Not Found';
      then 
        echo "No old buckets"
      else
        echo "Removing old bucket: projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA}"
        aws s3 rm s3://projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA} --profile $ACCOUNT_NAME --recursive
        aws s3 rb --force s3://projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA} --profile $ACCOUNT_NAME
      fi
    - bucket=`aws s3api create-bucket --bucket projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA} --region ${REGION} --create-bucket-configuration LocationConstraint=${REGION} --acl private --profile ${ACCOUNT_NAME}`
    - bucketurl=$(echo $bucket | /usr/bin/jq --raw-output '.Location')
    - aws s3 cp ./dist/pipeline.rpm s3://projectn-rpm-${account_id}-${CI_COMMIT_SHORT_SHA}/ --acl public-read --profile $ACCOUNT_NAME
    - s3url="${bucketurl}pipeline.rpm"
    - echo $s3url > $CI_PROJECT_DIR/s3url.txt
    - cat $CI_PROJECT_DIR/s3url.txt
  artifacts:
    untracked: false
    paths:
      - "$CI_PROJECT_DIR/s3url.txt"
故障根因

该问题属于未修改业务配置突发故障的典型场景,核心原因是承载作业运行的GitLab Runner近期自动升级到16.0及以上版本:

  • 16.0之前版本的GitLab Runner对artifacts路径校验宽松,支持识别绝对路径,会自动将$CI_PROJECT_DIR开头的绝对路径映射到作业工作目录,因此之前运行无异常
  • 16.0及以上版本新增了artifacts路径安全校验规则,仅支持相对于作业工作目录(即$CI_PROJECT_DIR)的相对路径,直接配置绝对路径会被判定为非法路径,Runner无法定位到待上传文件,最终导致上传失败。

基础镜像ubuntu:latest滚动升级带来环境差异的可能性极低,从cat命令能正常读取文件的现象来看,该原因可以基本排除。

排查步骤
  • 查看artifacts上传阶段的完整Runner日志,会明确报出path not found或invalid artifact path类的错误,可直接定位路径问题
  • 在脚本末尾追加pwd && ls -la s3url.txt执行,确认文件存在于当前工作目录、且对Runner运行用户可读
  • 对比作业运行成功历史记录对应的Runner版本,确认故障前后Runner是否存在版本升级行为
修复方案

直接修改artifacts配置段,将绝对路径替换为相对路径即可,Runner默认会从作业工作目录开始查找待上传的artifact文件:

artifacts:
    untracked: false
    when: always # 可选配置,确保哪怕脚本执行异常也会尝试上传已有产物,方便排查问题
    paths:
      - "s3url.txt"

可选优化:将脚本中写文件的命令也改为相对路径写法,避免不同环境下的路径解析差异,把echo $s3url > $CI_PROJECT_DIR/s3url.txt替换为echo $s3url > s3url.txt即可,脚本执行时的当前目录默认就是$CI_PROJECT_DIR,不需要额外拼接绝对路径前缀。

内容的提问来源于stack exchange,提问作者Jor-El

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:24:20