🚀Monorepo 项目 Git 权限管控:详细操作步骤指南

214 阅读14分钟

Monorepo 项目 Git 权限管控:详细操作步骤指南

基于 sichuanji-cc 项目(前面文章提及到的)的 Monorepo 架构(apps 应用层+packages 共享层)与团队协作痛点(如开发者误改跨模块代码、共享层变更无审核),本文通过 8个核心步骤,实现 Git 权限的精细化管控,确保“谁负责、谁操作,不越权、不误改”,同时兼容项目已有的 npm workspaces + Turbo 技术栈。

🚀从单体到Monorepo:四川省xxx协会官网架构重生记

一、前置准备:明确目标与工具

在开始操作前,需对齐权限管控目标、确认角色分工与工具版本,避免后续配置混乱。

1.1 权限管控核心目标

  • 限制 Web Dev 仅能操作 apps/web 及依赖的共享目录(如 packages/ui/shared),无法修改 apps/adminpackages/database
  • 确保 共享层(如 packages/auth/database)变更必须经过多角色审核,避免单一开发者修改导致全局故障;
  • 禁止 普通开发者直接推送 main/develop 等核心分支,所有变更通过 MR 合并并触发审核;
  • 实现 跨目录修改自动拦截(如 Web Dev 误改 apps/admin 时,CI 直接阻断)。

1.2 工具与环境准备

工具/平台版本要求核心作用
GitLab≥15.0(或 GitHub ≥2.0)代码托管+分支保护+CODEOWNERS 支持
Git≥2.30.0本地分支管理与提交
GitLab CI/CD与 GitLab 版本同步权限拦截脚本执行
企业 IM(如飞书)任意权限变更通知与审计结果同步

1.3 角色与账号映射表

提前在 GitLab 中创建项目角色并绑定开发者账号,后续权限配置将基于此表:

角色名称GitLab 账号示例负责目录核心操作权限
架构师@architect-li全目录(审核用)合并 main 分支、修改权限规则
Web 开发负责人@web-lead-zhangapps/web审核 Web 分支 MR、合并 release/web
Web 开发者@web-dev-wangapps/web创建 feature/web-* 分支、提交 MR
Admin 开发负责人@admin-lead-liuapps/admin审核 Admin 分支 MR、合并 release/admin
Admin 开发者@admin-dev-chenapps/admin创建 feature/admin-* 分支、提交 MR
核心服务开发@core-dev-zhaopackages/shared/auth/database创建 feature/core-* 分支、维护共享层
UI 开发@ui-dev-xupackages/ui创建 feature/ui-* 分支、维护组件库
工具链开发@devops-dev-songpackages/dev-tools维护 CI 脚本、开发工具配置
测试@tester-ma全目录(验证用)触发预发布部署、验证权限生效

二、步骤1:GitLab 仓库基础配置

先完成仓库初始化与角色添加,为后续权限配置打基础。

2.1 仓库创建(若未创建)

  • 操作路径:GitLab 首页 → New project → Import project → 选择“Existing repository”
  • 具体配置
    • 仓库名称:sichuanji-cc
    • 可见性:私有(Private)(避免外部访问)
    • 导入 URL:若从旧仓库迁移,填写旧仓库 Git 地址;若新建,直接初始化空仓库
  • 验证:访问 https://gitlab.com/[你的组名]/sichuanji-cc,确认仓库正常显示。

2.2 团队角色添加(核心操作)

将准备好的角色账号添加到仓库,并分配基础权限(避免过度授权):

  • 操作路径:GitLab 仓库 → Settings → Members → Invite members
  • 批量添加配置(按角色分组):
角色名称输入账号权限级别有效期
架构师@architect-liMaintainer(维护者)永久
Web 开发负责人@web-lead-zhangMaintainer永久
Admin 开发负责人@admin-lead-liuMaintainer永久
核心服务开发@core-dev-zhaoMaintainer永久
Web 开发者@web-dev-wangDeveloper(开发者)永久
Admin 开发者@admin-dev-chenDeveloper永久
UI 开发@ui-dev-xuDeveloper永久
工具链开发@devops-dev-songDeveloper永久
测试@tester-maReporter(报告者)永久
  • 权限说明
    • Maintainer:可配置分支保护、合并 MR(仅给负责人,避免普通开发者越权);
    • Developer:可创建分支、提交代码、发起 MR(无权限修改权限规则);
    • Reporter:可查看代码、触发 CI,但无法提交代码(适合测试角色)。
  • 验证:用 @web-dev-wang(Web 开发者)账号登录 GitLab,确认能看到 sichuanji-cc 仓库,但无法进入「Settings」页面(无权限修改配置)。

三、步骤2:核心分支保护规则实操

针对 sichuanji-cc 项目的分支体系(main/develop/release/feature),逐一配置保护规则,实现“分支-角色”绑定。

2.1 主分支(main)保护:生产环境绝对安全

main 分支对应生产代码,需最严格的权限控制:

  • 操作路径:GitLab 仓库 → Settings → Repository → Branch protection rules → Add rule
  • 具体配置
    1. Branch name pattern(分支匹配模式):填写 main(精确匹配主分支);
    2. Protect matching branches(启用保护):勾选;
    3. Allowed to push(允许推送):选择“None”(禁止任何人直接推送,必须通过 MR);
    4. Allowed to merge(允许合并):仅选择“@architect-li”(仅架构师可合并到生产);
    5. Required approvals(必填审核数):设置为“2”(需2人审核通过,如架构师+对应模块负责人);
    6. Require approval from code owners(强制代码所有者审核):勾选(关联后续 CODEOWNERS 规则);
    7. Do not allow bypassing the above settings(禁止绕过规则):勾选(防止管理员强制推送)。
  • 验证
    1. @web-dev-wang(Web 开发者)账号,本地执行 git push origin main
    2. 预期结果:Git 报错 remote: You are not allowed to push code to protected branches on this project.(无权限推送)。

2.2 开发主分支(develop)保护:整合开发成果

develop 是开发环境基准分支,允许合并但禁止直接推送:

  • 操作路径:同上,新增分支保护规则;
  • 具体配置
    1. Branch name pattern:填写 develop
    2. Allowed to push:选择“None”;
    3. Allowed to merge:选择所有角色(@web-lead-zhang/@admin-lead-liu/@core-dev-zhao 等 Maintainer 角色);
    4. Required approvals:设置为“1”(需1名对应模块负责人审核);
    5. Require approval from code owners:勾选。
  • 验证
    1. @web-dev-wang 账号发起 feature/web-test 合并到 develop 的 MR;
    2. 预期结果:MR 自动要求 @web-lead-zhang(Web 负责人)审核,审核通过后才能合并。

2.3 预发布分支(release/web/release/admin)保护:按应用隔离

release 分支对应预发布环境,仅允许对应应用的开发/测试操作:

(1)release/web 分支配置
  • 操作路径:新增分支保护规则;
  • 具体配置
    1. Branch name pattern:填写 release/web
    2. Allowed to push:选择“@web-lead-zhang”(Web 负责人)+“@tester-ma”(测试);
    3. Allowed to merge:选择“@web-lead-zhang”+“@architect-li”(架构师);
    4. Required approvals:设置为“1”(测试审核预发布结果)。
(2)release/admin 分支配置
  • Branch name pattern:填写 release/admin

  • Allowed to push:选择“@admin-lead-liu”(Admin 负责人)+“@tester-ma”;

  • Allowed to merge:选择“@admin-lead-liu”+“@architect-li”;

  • Required approvals:设置为“1”。

  • 验证

    1. @admin-dev-chen(Admin 开发者)账号,尝试推送代码到 release/web
    2. 预期结果:Git 报错 remote: You are not allowed to push code to protected branches matching 'release/web' on this project.(无权限)。

2.4 功能分支(feature/*)保护:按角色隔离

通过“分支匹配模式”批量管控 feature 分支,确保 Web Dev 仅能操作 feature/web-*

  • 操作路径:新增分支保护规则;

  • 具体配置

    1. Branch name pattern:填写 feature/web-*(匹配所有 Web 功能分支);
    2. Allowed to push:仅选择“@web-dev-wang”/“@web-lead-zhang”(Web 角色);
    3. Allowed to merge:仅选择“@web-lead-zhang”;
    4. Required approvals:设置为“1”(Web 负责人审核)。
  • 同理配置 feature/admin-* 分支:

    • Branch name patternfeature/admin-*
    • Allowed to push:仅“@admin-dev-chen”/“@admin-lead-liu”;
    • Allowed to merge:仅“@admin-lead-liu”。
  • 验证

    1. @web-dev-wang 账号创建 feature/admin-test 分支并推送;
    2. 预期结果:Git 报错 remote: You are not allowed to push code to protected branches matching 'feature/admin-*' on this project.(无权限创建 Admin 功能分支)。

四、步骤3:CODEOWNERS 配置:目录级审核绑定

通过 CODEOWNERS 文件,实现“修改特定目录必须经对应角色审核”,解决“跨目录修改无拦截”问题。

3.1 创建 CODEOWNERS 文件

  • 本地操作:在 sichuanji-cc 仓库根目录,创建 .gitlab/CODEOWNERS 文件(GitLab 专用路径;若用 GitHub,路径为 .github/CODEOWNERS);
  • 文件内容(贴合项目目录结构):
# ================= 应用层目录 =================
# apps/web:仅 Web 负责人审核
/apps/web/ @web-lead-zhang @web-reviewer

# apps/admin:仅 Admin 负责人审核
/apps/admin/ @admin-lead-liu @admin-reviewer

# ================= 共享层目录 =================
# packages/ui:UI 负责人+两端应用负责人审核(确保跨应用适配)
/packages/ui/ @ui-dev-xu @web-lead-zhang @admin-lead-liu

# packages/shared:核心开发+两端负责人审核(全局工具函数,影响所有应用)
/packages/shared/ @core-dev-zhao @web-lead-zhang @admin-lead-liu

# packages/auth:核心开发+架构师+运维审核(高风险,涉及安全)
/packages/auth/ @core-dev-zhao @architect-li @devops-dev-song

# packages/database:核心开发+架构师+运维审核(高风险,涉及数据)
/packages/database/ @core-dev-zhao @architect-li @devops-dev-song

# packages/dev-tools:仅工具链开发审核(低风险,不影响生产)
/packages/dev-tools/ @devops-dev-song

# ================= 根目录配置 =================
# CI 脚本:架构师+工具链开发审核(影响所有构建流程)
/.gitlab-ci.yml @architect-li @devops-dev-song

# 项目文档:架构师审核
/README.md @architect-li

3.2 提交 CODEOWNERS 文件

  • 本地命令
git add .gitlab/CODEOWNERS
git commit -m "feat: add CODEOWNERS for directory permission"
git push origin develop  # 推送到开发主分支
  • 验证:访问 GitLab 仓库 → Repository → Files → .gitlab → CODEOWNERS,确认文件正常显示。

3.3 验证 CODEOWNERS 生效

  • 测试场景:用 @web-dev-wang 账号修改 apps/web/src/views/Home/Banner.vue,并提交 MR 到 develop
  • 预期结果
    1. MR 页面自动显示“Required approvals from code owners”(需代码所有者审核);
    2. 审核人列表自动添加 @web-lead-zhang(CODEOWNERS 中配置的 apps/web 所有者);
    3. 若未通过 @web-lead-zhang 审核,MR 无法合并。

五、步骤4:CI/CD 权限拦截:技术阻断跨目录修改

通过 GitLab CI 脚本,在代码提交时自动检查“修改的目录是否在角色授权范围内”,实现“技术拦截”(即使权限配置遗漏,也能阻断)。

4.1 编写 CI 拦截脚本

在项目根目录创建 .gitlab-ci.yml 文件,添加“目录校验”阶段(validate-directory),优先于构建/测试阶段执行:

# .gitlab-ci.yml
# 定义流水线阶段(目录校验优先)
stages:
  - validate-directory  # 目录权限校验
  - build               # 构建(项目原有阶段,保留)
  - test                # 测试(项目原有阶段,保留)
  - deploy              # 部署(项目原有阶段,保留)

# ================= 目录权限校验任务 =================
validate-directory:
  stage: validate-directory
  image: alpine:latest  # 轻量镜像,加速执行
  only:
    - merge_requests    # 仅在 MR 时触发(避免正常开发阻塞)
  script:
    # 1. 安装 Git(alpine 镜像默认无 Git,需安装)
    apk add --no-cache git

    # 2. 获取 MR 变更的所有文件路径(对比目标分支与当前分支)
    # CI_MERGE_REQUEST_TARGET_BRANCH_SHA:目标分支(如 develop)的 commit ID
    # CI_COMMIT_SHA:当前分支(如 feature/web-test)的 commit ID
    changed_files=$(git diff --name-only $CI_MERGE_REQUEST_TARGET_BRANCH_SHA $CI_COMMIT_SHA)
    echo "=== 本次 MR 修改的文件 ==="
    echo "$changed_files"
    if [ -z "$changed_files" ]; then
      echo "ERROR:未检测到修改文件,终止校验"
      exit 1
    fi

    # 3. 定义「分支类型→允许修改的目录」映射(贴合项目角色与目录)
    declare -A branch_dir_map
    # Web 功能分支:仅允许修改 apps/web + 依赖的共享层
    branch_dir_map["feature/web-*"]="^apps/web/|^packages/ui/|^packages/shared/|^packages/auth/"
    # Admin 功能分支:仅允许修改 apps/admin + 依赖的共享层
    branch_dir_map["feature/admin-*"]="^apps/admin/|^packages/ui/|^packages/shared/|^packages/auth/|^packages/database/"
    # 核心共享层分支:仅允许修改 packages/shared/auth/database
    branch_dir_map["feature/core-*"]="^packages/shared/|^packages/auth/|^packages/database/"
    # UI 分支:仅允许修改 packages/ui
    branch_dir_map["feature/ui-*"]="^packages/ui/"
    # Web 预发布分支:仅允许修改 apps/web
    branch_dir_map["release/web"]="^apps/web/"
    # Admin 预发布分支:仅允许修改 apps/admin
    branch_dir_map["release/admin"]="^apps/admin/"

    # 4. 匹配当前分支对应的允许目录规则
    current_branch=$CI_COMMIT_BRANCH
    allowed_dirs=""
    for pattern in "${!branch_dir_map[@]}"; do
      if [[ $current_branch == $pattern ]]; then
        allowed_dirs=${branch_dir_map[$pattern]}
        break
      fi
    done

    # 5. 检查是否匹配到规则(未匹配则需人工审核)
    if [ -z "$allowed_dirs" ]; then
      echo "WARNING:当前分支 $current_branch 无预设目录规则,需人工审核修改范围!"
      exit 0  # 不阻断,但提示人工检查
    fi
    echo "=== 当前分支 $current_branch 允许修改的目录规则 ==="
    echo "$allowed_dirs"

    # 6. 校验每个修改的文件是否在允许范围内
    for file in $changed_files; do
      if ! echo "$file" | grep -E "$allowed_dirs"; then
        echo "ERROR:文件 $file 不在授权范围内!"
        echo "允许的目录规则:$allowed_dirs"
        exit 1  # 阻断 CI 流程,禁止合并
      fi
    done

    echo "=== 所有修改文件均在授权范围内,目录校验通过! ==="

# ================= 保留项目原有构建/测试/部署阶段 =================
# (以下为项目原有配置,无需修改,确保权限校验不影响原有流程)
build:
  stage: build
  image: node:18-alpine
  script:
    - npm install
    - npm run build  # 基于 npm workspaces + Turbo 的构建命令

test:
  stage: test
  image: node:18-alpine
  script:
    - npm run test

deploy:
  stage: deploy
  image: node:18-alpine
  only:
    - main  # 仅生产分支触发部署
  script:
    - npm run deploy

4.2 提交 CI 脚本并验证

  • 本地提交
git add .gitlab-ci.yml
git commit -m "feat: add directory validation in CI"
git push origin develop
  • 测试跨目录修改拦截
    1. @web-dev-wang 账号创建 feature/web-test-ci 分支;
    2. 修改 apps/admin/src/components/Button.vue(跨目录修改,Web Dev 无权限);
    3. 提交 MR 到 develop,触发 CI 流水线;
    4. 预期结果validate-directory 阶段失败,日志显示 ERROR:文件 apps/admin/src/components/Button.vue 不在授权范围内!,MR 无法合并。

六、步骤5:权限测试与验收

针对所有角色与分支,进行全场景测试,确保权限配置无遗漏。

5.1 测试用例设计(核心场景)

测试场景操作角色预期结果
普通开发者推 main 分支@web-dev-wang报错,无权限
Web Dev 创建 feature/admin-* 分支@web-dev-wang报错,无权限
Admin Dev 修改 packages/auth@admin-dev-chenMR 要求 @core-dev-zhao 审核,无审核无法合并
Web Dev 误改 apps/admin@web-dev-wangCI 校验失败,MR 阻断
架构师合并 release/webmain@architect-li成功合并,无报错

5.2 验收标准

  • 所有测试用例通过率 100%;
  • 每个角色仅能操作职责范围内的分支与目录;
  • 跨目录修改、越权分支操作均被阻断(要么 Git 报错,要么 CI 失败,要么 MR 无法审核)。

七、步骤6:定期权限审计操作

为避免“角色离职后权限未回收”“权限配置过时”等问题,需定期审计。

7.1 审计工具:GitLab API

通过 GitLab API 导出当前权限配置,无需手动检查:

  • 获取分支保护规则
# 替换 [PRIVATE_TOKEN](GitLab 个人访问令牌,需有 api 权限)、[PROJECT_ID](仓库ID)
curl --header "Private-Token: [PRIVATE_TOKEN]" "https://gitlab.com/api/v4/projects/[PROJECT_ID]/protected_branches" > branch-protection.json
  • 获取 CODEOWNERS 配置
curl --header "Private-Token: [PRIVATE_TOKEN]" "https://gitlab.com/api/v4/projects/[PROJECT_ID]/repository/files/.gitlab%2FCODEOWNERS/raw?ref=main" > codeowners-audit.txt

7.2 审计 checklist

  1. 角色权限检查:确认离职人员账号已从仓库移除(查看 Members 列表);
  2. 分支规则检查:确认 branch-protection.json 中无冗余规则(如旧分支 feature/old-* 仍有保护);
  3. CODEOWNERS 检查:确认 codeowners-audit.txt 中角色账号未失效(如 @web-reviewer 已离职,需替换);
  4. MR 记录检查:查看近1个月 MR,确认无“绕过审核合并”的情况(GitLab 仓库 → Merge requests → 筛选“Merged”,检查审核记录)。

7.3 审计结果同步

将审计报告(含问题与整改措施)通过企业 IM 同步给架构师与团队负责人,确保问题及时解决。

八、步骤7:常见问题与解决方案

问题场景原因分析解决方案
CODEOWNERS 不生效,MR 无自动审核人1. 文件路径错误(如 GitHub 用了 .gitlab/CODEOWNERS);2. 分支保护未勾选“Require approval from code owners”1. 确认文件路径正确(GitHub:.github/CODEOWNERS;GitLab:.gitlab/CODEOWNERS);2. 进入分支保护规则,勾选“Require approval from code owners”
CI 目录校验误判(合法文件被阻断)正则表达式错误(如允许目录少写 /,导致匹配失败)修正 allowed_dirs 正则,如将 ^apps/web 改为 ^apps/web/(确保匹配目录下所有文件)
开发者无法创建 feature 分支分支保护规则中“Allowed to push”未添加该角色进入对应 feature/* 分支保护规则,将开发者账号添加到“Allowed to push”列表

九、操作后效果总结

方案核心概括

保护维度具体措施核心目标
核心分支锁死main/develop分支添加.gitlab/CODEOWNERS文件级保护,仅允许架构师+工具链开发修改/合并禁止普通角色触碰核心规则
规则自保护CODEOWNERS内添加自引用配置,修改自身需双人审核(架构师+工具链开发)避免单一角色篡改规则
非授权分支阻断CI脚本拦截feature/*分支修改CODEOWNERS,触发即失败防止通过功能分支绕过规则
权限最小化仅授权2个必要角色(架构师+工具链开发),禁用强制推送减少可修改角色,降低风险
事后追溯每周用Git命令/GitLab日志审计CODEOWNERS修改记录确保所有变更可追溯
紧急流程仅通过hotfix分支修改,需双人审核+同步归档兼顾安全与紧急场景效率

通过“核心分支文件级保护+规则自审核+CI拦截非授权分支+最小化授权+定期审计”,仅允许架构师与工具链开发双人操作.gitlab/CODEOWNERS,杜绝未授权修改。

通过以上7个步骤,sichuanji-cc 项目实现了:

  1. 角色-分支-目录的精准绑定:Web Dev 仅能操作 feature/web-*apps/web,Admin Dev 仅能操作 feature/admin-*apps/admin
  2. 跨目录修改100%阻断:通过 CI 脚本与 CODEOWNERS,确保开发者无法误改非职责目录;
  3. 共享层变更多角色审核packages/auth/database 等高风险模块变更,需核心开发+架构师+运维三方审核,避免安全隐患;
  4. 权限可审计、可追溯:定期审计确保权限配置不过时,MR 记录可追溯所有变更的审核流程。

最终,该配置与项目的 npm workspaces + Turbo 技术栈协同,既保留了 Monorepo“共享复用、统一构建”的优势,又解决了“权限混乱、误操作”的痛点,为项目后续迭代提供安全保障。

以上操作步骤已覆盖从基础配置到验收审计的全流程,你可根据项目实际使用的 Git 平台(如 GitHub)微调操作路径(文中已标注 GitHub 与 GitLab 的差异)。若在实操中遇到特定场景(如新增 apps/mobile 模块后的权限扩展),或需要优化 CI 脚本适配项目现有构建流程,欢迎随时提出,我可进一步补充针对性方案。