git远程分支不会自动部署,必须通过ci/cd配置rules精准控制触发条件:区分mr(用$ci_pipeline_source和$ci_merge_request_target_branch_name)、push(用正则匹配$ci_commit_branch)及排除tag($ci_commit_tag != null),禁用已废弃的only/except,结合受保护环境确保部署安全。

分支触发是 Git 自动部署中最常用也最容易出错的环节——不是所有 push 都该跑完整流水线,也不是所有分支都适合自动部署到生产环境。关键在于规则写对、保护设严、动作可控。
rules 里用 $CI_COMMIT_BRANCH 判断分支时,别漏掉空值和特殊字符
很多团队在 rules 中直接写 if: $CI_COMMIT_BRANCH == "main",结果发现 PR 合并后没触发,或者 tag 推送意外触发了部署。这是因为:$CI_COMMIT_BRANCH 在合并请求(MR)场景下为空,GitLab 实际用的是 $CI_MERGE_REQUEST_TARGET_BRANCH_NAME;而打 tag 时它又可能不等于你预期的分支名。
- 判断 MR 场景:优先用
if: $CI_PIPELINE_SOURCE == "merge_request_event"+$CI_MERGE_REQUEST_TARGET_BRANCH_NAME - 判断普通 push:用
if: $CI_COMMIT_BRANCH =~ /^(main|release\/.*)$/,正则比==更安全 - 排除 tag 构建:加一条
- if: $CI_COMMIT_TAG != null when: never
only 和 except 已弃用,但老配置还在生效
GitLab 14.0+ 开始标记 only/except 为废弃,但它们仍能运行——只是逻辑更难预测,比如 except: - tags 不会阻止由 tag 触发的 pipeline(因为 tag 的 pipeline 类型是 tag,不是 push)。强行混用 only 和 rules 还会导致规则被忽略。
- 新项目一律用
rules,删掉所有only/except - 迁移旧配置时,用
gitlab-ci.yml的include拆分公共规则,避免重复写判断 - 测试规则是否生效:用
git push origin HEAD:refs/heads/feature/test手动推一个临时分支,看 pipeline 是否创建
受保护分支上自动部署必须绕过权限校验?不,应该用 protected environments
有人为让 main 分支的 deploy job 跑通,干脆把 main 分支设为“允许所有人推送”,或者在 job 里加 allow_failure: true ——这等于把安全门锁换成贴纸。真正该做的是启用 protected environments 并绑定 deployment job 的 environment。
- 在 GitLab 项目设置 → Settings → CI/CD → Protected environments 中,添加
production环境,并只允许特定角色(如 Maintainer)部署 - 在 job 中声明:
environment: production,GitLab 会自动校验权限,无需额外脚本或 token - 如果要用 API 或 runner 执行部署,应使用
deployment token,而非个人 access token
分支触发看着简单,但实际要同时处理 MR、push、tag、rebase、force-push 多种事件类型,且每种的 CI_* 变量值都不同。最稳妥的做法,是把每个 job 的触发条件单独验证,而不是靠“大概率能跑通”来上线。











