laravel项目需通过git分支策略与环境映射实现多环境精准部署:main触发生产、release/**触发预发布、develop用于开发测试;配合分支保护、规范命名(feat/、hotfix/、release/)、ci注入环境变量及强制清理未合入分支,确保代码流安全可控。

让Laravel项目在不同环境走对代码分支,避免开发改完直接推到生产、测试用着未合入的feature、上线后发现main里混着调试代码——关键不是多建几个分支,而是让每个分支有明确归属和自动响应机制。
配置Git分支策略与环境映射
生产环境只响应【main】分支推送,预发布环境监听release/*分支,开发测试走develop分支。GitHub Actions会按分支名自动分流任务,写错分支名会导致部署被跳过。
在仓库根目录创建.github/workflows/deploy.yml文件,开头明确声明触发规则:
on:
push:
branches:
- main
- 'release/**'
- develop
注意:release/后必须加两个星号(**),否则release/v1.2.0这种带点号的分支不会被匹配。单个*只匹配一级,比如release/123能命中,但release/v1.2.0不行。
分支权限与保护规则设置
进入GitHub仓库 Settings → Branches → Branch protection rules → Create rule。
方法一:保护main分支
填写Branch name pattern为main → 勾选Require pull request reviews before merging → Require status checks to pass before merging → 在Status checks中勾选CI流程名称(如laravel-ci)→ 启用Include administrators。
方法二:限制直接推送
对develop分支启用Require linear history和Restrict who can push to matching branches,只允许CI机器人账号(如github-actions[bot])或指定团队成员推送。普通开发者必须通过PR合入,防止本地误操作污染主干。
本地开发分支命名规范
第一步:所有功能开发从develop拉出独立分支
git checkout -b feat/user-profile-update develop
第二步:修复紧急线上问题时,必须从main拉hotfix分支
git checkout -b hotfix/login-500-error main
第三步:准备发版前,在develop稳定后切出release分支
git checkout -b release/v2.1.0 develop
这三类前缀(feat/、hotfix/、release/)不是可选项,是CI脚本识别部署目标环境的硬编码依据。比如release/v2.1.0推送到远程,就会触发预发布环境的完整构建+数据库迁移+Smoke测试;而feat/分支仅运行单元测试和PHPStan,不连接真实数据库。
分支合并后立即删除远程分支。GitHub PR关闭时勾选Delete head branch,避免分支列表堆积失效分支干扰判断。
区分环境变量注入路径
方法一:main分支部署时读取GitHub Secrets中的PROD_*前缀密钥
在workflow中写:
DB_DATABASE: ${{ secrets.PROD_DB_DATABASE }}
REDIS_PASSWORD: ${{ secrets.PROD_REDIS_PASSWORD }}
方法二:release/*分支使用STAGING_*前缀
同一份workflow文件内,用if条件切换:
env:
DB_DATABASE: ${{ github.head_ref == 'main' && secrets.PROD_DB_DATABASE || secrets.STAGING_DB_DATABASE }}
APP_ENV: ${{ github.head_ref == 'main' && 'production' || 'staging' }}
注意:不要在.env文件里硬写APP_ENV=staging然后提交进Git——这会导致本地开发也变成staging行为,缓存、日志路径全错。环境标识必须由CI注入,.env只保留占位符如DB_DATABASE=not-set。
强制执行分支清理检查
在CI流程末尾添加一步验证脚本:
- name: Verify no unmerged feat branches remain
run: |
git fetch --prune origin
if git branch -r --format='%(refname:short)' | grep -q 'origin/feat/'; then
echo "ERROR: Found unmerged feat/* branches on remote"; exit 1;
fi
这一步放在所有部署动作之后、通知发送之前。它不阻断上线,但会让CI失败并报错,逼迫团队在发版前清理掉悬空的功能分支,避免后续误合入或遗忘。











