第 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 打错了版本,回滚花了两个通宵。

推荐的最小保护规则:

  1. 禁止直接推送(Require pull request before merging)
  2. 要求状态检查通过(Require status checks to pass)——把 CI 的关键 Job 加进去
  3. 要求最新代码(Require branches to be up-to-date)
  4. 限制谁可以 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 集成的最佳实践清单

最后给一张“检查清单”,你可以在搭建新项目时对着它过一遍:

  1. 部署密钥: 每台 CI 节点独立生成,公钥加入仓库只读部署密钥列表
  2. 保护分支: 主分支启用,禁止直推,要求至少 1 个审批 + CI 状态通过
  3. Webhook: 只勾选 push 和 pull_request 事件,设置 secret 令牌
  4. CI 账户: 创建专用机器人账户(如 ci-bot),赋予 Developer 角色,不要用管理员账号
  5. 令牌管理: 访问令牌(PAT)等定期轮换,最长 90 天

我的习惯:每次切换平台时,我都会拿这个清单和新的平台文档对比一遍。GitHub 的“Restrict who can push”和 GitLab 的“Allowed to merge”其实是同一个东西,但名字不一样——理解这些映射关系,迁移起来就不慌。

代码仓库权限与CI集成核心节点 代码仓库管理:三大平台核心能力映射 GitHub GitLab Bitbucket 权限:Admin/Write/Read 权限:5 级+自定义角色 权限:Workspace 级 保护分支 + 状态检查 MR 审批 + 保护分支 分支权限规则 Deploy Keys / Webhook Deploy Keys / Webhook Access Keys / Webhook 核心模块:权限 → 保护分支 → SSH/密钥 → Webhook → CI 触发

嗯,这张图把三个平台的权限链路串起来了。你看,从上到下其实都遵循同一个模式:组织/仓库 → 权限角色 → 分支保护 → 密钥与 Webhook。只是每个平台的命名和粒度不同。我在做跨平台迁移时,就是照着这个图逐个模块找对应关系的。