GitLab CI无代码变更时突发流水线artifacts无法上传故障
故障背景
此前流水线运行一直正常,未对流水线代码做任何修改,当日运行时出现artifacts无法上传的问题。
作业脚本末尾通过cat命令验证s3url.txt文件确实存在且内容写入正常,但artifacts阶段始终无法完成该文件的上传,日志截图可佐证cat命令执行成功:
涉及的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
相关产品推荐
相关产品推荐

