이 가이드에서는 풀 요청 (PR) 승인 요구사항을 유연하게 제어할 수 있는 CODEOWNERS 기능의 구조, 구문, 구현을 설명합니다.
소개
Secure Source Manager CODEOWNERS 기능은 코드베이스의 파일을 사용하여 파일 수준 승인자를 설정합니다. 특정 파일에 특정 소유자를 할당하고 독립적인 승인자 집합을 정의할 수 있으므로 다른 브랜치 규칙보다 더 세부적인 제어가 가능합니다.
CODEOWNERS 기능은 다음 기능을 제공합니다.
- 파일, 디렉터리, 브랜치의 풀 요청을 승인할 수 있는 사용자를 정의합니다.
- 다양한 분기를 보호하도록 다양한 코드 소유자 집합을 구성합니다.
- 파일 변경사항이 지정된 소유자에 의해 검토되도록 합니다.
코드 소유자 검토 사용 설정
CODEOWNERS 규칙을 활성화하고 시행하려면 브랜치 보호 관리자가 저장소 설정에서 브랜치 규칙을 풀 요청에 코드 소유자 검토 필요로 업데이트해야 합니다. 브랜치 규칙 설정에서 이 옵션을 선택합니다.
이 설정이 사용 중지이면 시스템은 타겟 브랜치로 병합할 때 CODEOWNERS 파일을 무시합니다. 이 옵션을 선택하면 코드 소유자가 풀 요청을 검토하고 승인할 때까지 시스템에서 브랜치에 대한 푸시 및 병합을 차단합니다.
CODEOWNERS 파일 위치 및 우선순위
Secure Source Manager는 CODEOWNERS 파일을 정의하는 두 가지 옵션을 지원합니다.
중첩된 파일:
.securesourcemanager디렉터리를 제외한 모든 디렉터리의CODEOWNERS파일 중첩된CODEOWNERS파일은 자체 디렉터리 (하위 디렉터리 포함)에만 영향을 미치며, 파일 경로는CODEOWNERS파일이 있는 디렉터리를 기준으로 지정해야 합니다. 이는 대부분의 사용 사례에 권장되는 접근 방식입니다.단일 전용 파일: Secure Source Manager의
CODEOWNERS파일을 다른 도구 (예:.gitlab/CODEOWNERS)에서 사용하는 다른CODEOWNERS파일과 구분해야 하는 경우 저장소 루트의.securesourcemanager/CODEOWNERS에 있는 단일 파일을 사용할 수 있습니다. 이 파일이 있으면 Secure Source Manager는 중첩된 파일을 포함하여 동일한 브랜치의 다른 모든 CODEOWNERS 파일을 무시합니다..securesourcemanager디렉터리는 저장소 루트에서만 인식됩니다.
풀 요청 및 승인과의 상호작용
pull 요청이 생성되거나 소스 브랜치가 새 커밋으로 업데이트되면 시스템은 기본 브랜치 (병합하려는 브랜치)의 CODEOWNERS 파일만 사용하여 승인 요구사항을 결정합니다.
시스템은 해당 확인을 위해 푸시하는 코드 내의 CODEOWNERS 파일 변경사항을 무시합니다.
CODEOWNERS 구문 및 구조
CODEOWNERS 파일은 주석, 규칙 줄, 섹션 마커로 구성됩니다.
주석은 #로 시작하며 시스템에서 무시됩니다.
규칙 선 형식
규칙 줄의 표준 형식은 다음과 같습니다.
[BRANCH_GLOB] PATH_GLOB [OWNERS...]
각 항목의 의미는 다음과 같습니다.
BRANCH_GLOB: 규칙이 적용되는 브랜치를 지정하는 선택적 glob 패턴입니다. 브랜치 glob을 지정하지 않으면CODEOWNERS파일이 체크인된 모든 브랜치에 규칙이 적용됩니다 (브랜치 규칙에CODEOWNERS가 사용 설정된 경우). 예를 들면 다음과 같습니다.main은main브랜치와만 일치합니다.dev-*는dev-로 시작하는 브랜치와 일치합니다.*-glob는-glob로 끝나는 브랜치와 일치합니다.my-*-glob는my-feat-glob과 같은 브랜치와 일치합니다.
PATH_GLOB: 규칙이 적용되는 파일 경로를 지정하는 필수 glob 패턴입니다. Secure Source Manager의 구문은gitignore패턴을 기반으로 합니다.- 패턴에
/가 없거나/가 후행 문자로만 포함된 경우 모든 디렉터리에서 일치하는 glob입니다.*.js는 어디에나 있는 JavaScript 파일과 일치합니다.build/은build이라는 디렉터리와 일치합니다.
- 패턴에
/가 끝이 아닌 다른 위치에 포함되어 있으면CODEOWNERS파일의 위치를 기준으로 하는 경로로 처리됩니다.docs/*는CODEOWNERS파일을 기준으로docs/아래의 파일과 일치합니다./*.js는 CODEOWNERS 파일과 동일한 디렉터리의 JavaScript 파일과 일치하지만 중첩된 JavaScript 파일과는 일치하지 않습니다.
/로 끝나는 패턴은 디렉터리와 그 콘텐츠만 재귀적으로 일치합니다. 예를 들어build-*/은build-app/및build-tool/와 같은 디렉터리를 어디에서나 찾습니다..securesourcemanager/CODEOWNERS를 사용하는 경우 경로는 저장소 루트를 기준으로 합니다.
- 패턴에
OWNERS: 소유자 이메일 주소의 선택적 목록입니다(공백으로 구분). 생략할 경우 이 규칙은 경로 제외로 작동합니다.
지점별 소유권
규칙 줄 시작 부분에 있는 선택적 BRANCH_GLOB 필드를 사용하면 브랜치별 코드 소유자 제어를 구현할 수 있습니다.
- 규칙 시작 부분에
BRANCH_GLOB를 지정하지 않으면 규칙이 모든 지점에 적용됩니다. - 시스템은 현재 브랜치와 일치하지 않는 브랜치 glob이 있는 행을 무시합니다.
구문 기본사항
- 필드 해석: 필드는 공백으로 구분됩니다.
@이 포함된 필드는 소유자 이메일 주소로 식별됩니다.@가 없는 필드가 소유자 이메일 주소 앞에 있으면PATH_GLOB로 처리됩니다. 예를 들어*.js user@example.com에서*.js은PATH_GLOB입니다.@가 없는 두 필드가 소유자 이메일 주소 앞에 오는 경우 첫 번째는BRANCH_GLOB이고 두 번째는PATH_GLOB입니다. 예를 들어main *.js user@example.com에서main은BRANCH_GLOB이고*.js은PATH_GLOB입니다.- 소유자가 지정되지 않은 경우에도 동일한 논리가 적용됩니다. 한 필드는
PATH_GLOB이고 두 필드는BRANCH_GLOB PATH_GLOB입니다.
- 글로브 스타일 구문: Secure Source Manager는 경로 표현식에 표준 글로브 스타일(
.gitignore스타일) 구문을 사용합니다. - 와일드 카드 문자 세부정보:
**는/를 포함한 모든 문자 시퀀스와 일치합니다.*는/을 제외한 모든 문자 시퀀스와 일치합니다.?는/을 제외한 모든 단일 문자와 일치합니다.
- 대소문자 구분:
CODEOWNERS파일은 대소문자를 구분합니다. - 소유자 식별: 시스템에서 이메일 주소로 소유자를 식별합니다.
@문자는 소유자 필드를 구분합니다. - 소유자 이메일 주소에서는
space와backslash만 이스케이프하면 됩니다. - 예약된 문자: 시스템에서 다음 문자를 예약합니다. 브랜치 및 경로 표현식(
[,],,@,*,?,\,{,},!)에서 백슬래시로 이스케이프(\)해야 합니다. **이 슬래시가 아닌 문자와 혼합되면 시스템에서 일반 와일드 카드로 처리합니다. 예를 들어/**/*.py는 모든 깊이의 Python 파일과 일치하고/**.py은/*.py처럼 처리되어 루트 디렉터리의 파일과만 일치합니다.
여러 승인 세트의 섹션
[Section]를 사용하면 승인이 필요한 항목이 독립적으로 그룹화됩니다. 이는 보안팀이나 QA팀과 같은 별도의 팀의 검토를 요구하는 데 유용합니다.
- 섹션 정의:
[Section Name]형식의 줄을 사용합니다 (자연어 이름을 사용해도 됨). - 승인 수: 섹션에는 1이 아닌 승인 수를 지정하는 선택적 접미사
[<approverCount>]가 포함될 수 있습니다.0개수는 선택적 소유자를 나타냅니다. 예를 들어 이 기능을 사용하면 검토가 필요하지 않은 특정 파일의 전문가를 정보 제공 목적으로 표시할 수 있습니다. - 섹션 종료: 섹션은 다음 섹션이 시작될 때까지 섹션 다음에 나오는 모든 규칙에 적용됩니다.
- 섹션이 없는 규칙:
[Section]정의 앞에 표시되는 규칙은 단일 통합 섹션으로 처리되므로 기본적으로 승인이 하나 필요합니다. - 통합: 시스템은 여러 중첩된
CODEOWNERS파일에 걸쳐 있더라도 대소문자를 구분하지 않는 이름이 동일한 섹션을 표준 우선순위 규칙에 따라 단일 통합 섹션으로 취급합니다.
경로 제외
이전의 더 광범위한 절에서 특정 경로를 제외하려면 경로의 소유자를 0으로 설정하세요. 소유자 없이 규칙을 정의하면 시스템에서 이전 규칙에 의해 설정된 해당 경로의 소유자를 삭제하고 경로에 소유자 승인이 필요하지 않습니다.
디렉터리 일치는 /로 끝나거나 마지막 부분에 와일드 카드가 없는 경우에만 작동합니다.
예를 들어 *.py은 숨겨진 디렉터리 .py/와 일치하지 않지만 *.py/는 일치합니다.
충돌 해결 및 우선순위
.securesourcemanager/CODEOWNERS 파일이 있으면 다른 모든 CODEOWNERS 파일은 무시됩니다. 경로가 동일한 섹션의 두 가지 다른 행과 일치하는 경우 마지막 행만 적용됩니다. 줄이 서로 다른 섹션에 있는 경우 두 줄이 모두 적용됩니다.
시스템은 중첩된 파일에 위치 기반 우선순위 규칙을 사용합니다.
- 더 깊이 중첩된 (더 로컬)
CODEOWNERS파일의 규칙은 더 얕은 파일의 일치하는 규칙을 재정의합니다. - 루트 디렉터리
CODEOWNERS파일은 항상 우선순위가 가장 낮습니다.
CODEOWNERS 파일의 예
다음은 CODEOWNERS 구문을 보여주는 CODEOWNERS 파일의 예시입니다.
# Un-sectioned rules; 1 approve required from any of owners of last matching line.
# Format: [BRANCH_GLOB] PATH_GLOB [OWNERS...]
# Make repo-admin the owner of all files of the current branch.
* repo-admin@example.com # No slash prefix; matches in sub-dirs too.
/**/* repo-admin@example.com # Slash-prefix equivalent of prior line.
# Match all py files (including sub-dirs). Note repo-admin must be re-added.
*.py repo-admin@example.com python-owner@example.com
# With repo-admin not included here, repo-admin no longer owns README.
/README.md readme-owner@example.com
/scratchpad.txt # Can also override a path to have zero owners (path exclusion).
# Branch-specific syntax.
# Note that since un-sectioned rules are independent of sectioned rules,
# the above [Section] rules will still apply to this branch if they
# aren't modified to add e.g. `main ` as a prefix.
dev-* * # Remove all owners reqs on dev branches.
dev-* /experimental/ exp-owner@example.com # dev-specific owners.
# Make repo admin own all CODEOWNERS files, regardless of any prior rules.
CODEOWNERS repo-admin@example.com
# Section; 1 approval required *in addition* to owners outside this section.
[Security Team]
/secure-directory/ security-expert@example.com security-reviewer@example.com
/**/*secure\ me* security-expert@example.com security-reviewer@example.com
# Section w/ req approval count of 2 instead of 1.
[Doc Team][2]
/docs doc-expert@example.com doc-reviewer@example.com
*.md doc-expert@example.com doc-reviewer@example.com
다른 소스 코드 관리자와의 호환성
Secure Source Manager는 다른 소스 코드 관리자와 호환되고 이식 가능한 구문을 제공합니다. Secure Source Manager CODEOWNERS 구문은 GitHub CODEOWNERS 구문과 호환되며, [Section
Name][2]와 같은 섹션별 승인 수를 비롯해 GitLab CODEOWNERS 구문과 부분적으로 호환됩니다.
CODEOWNERS의 Secure Source Manager 구현은 경로 부정에 대한 GitLab !path 구문을 지원하지 않습니다. Secure Source Manager의 경로 부정에 관한 자세한 내용은 경로 제외를 참고하세요. Secure Source Manager는 섹션 헤더의 기본 소유자(예: [Section
Name] @owner1 @owner2)도 지원하지 않습니다.
유효성 검사 및 오류 처리
CODEOWNERS 파일을 볼 때 UI에 상태와 행 수준 경고 또는 정보 (예: 이 브랜치와 일치하지 않는 행)가 표시됩니다. 강조 표시된 줄 번호 또는 줄 위로 마우스를 가져가면 추가 세부정보를 볼 수 있습니다.
적용
제출 전 가드는 코드 소유자 브랜치 규칙을 사용 설정한 모든 브랜치에서 문법 오류 검사를 적용합니다. 이렇게 하면 손상된 CODEOWNERS 파일을 실수로 체크인하는 것을 방지할 수 있습니다.
구문 오류 처리
사전 제출 검사는 pull 요청에 코드 소유자 검토 필요가 사용 설정된 브랜치에서만 실행됩니다. 구문이 잘못된 CODEOWNERS 파일이 브랜치에 커밋되고 나중에 해당 브랜치에 코드 소유자 검토가 사용 설정되면 시스템에서 오류를 적절하게 처리합니다.
- 시스템은 섹션 정의, 규칙 줄 또는 주석 형식으로 파싱할 수 없는 줄을 무시합니다.
- 승인 수가 음수이면 시스템에서 0으로 처리합니다.
- 시스템은 유효한 행을 평소와 같이 계속 파싱하고 적용합니다.