第 4 章:代码仓库管理:GitHub、GitLab、Bitbucket 配置与权限归纳总结
说起代码仓库管理,我这些年接触过的项目几乎把这三大平台都轮了一遍。GitHub 上做开源项目最顺手,企业内部用 GitLab 自托管更可控,Bitbucket 跟 Atlassian 全家桶绑得紧。但说实话,很多团队把仓库权限配得一团乱——要么给所有人写权限,要么分支保护设得太死导致 CI 没法推。这一章我们就来把它们彻底捋清楚。
一句话总结:权限模型决定了“谁能读到代码”,保护分支决定了“谁能改主线”,Webhook 决定了“谁触发 CI”。先把这三种机制搞明白,仓库管理就稳了。
4.1 三大平台的权限模型对比
先看一个最直观的对比表,这是我做跨平台迁移时整理的。
| 维度 | GitHub | GitLab | Bitbucket |
|---|---|---|---|
| 权限层级 | Owner → Admin → Write → Read | Owner → Maintainer → Developer → Reporter → Guest | Admin → Write → Read |
| 组织/组管理 | Organization + Team | Group + Subgroup | Workspace + Project |
| 分支保护 | 需规则+状态检查+审批 | 内置 MR 审批规则 | 需配合 Branches 设置 |
| CI 触发方式 | Push / PR / Tag / Schedule | Push / MR / Tag / Schedule / Webhook | Push / PR / Tag / Schedule |
| Webhook 限制 | 最多 20 个(免费版) | 无数量限制(自托管) | 最多 50 个(标准版) |
我个人习惯是:团队小于 10 人用 GitHub 的 Read/Write 两档就够了;超过 20 人一定要上 GitLab 的 Maintainer/Developer 分层——Developer 不能改 CI 配置,这个细节能避免很多“谁手滑改了 pipeline 脚本”的惨案。
小技巧:在 GitLab 里把默认分支的 Merge Request 权限设为“仅 Maintainer 可合并”,Developer 只能创建 MR 不能点 Merge。我在一个金融项目中靠这个规则挡住了三次不合规格的代码上线。
4.2 SSH 密钥配置与最佳实践
SSH 密钥是 CI 与仓库交互的基础。很多新手把同一个私钥丢在多台机器上,一旦泄露就得逐个撤销。我建议每台 CI 节点生成独立的密钥对。
# 生成专用部署密钥(不设密码)
ssh-keygen -t ed25519 -C "ci@mycompany.com" -f ~/.ssh/ci_deploy_key -N ""
# 获取公钥
cat ~/.ssh/ci_deploy_key.pub
三个平台的密钥存放位置:
- GitHub: 仓库 Settings → Deploy keys(只读/读写);或者个人 Settings → SSH and GPG keys(用于用户身份)
- GitLab: 仓库 Settings → Repository → Deploy keys;或者用户 Preferences → SSH Keys
- Bitbucket: 仓库 Settings → Access keys;或者个人头像 → Personal settings → SSH keys
警告:部署密钥如果设成读写权限,它就可以推送代码。我曾经因此踩过坑——CI 用的部署密钥误配了写权限,导致一个 Job 意外覆盖了 master 分支。现在我的原则是:只给 CI 部署密钥读权限,写操作一律用个人令牌+专属 CI 账户。
4.3 Branch Protection 规则配置
保护分支是 CI 管线的最后一道门。我见过一个反面案例:有人把 master 的保护关了,然后 CI 直接往 master 推 tag,结果 tag 打错了版本,回滚花了两个通宵。
推荐的最小保护规则:
- 禁止直接推送(Require pull request before merging)
- 要求状态检查通过(Require status checks to pass)——把 CI 的关键 Job 加进去
- 要求最新代码(Require branches to be up-to-date)
- 限制谁可以 push(Restrict who can push to matching branches)
拿 GitHub 举例,一个完整的保护规则配置分支如下:
Settings → Branches → Add rule
Branch name pattern: main
☑ Require pull request reviews before merging
Required approving reviews: 2
☑ Dismiss stale pull request approvals when new commits are pushed
☑ Require status checks to pass
Status checks: CI / build, CI / test, CI / lint
☑ Require branches to be up to date before merging
☑ Include administrators
在 GitLab 里,保护规则集成在 Merge Request 的审批流程中。我记得有一次配置 GitLab CE 版本时发现它没有“要求最新代码”选项——需要用 CI 脚本手动检查。这一点自托管用户要注意。
4.4 Webhook 配置与 CI 触发
Webhook 是仓库告诉 CI 系统“嘿,有更新啦”的通道。配置核心就两点:
- URL: CI 系统的接收接口(比如 Jenkins 的
http://jenkins:8080/github-webhook/) - 事件选择: 只勾选必要的(push、pull request、tag push),避免每点一下 issue 都触发 pipeline
常见坑:Webhook 默认会用 HTTP POST 发送 JSON 数据。如果 CI 在内网,仓库在外网(比如 GitHub SaaS),你需要一个反向代理或隧道(如 ngrok)来接收。我曾在一次演示中忘了开隧道,现场死活看不到 webhook 事件,被领导当场问“是不是环境没配好”…其实就差一条转发规则。
这是三个平台 Webhook 的配置入口:
| GitHub | 仓库 Settings → Webhooks → Add webhook |
| GitLab | 仓库 Settings → Webhooks → Add webhook |
| Bitbucket | 仓库 Settings → Webhooks → Add webhook |
顺便提一句,GitLab 自带的 Webhook 支持“令牌验证”和“SSL 验证”——我会把这两个都打开。偷偷告诉你,GitHub 的 Webhook secret 一定不能和 API 混用,之前有团队因为复用 secret 导致整个 CI 环境被攻破。
4.5 权限与 CI 集成的最佳实践清单
最后给一张“检查清单”,你可以在搭建新项目时对着它过一遍:
- 部署密钥: 每台 CI 节点独立生成,公钥加入仓库只读部署密钥列表
- 保护分支: 主分支启用,禁止直推,要求至少 1 个审批 + CI 状态通过
- Webhook: 只勾选 push 和 pull_request 事件,设置 secret 令牌
- CI 账户: 创建专用机器人账户(如 ci-bot),赋予 Developer 角色,不要用管理员账号
- 令牌管理: 访问令牌(PAT)等定期轮换,最长 90 天
我的习惯:每次切换平台时,我都会拿这个清单和新的平台文档对比一遍。GitHub 的“Restrict who can push”和 GitLab 的“Allowed to merge”其实是同一个东西,但名字不一样——理解这些映射关系,迁移起来就不慌。
嗯,这张图把三个平台的权限链路串起来了。你看,从上到下其实都遵循同一个模式:组织/仓库 → 权限角色 → 分支保护 → 密钥与 Webhook。只是每个平台的命名和粒度不同。我在做跨平台迁移时,就是照着这个图逐个模块找对应关系的。