GitLab CI流水线规则未识别执行期变量的问题排查
GitLab CI 执行期检查APP_VERSION及动态设置变量的正确方式
核心问题原因
GitLab CI 的 rules 是在流水线初始化阶段(触发流水线后、作业开始执行前)完成评估的,一旦流水线启动,rules 中定义的变量值就会固定,不会在作业执行阶段根据实时的 APP_VERSION 重新计算。这就是你看到即使 APP_VERSION 是 1.0.0-SNAPSHOT,IS_SNAPSHOT 和 DOCKER_REPOSITORY 仍保持初始值的原因。
正确解决方案
要在执行期动态检查 APP_VERSION 并传递正确的变量,需要将变量计算逻辑移到作业的 script 或 before_script 中,再通过 GitLab 的 dotenv 报告机制将变量传递给后续作业。
1. 定义全局默认变量(可选)
先在流水线顶部设置环境和版本的默认值,支持手动触发时覆盖:
variables: DEPLOY_ENV: "DEV" # 默认部署环境 APP_VERSION: "1.0.0-SNAPSHOT" # 默认版本
2. 编写验证作业(执行期检查版本)
在验证作业中直接检查 APP_VERSION 是否包含 SNAPSHOT,同时根据部署环境做校验,并将计算后的变量写入 dotenv 文件传递给后续作业:
validate_version: stage: validate script: # 判断是否为SNAPSHOT版本,同时校验生产环境禁止SNAPSHOT - | if [[ "$APP_VERSION" == *SNAPSHOT* ]]; then echo "IS_SNAPSHOT=true" >> variables.env if [[ "$DEPLOY_ENV" == "PROD" ]]; then echo "ERROR: SNAPSHOT版本不允许部署到生产环境" exit 1 fi else echo "IS_SNAPSHOT=false" >> variables.env fi # 根据环境设置对应的Docker仓库 - | case "$DEPLOY_ENV" in DEV) echo "DOCKER_REPOSITORY=dev-docker-repo" >> variables.env ;; PREPROD) echo "DOCKER_REPOSITORY=preprod-docker-repo" >> variables.env ;; PROD) echo "DOCKER_REPOSITORY=prod-docker-repo" >> variables.env ;; *) echo "ERROR: 不支持的部署环境 $DEPLOY_ENV" exit 1 ;; esac artifacts: reports: dotenv: variables.env # 将变量传递给后续依赖此作业的任务
3. 后续作业使用动态变量
在 Debug 或构建/部署作业中,通过 needs 依赖验证作业,即可获取到执行期计算的变量:
debug_vars: stage: debug needs: [validate_version] # 依赖验证作业,确保拿到最新变量 script: - echo "当前版本是否为SNAPSHOT: $IS_SNAPSHOT" - echo "Docker仓库地址: $DOCKER_REPOSITORY" - echo "当前应用版本: $APP_VERSION" build_image: stage: build needs: [validate_version] script: - docker build -t $DOCKER_REPOSITORY/app:$APP_VERSION . - docker push $DOCKER_REPOSITORY/app:$APP_VERSION
关键注意事项
- 手动触发流水线时,输入的
APP_VERSION和DEPLOY_ENV会直接覆盖默认值,验证作业的script能正确读取到这些实时输入的值。 - 若不需要传递变量给后续作业,仅需在当前作业中做校验,可直接在
script中完成判断,无需生成dotenv文件。
内容的提问来源于stack exchange,提问作者Atatorus
相关产品推荐
相关产品推荐

