-
Notifications
You must be signed in to change notification settings - Fork 0
Protected Paths
승인 없이는 바꿀 수 없는 경로 — Repository ruleset +
.github/CODEOWNERS. 저장소:UMC-PRODUCT/Big-Dipper-iOS
기수가 바뀌어도 기반 계층은 임의로 바뀌면 안 된다. UMCFoundation 하나를 잘못 건드리면
그걸 import 하는 449개 파일이 같이 흔들린다. 반면 Features/* 는 하나가 깨져도 그 피처만 죽는다.
그래서 blast radius 가 큰 경로에만 소유자 승인을 요구한다. 나머지는 지금까지처럼 자유롭게 머지된다.
두 개가 모두 있어야 발동한다. 하나만 있으면 아무것도 막지 않는다.
| 축 | 정하는 것 | 위치 |
|---|---|---|
Repository ruleset Protect branch
|
어떤 브랜치를, 어떤 규칙으로 | GitHub 설정 (id 11514288) |
.github/CODEOWNERS |
어떤 경로에, 누구 승인이 | 저장소 파일 (base 브랜치 기준) |
⚠️ CODEOWNERS 는 base 브랜치(develop)에 있는 버전이 적용된다. 내 브랜치에서 CODEOWNERS 를 고쳐도 그 PR 에는 적용되지 않는다.
대상 브랜치: main(default) · develop · release · testFlight
| 규칙 | 하는 일 |
|---|---|
deletion |
브랜치 삭제 금지 |
non_fast_forward |
force push 금지 |
required_linear_history |
머지 커밋 금지 (squash / rebase 만) |
pull_request |
PR 없이 직접 푸시 금지. required_approving_review_count: 0 — 일반 PR 은 지금처럼 승인 없이 머지된다 |
↳ require_code_owner_review
|
CODEOWNERS 경로가 바뀐 PR 만 소유자 승인 필수 |
↳ require_extra_approval_for_unattributed_changes
|
GitHub 계정에 연결되지 않은 이메일로 만든 커밋이 섞이면 추가 승인 요구 (GitHub 기본값) |
bypass actors — 아래 주체는 위 규칙을 우회한다.
| 주체 | 모드 |
|---|---|
Repository role Admin
|
always |
Team @UMC-PRODUCT/1st-ios
|
always |
신규 기수 팀원을
1st-ios팀에 넣으면 이 문서의 모든 보호가 무력화된다. 새 팀은 자기 기수 팀(2nd-ios등)에만 추가할 것.
소유자는 모두 @JEONG-J.
| 분류 | 경로 | 왜 |
|---|---|---|
| 게이트 | /.github/ |
여길 열어두면 CI·CODEOWNERS 를 PR 하나로 지울 수 있다 |
| 빌드 그래프 | UMCApp/Tuist/ |
Project+Feature.swift 가 전 피처의 의존성을 정의한다 |
UMCApp/Project.swift · Workspace.swift · Tuist.swift
|
워크스페이스·타겟 구성 | |
UMCApp/mise.toml |
Tuist 버전 고정 (4.155.0) |
|
UMCApp/Makefile |
빌드 진입점 | |
| 서명 · 키 | UMCApp/Secrets/ |
xcconfig · 키 |
UMCApp/UMCApp.entitlements |
App Group · capability | |
| 동결 | AppProduct/ |
v2.2.0 릴리즈 상태로 동결 (절대 규칙 #9) |
| 코어 모듈 | UMCApp/Core/Foundation/ |
UMCFoundation |
UMCApp/Core/DesignSystem/ |
||
UMCApp/Core/UIComponents/ |
||
UMCApp/Core/Domain/ |
||
UMCApp/Core/DI/ |
||
UMCApp/Core/Network/ |
CODEOWNERS 는 마지막에 일치한 줄이 이긴다. 항목을 추가할 땐 순서를 확인할 것.
코어 모듈은 취향이 아니라 실제 import 하는 파일 수로 골랐다.
| 모듈 | import 파일 수 | 보호 |
|---|---|---|
Core/Foundation (UMCFoundation) |
449 | ✅ |
Core/DesignSystem |
222 | ✅ |
Core/UIComponents |
134 | ✅ |
Core/Domain |
113 | ✅ |
Core/DI |
103 | ✅ |
Core/Network |
78 | ✅ |
Core/NearbyExchange |
23 | ❌ |
Core/WatchDesignSystem |
21 | ❌ |
Core/WatchConnectivity |
18 | ❌ |
Core/Routing |
15 | ❌ |
Core/Photo |
1 | ❌ |
Core/WidgetShared |
0 | ❌ |
측정 명령:
cd UMCApp
grep -rl --include='*.swift' '^import UMCFoundation' Core Features UMCApp UMCWatchApp UMCAppWidget UMCWatchComplication | wc -l의도적으로 제외한 것
-
Features/*전부 — 팀이 실제로 일하는 곳이다. 여기까지 막으면 승인 대기로 개발이 멈춘다. 승인 게이트의 값어치보다 리뷰 대기 비용이 크다. - fan-in 낮은 Core 모듈 — 격리돼 있어 깨져도 해당 기능만 영향받는다.
-
Core/Routing(15) 은 경계선. 딥링크 회귀가 반복되면 그때 추가한다.
보호 경로를 건드렸다는 뜻이다. PR 의 Files changed 에서 어떤 파일이 위 표에 해당하는지 확인하고,
@JEONG-J 를 리뷰어로 요청한다. 보호 경로를 건드릴 의도가 없었다면 그 파일을 커밋에서 빼는 게 빠르다.
로컬 git 이메일이 GitHub 계정에 등록돼 있지 않다. 확인:
git config user.email # 로컬 설정
gh api user/emails --jq '.[].email' # GitHub 에 등록된 이메일GitHub Settings → Emails 에 그 주소를 추가하거나, git config user.email 을 등록된 주소로 맞춘다.
정상적인 경로다. 막는 게 목적이 아니라 혼자 조용히 바뀌는 걸 막는 게 목적이다. 이슈에 변경 이유와 영향 범위(어떤 모듈이 같이 깨질 수 있는지)를 적고 PR 을 올린 뒤 승인을 요청하면 된다.
.github/CODEOWNERS 를 수정하는 PR 을 올린다. 그 PR 자체가 /.github/ 경로에 걸리므로 소유자 승인이 필요하다.
# CODEOWNERS 문법 검증 (잘못된 경로는 조용히 무시되므로 반드시 확인)
gh api repos/UMC-PRODUCT/Big-Dipper-iOS/codeowners/errors
# 현재 ruleset 상태
gh api repos/UMC-PRODUCT/Big-Dipper-iOS/rulesets/11514288 \
--jq '{enforcement, rules: [.rules[].type], bypass: .bypass_actors}'
# bypass 권한을 가진 팀 멤버 (게이트가 실제로 걸리는지 확인)
gh api orgs/UMC-PRODUCT/teams/1st-ios/members --jq '.[].login'관련 문서: Git Workflow · Module Structure · Coding Conventions