git分支名直接决定部署目标环境的关键是ci/cd流水线读取ci_commit_ref_name等变量做条件判断,通过glob匹配(如feature/*)实现动态路由,配合路径隔离、权限控制与环境变量注入,确保多环境安全隔离。

怎么让 Git 分支名直接决定部署目标环境
关键不是“监听分支”,而是用 CI/CD 流水线读取 GIT_BRANCH 或 CI_COMMIT_REF_NAME(GitLab)/GITHUB_HEAD_REF(GitHub Actions),再做条件判断。硬编码分支名映射是常见做法,但容易漏维护;更稳妥的是用 glob 匹配,比如 feature/*、release/*。
示例(GitHub Actions):
if: ${{ startsWith(github.head_ref, 'feature/') }}
run: npm run build && rsync -av ./dist/ user@test-server:/var/www/test/${{ github.head_ref }}/
注意:github.head_ref 在 PR 场景下才是源分支名,push 事件才稳定对应真实分支名;PR 合并前测试应走 pull_request 触发器,而非 push。
- GitLab Runner 中优先用
CI_COMMIT_REF_SLUG(安全的分支名转义值),避免空格或特殊字符导致路径错误 - 不要在脚本里写死
master→ 生产,而应查环境变量或配置文件,便于后期切换策略 - 匹配失败时必须有 fallback 行为(如退出 + 报错),否则可能误部署到默认目录
为什么 feature/* 分支部署后访问路径要带子路径
不带子路径(比如全打到 /)会导致多个功能分支互相覆盖——这是最常被忽略的线上事故来源。每个 feature/xxx 必须隔离部署路径,否则 A 分支覆盖了 B 分支的静态资源,测试就失真了。
典型路径规则:
-
feature/login→https://test.example.com/feature/login/ -
release/v2.3→https://test.example.com/release/v2.3/ -
develop→https://test.example.com/develop/
实现上,构建时需传入 --base-url=/feature/login/(Vue CLI)、homepage 字段(Create React App),或通过 Nginx location 做反向代理。静态资源里的相对路径会因此生效,否则 JS/CSS 加载 404。
如何防止测试分支误推送到生产服务器
最直接的防护是部署脚本开头加校验:
if [[ "$CI_COMMIT_REF_NAME" == "master" || "$CI_COMMIT_REF_NAME" == "main" ]]; then TARGET_HOST="prod-server" else TARGET_HOST="test-server" fi
但仅靠分支名不够——有人可能本地 checkout master 后改代码再 push。所以必须叠加权限控制:
- Git 服务端设置保护分支:master/main 仅允许特定角色 merge,禁止直接 push
- CI/CD 配置中,生产部署 job 显式 require
workflow_dispatch手动触发,禁用自动 push 触发 - SSH 部署用户只对
/var/www/prod有写权限,对/var/www/test只读;测试机用户则相反
别依赖“人不会犯错”,要靠机制堵住漏洞。
本地开发时怎么模拟分支自动部署逻辑
不用真连 CI,用 shell 脚本快速验证分支路由逻辑:
#!/bin/bash BRANCH=$(git rev-parse --abbrev-ref HEAD) case $BRANCH in master|main) echo "→ production";; develop) echo "→ staging";; feature/*) echo "→ test/$(basename $BRANCH)";; release/*) echo "→ staging/$(basename $BRANCH)";; *) echo "⚠ unknown branch: $BRANCH"; exit 1;; esac
运行 ./deploy-check.sh 就能立刻看到当前分支该去哪——这个脚本可放进项目根目录,和 CI 配置保持逻辑一致,避免两边 diverge。
真正复杂的地方不在分支识别,而在环境配置的隔离:同一份代码,.env.development 和 .env.production 的变量不能混用,构建产物里的 API 地址、开关标识必须随分支动态注入。这点稍不注意,测试环境调用的还是生产接口。











