如何配置GitLab CI阶段仅在文件变更或上一次运行失败时执行
解决方案
核心逻辑说明
问题本质源于两点:一是构建失败时没有自动清理不完整的镜像资源,二是默认only:changes规则仅判断当前提交的文件变更,不感知上一次同作业的执行结果,导致失败后提交无相关变更时直接跳过该阶段。
完整调整配置
# 全局缓存定义:仅存储构建成功标记,几乎不占用存储空间 cache: key: ${CI_COMMIT_BRANCH}_buildroot_status paths: - .buildroot_build_success policy: pull-push create_buildroot_image: stage: createBuildrootImage script: - *do_docker_login - docker build -t $BUILD_ROOT_TAG1 -t $BUILD_ROOT_TAG2 build_root - docker push $BUILD_ROOT_TAG1 - docker push $BUILD_ROOT_TAG2 # 构建全流程成功后写入标记文件 - touch .buildroot_build_success # 注意:原配置中的 exit 1 为测试失败逻辑,正式使用请删除该行 after_script: # 作业失败时自动清理残留资源 - | if [ "$CI_JOB_STATUS" == "failed" ]; then # 清理本地不完整镜像 docker rmi -f $BUILD_ROOT_TAG1 $BUILD_ROOT_TAG2 || true # 如需清理已推送到远端的不完整镜像,可在此处添加对应镜像仓库的删除命令,需提前配置CI账号的镜像删除权限 rm -f .buildroot_build_success fi rules: # 规则1:Docker相关文件有变更时,强制执行构建 - if: $CI_COMMIT_BRANCH changes: - Dockerfile - build_root/* when: always # 规则2:无文件变更但上一次构建失败(无成功标记)时,强制执行构建 - if: $CI_COMMIT_BRANCH exists: - .buildroot_build_success when: never - when: always tags: - docker
配置说明
- 缓存仅存储体积可忽略的成功标记文件,缓存key绑定分支维度,不同分支的构建状态互不干扰
CI_JOB_STATUS为GitLab CI内置变量,会自动返回当前作业的执行状态,after_script钩子无论作业成功失败都会执行,确保失败后残留资源被清理- 规则优先级从上到下匹配:优先响应文件变更触发构建,无变更时判断是否存在上一次的成功标记,无标记则强制重跑,避免失败后持续跳过的问题
内容的提问来源于stack exchange,提问作者Attis
相关产品推荐
相关产品推荐

