GitLab CI配置:仅在develop推送或main打标签时执行构建推送任务
GitLab CI 配置方案:仅在指定场景构建推送Docker镜像
核心问题说明
你之前的问题出在执行顺序:GitLab CI会先评估所有job的rules(决定是否执行该job),之后才会运行before_script。所以before_script里定义的变量在rules评估阶段根本不存在,导致任务被跳过。另外标签流水线中CI_COMMIT_BRANCH确实不可用,需要用预定义变量和额外命令来判断场景。
正确配置思路
针对你的两个触发场景,直接用GitLab预定义变量在rules中做判断,镜像标签的逻辑放在job的before_script中(此时预定义变量已可用):
- 场景1:推送至
develop分支 → 判断$CI_PIPELINE_SOURCE == "push"且$CI_COMMIT_BRANCH == "develop" - 场景2:在
main分支上创建标签 → 判断$CI_COMMIT_TAG存在,再通过git命令验证标签是否基于main分支(可选但更严谨)
完整配置示例
# 全局变量:替换为你的镜像仓库和镜像名 variables: IMAGE_NAME: "your-registry-domain/your-project-image" stages: - build - deploy build_image: stage: build before_script: - | # 根据场景设置镜像标签 if [ -n "$CI_COMMIT_TAG" ]; then # 标签场景:用标签名作为镜像标签 export IMAGE_TAG="$CI_COMMIT_TAG" # 可选:验证标签是否基于main分支,非main分支的标签直接终止任务 git fetch origin main git branch --contains "$CI_COMMIT_TAG" | grep -q main || { echo "标签未基于main分支,终止构建"; exit 1; } else # develop分支推送场景:用分支名作为镜像标签(也可以用CI_COMMIT_SHORT_SHA) export IMAGE_TAG="$CI_COMMIT_BRANCH" fi # 登录你的Docker仓库(如果是GitLab内置仓库,用CI_REGISTRY相关变量) - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" script: - docker build -t "$IMAGE_NAME:$IMAGE_TAG" . rules: # 触发场景1:develop分支推送 - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' when: always # 触发场景2:存在标签(后续在before_script验证是否基于main) - if: '$CI_COMMIT_TAG != null' when: always push_image: stage: deploy needs: [build_image] # 依赖build_image任务完成 before_script: - | if [ -n "$CI_COMMIT_TAG" ]; then export IMAGE_TAG="$CI_COMMIT_TAG" else export IMAGE_TAG="$CI_COMMIT_BRANCH" fi - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" script: - docker push "$IMAGE_NAME:$IMAGE_TAG" rules: - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' when: always - if: '$CI_COMMIT_TAG != null' when: always
关键细节说明
rules直接使用GitLab预定义变量判断,确保job只在指定场景触发- 标签场景中,通过
git branch --contains "$CI_COMMIT_TAG"验证标签是否基于main分支,避免非main分支的标签触发构建 - 镜像标签的逻辑放在job的
before_script中,此时预定义变量(如CI_COMMIT_TAG、CI_COMMIT_BRANCH)已可正常读取 needs关键字确保push_image只在build_image成功后执行
内容的提问来源于stack exchange,提问作者Misiu
相关产品推荐
相关产品推荐

