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

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. 场景1:推送至develop分支 → 判断$CI_PIPELINE_SOURCE == "push"且$CI_COMMIT_BRANCH == "develop"
  2. 场景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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:10:15