푸시 규칙
GitLab v19.5Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
요약
푸시 규칙은 사용자 친화적인 인터페이스에서 활성화할 수 있는 pre-receive Git 훅입니다. GitLab은 푸시 규칙의 정규 표현식에 RE2 구문을 사용합니다. RE2는 /pattern/flags 형식을 지원하지 않습니다.
푸시 규칙은 사용자 친화적인 인터페이스에서 활성화할 수 있는
pre-receive Git 훅입니다. 푸시 규칙을 사용하면 리포지터리에 푸시할 수 있는 항목과
푸시할 수 없는 항목을 더 세밀하게 제어할 수 있습니다. GitLab은 보호된 브랜치를 제공하지만,
다음과 같이 더 구체적인 규칙이 필요할 수 있습니다.
- 커밋 내용 평가.
- 커밋 메시지가 예상 형식과 일치하는지 확인.
- 브랜치 이름 규칙 적용.
- 파일 세부 정보 평가.
- Git 태그 제거 방지.
- 서명된 커밋 요구.
GitLab은 푸시 규칙의 정규 표현식에 RE2 구문을 사용합니다. 정규 표현식은 regex101 정규식 테스터에서 테스트할 수 있습니다. 각 정규 표현식은 511자로 제한됩니다.
RE2는 /pattern/flags 형식을 지원하지 않습니다.
플래그를 설정하려면 표현식 시작 부분에 추가합니다.
예를 들어 대소문자를 구분하지 않고 패턴을 일치시키려면 (?i)pattern을 사용합니다.
사용자 정의 푸시 규칙에는 서버 훅을 사용합니다.
푸시 규칙은 포크 동기화 중에 우회됩니다. 업스트림 프로젝트에서 포크를 업데이트하면 변경 사항이 포크의 푸시 규칙에 대한 검증 없이 직접 적용됩니다.
푸시 규칙은 상속되는 설정이 아니라 템플릿으로 동작합니다.
- 전역 푸시 규칙은 새 프로젝트의 템플릿 역할을 합니다. 전역 푸시 규칙을 만들면 그 시점 이후에 만들어진 모든 프로젝트에 복사됩니다.
- 프로젝트 푸시 규칙은 독립된 복사본입니다. 프로젝트가 만들어진 후에는 전역 규칙이나 그룹 규칙을 변경해도 프로젝트의 푸시 규칙이 자동으로 갱신되지 않습니다.
- 프로젝트 푸시 규칙을 삭제하면 해당 프로젝트에서 모든 푸시 규칙 제어가 제거됩니다. 프로젝트가 전역 규칙이나 그룹 규칙을 사용하는 상태로 되돌아가지 않습니다.
업데이트된 전역 푸시 규칙을 기존 프로젝트에 적용하려면 각 프로젝트마다 개별적으로 전역 푸시 규칙을 재정의해야 합니다.
프로젝트에서 푸시 규칙을 삭제하면 해당 프로젝트에는 푸시 규칙이 전혀 없습니다. 프로젝트가 그룹이나 인스턴스의 규칙을 자동으로 상속하지 않습니다. 푸시 규칙을 복원하려면 프로젝트에 다시 구성해야 합니다.
전역 푸시 규칙 활성화#
모든 새 프로젝트의 템플릿 역할을 하는 푸시 규칙을 만들 수 있습니다. 이러한 규칙은 개별 프로젝트나 그룹에서 재정의할 수 있습니다.
전역 푸시 규칙을 구성하면 다음과 같이 동작합니다.
- 전역 푸시 규칙을 구성한 후에 만들어진 모든 프로젝트는 이 구성의 복사본을 상속합니다.
- 기존 프로젝트는 영향을 받지 않습니다. 이러한 프로젝트를 수동으로 업데이트하려면 프로젝트별 전역 푸시 규칙 재정의를 참고합니다.
- 전역 푸시 규칙을 변경해도 이미 푸시 규칙이 구성된 프로젝트는 업데이트되지 않습니다.
사전 요구 사항:
- 관리자여야 합니다.
전역 푸시 규칙을 만들려면 다음 단계를 수행합니다.
- 오른쪽 위 모서리에서 Admin을 선택합니다.
- 왼쪽 사이드바에서 Push rules를 선택합니다.
- Push rules를 확장합니다.
- 원하는 규칙을 설정합니다.
- Save push rules를 선택합니다.
그룹 푸시 규칙#
그룹 푸시 규칙을 사용하면 그룹 Maintainer가 특정 그룹에서 새로 만들어진 프로젝트에 적용할 푸시 규칙을 설정할 수 있습니다.
그룹의 푸시 규칙을 구성하려면 다음 단계를 수행합니다.
- 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
- 왼쪽 사이드바에서 Settings > Repository를 선택합니다.
- Pre-defined push rules 섹션을 확장합니다.
- 원하는 설정을 선택합니다.
- Save push rules를 선택합니다.
새 프로젝트는 다음에서 푸시 규칙을 상속합니다.
- 푸시 규칙이 정의된 가장 가까운 상위 그룹.
- 상위 그룹에 푸시 규칙이 정의되어 있지 않으면 인스턴스 전체에 설정된 푸시 규칙.
푸시 규칙을 상속하는 것은 프로젝트뿐입니다. 하위 그룹은 상위 그룹에서 푸시 규칙을 상속하지 않습니다. 새 프로젝트에 어떤 푸시 규칙이 적용되는지 확인하려면 하위 그룹에 프로젝트를 만들고 그 프로젝트의 푸시 규칙을 확인합니다.
프로젝트별 전역 푸시 규칙 재정의#
프로젝트 푸시 규칙은 전역 푸시 규칙과 독립적입니다. 프로젝트에 푸시 규칙을 설정하면 그 규칙이 해당 프로젝트에 이전에 구성된 모든 규칙을 대체합니다.
프로젝트에 푸시 규칙을 설정하려면 다음 단계를 수행합니다.
- 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
- 왼쪽 사이드바에서 Settings > Repository를 선택합니다.
- Push rules를 확장합니다.
- 원하는 규칙을 설정합니다.
- Save push rules를 선택합니다.
프로젝트가 새 전역 푸시 규칙과 일치하게 하려면 전역 설정과 일치하도록 프로젝트의 푸시 규칙을 직접 구성해야 합니다. 프로젝트는 전역 푸시 규칙의 변경 사항을 자동으로 상속하지 않습니다.
사용자 검증#
커밋을 작성하는 사용자를 검증할 때 다음 규칙을 사용합니다.
이러한 푸시 규칙은 커밋에만 적용되며 태그에는 적용되지 않습니다.
-
Reject unverified users: 커미터 이메일은 사용자의 확인된 이메일 주소 또는 비공개 커밋 이메일 주소 중 하나와 일치해야 합니다.
-
Reject inconsistent user name: 작성자 이메일과 커미터 이메일이 같은 커밋에서는 커밋 작성자 이름이 사용자의 GitLab 계정 이름과 일치해야 합니다. 두 이메일이 다르면 이 검사는 건너뜁니다. 이런 경우는 다른 기여자의 커밋을 cherry-pick 하거나 리베이스하는 등의 워크플로에서 발생합니다.
이 규칙은 사용자의 Git 설정에서 잘못된 구성을 잡아내어 커밋 위생을 유지하는 데 도움이 되지만, 사칭을 막지는 못합니다. 암호학적 신원 검증이 필요하면 Reject unsigned commits를 대신 사용합니다.
-
Check whether the commit author is a GitLab user: 커밋 작성자와 커미터 이메일 주소가 모두 GitLab 사용자의 확인된 이메일 주소와 일치해야 합니다.
-
Commit author's email: 작성자와 커미터 이메일 주소가 모두 정규 표현식과 일치해야 합니다. 모든 이메일 주소를 허용하려면 비워 둡니다.
프로젝트용 봇 사용자 또는 그룹용 봇 사용자를 사용할 때는 봇 토큰이 커밋하고 변경 사항을 푸시할 수 있도록 생성된 이메일 접미사를 추가해야 합니다.
GitLab이 서명한 커밋#
히스토리
- GitLab 19.3에서 미러링된 커밋을 포함하도록 변경되었습니다.
GitLab이 서명한 커밋은 커미터로 noreply@example.com과 같은
인스턴스 이메일 주소를 사용합니다.
이 주소는 GitLab 사용자에게 속하지 않습니다.
다음 규칙은 커밋이 프로젝트에 도달한 경로와 관계없이 이러한 커밋의 커미터 이메일 주소를
검사하지 않습니다.
- Reject unverified users
- Check whether the commit author is a GitLab user
- Commit author's email
GitLab은 대신 작성자 이메일 주소를 검사합니다. 예외는 Reject unverified users로, GitLab은 리포지터리 미러링처럼 Git 푸시로 도착한 커밋에 대해서는 이 규칙을 건너뜁니다.
커밋 메시지 검증#
커밋 메시지에는 다음 규칙을 사용합니다.
-
Require expression in commit messages: 메시지가 해당 표현식과 일치해야 합니다. 모든 커밋 메시지를 허용하려면 비워 둡니다. 멀티라인 모드를 사용하며,
(?-m)으로 비활성화할 수 있습니다. 검증 예시는 다음과 같습니다.JIRA\-\d+는 모든 커밋이 Jira 이슈를 참조하도록 요구합니다. 예를 들면Refactored css. Fixes JIRA-123입니다.[[:^punct:]]\b$는 마지막 문자가 문장 부호이면 커밋을 거부합니다. Git이 커밋 메시지 끝에 줄바꿈 문자(\n)를 추가하므로, 단어 경계 문자(\b)가 거짓 음성을 방지합니다.
GitLab UI에서 만든 커밋 메시지는 줄바꿈 문자로
\r\n을 설정합니다. 정규 표현식에서\n대신(\r\n?|\n)을 사용해야 이를 올바르게 일치시킵니다.예를 들어 다음과 같은 여러 줄 커밋 설명이 있다고 가정합니다.
JIRA: Description이 설명은
JIRA:(\r\n?|\n)\w+정규 표현식으로 검증할 수 있습니다. -
Reject expression in commit messages: 커밋 메시지가 해당 표현식과 일치하지 않아야 합니다. 모든 커밋 메시지를 허용하려면 비워 둡니다. 멀티라인 모드를 사용하며,
(?-m)으로 비활성화할 수 있습니다.
브랜치 이름 검증#
브랜치 이름을 검증하려면 Branch name에 정규 표현식을 입력합니다. 모든 브랜치 이름을 허용하려면 비워 둡니다. 기본 브랜치는 항상 허용됩니다. 보안을 위해 일부 형식의 브랜치 이름은 기본적으로 제한됩니다. Git 커밋 해시와 비슷한 40자리 16진수 문자로 이루어진 이름은 금지됩니다.
검증 예시는 다음과 같습니다.
-
브랜치는
JIRA-로 시작해야 합니다.^JIRA- -
브랜치는
-JIRA로 끝나야 합니다.-JIRA$ -
브랜치는 대소문자 구분 없이
feature/로 시작해야 합니다.(?i)^feature/ -
브랜치 이름은
4자에서15자 사이여야 하며, 소문자, 숫자, 하이픈만 허용합니다.^[a-z0-9\\-]{4,15}$
의도하지 않은 결과 방지#
의도하지 않은 결과를 방지할 때 다음 규칙을 사용합니다.
- Reject unsigned commits: 커밋에 서명이 있어야 합니다. 이 규칙은 Web IDE에서 만든 일부 정상적인 커밋을 차단할 수 있고, GitLab이 만든 서명되지 않은 커밋이 커밋 이력에 나타나는 것을 허용합니다.
- Do not allow users to remove Git tags with
git push: 사용자가git push로 Git 태그를 제거할 수 없습니다.
파일 검증#
커밋에 포함된 파일을 검증할 때 다음 규칙을 사용합니다.
- Prevent pushing secret files: 파일에 시크릿이 포함되어 있지 않아야 합니다.
- Prohibited filenames: 리포지터리에 존재하지 않는 파일은 이 정규 표현식과 일치하지 않아야 합니다. 모든 파일 이름을 허용하려면 비워 둡니다. 일반적인 예시를 참고합니다.
- Maximum file size: 추가되거나 업데이트된 파일이 이 파일 크기(MB 단위)를
초과하지 않아야 합니다. 크기와 무관하게 파일을 허용하려면
0으로 설정합니다. Git LFS로 추적되는 파일은 제외됩니다.
리포지터리에 시크릿 푸시 방지#
자격 증명 파일이나 SSH 개인 키 같은 시크릿은 버전 관리 시스템에 절대 커밋하지 않아야 합니다. GitLab에서는 미리 정의된 파일 이름 패턴 목록을 사용해 일치하는 파일이 리포지터리에 푸시되는 것을 방지할 수 있습니다. 일치하는 파일이 포함된 머지 리퀘스트는 차단됩니다. 이 푸시 규칙은 이미 리포지터리에 커밋된 파일은 제한하지 않습니다. 기존 프로젝트에 이 규칙을 적용하려면 프로젝트별 전역 푸시 규칙 재정의에 설명된 절차에 따라 구성을 업데이트해야 합니다.
이 규칙으로 차단되는 파일은 아래와 같습니다. 전체 기준 목록은
files_denylist.yml을 참고합니다.
- AWS CLI 자격 증명 블롭:
.aws/credentialsaws/credentialshomefolder/aws/credentials
- RSA SSH 개인 키:
/ssh/id_rsa/.ssh/personal_rsa/config/server_rsaid_rsa.id_rsa
- DSA SSH 개인 키:
/ssh/id_dsa/.ssh/personal_dsa/config/server_dsaid_dsa.id_dsa
- ED25519 SSH 개인 키:
/ssh/id_ed25519/.ssh/personal_ed25519/config/server_ed25519id_ed25519.id_ed25519
- ECDSA SSH 개인 키:
/ssh/id_ecdsa/.ssh/personal_ecdsa/config/server_ecdsaid_ecdsa.id_ecdsa
- ECDSA_SK SSH 개인 키:
/ssh/id_ecdsa_sk/.ssh/personal_ecdsa_sk/config/server_ecdsa_skid_ecdsa_sk.id_ecdsa_sk
- ED25519_SK SSH 개인 키:
/ssh/id_ed25519_sk/.ssh/personal_ed25519_sk/config/server_ed25519_skid_ed25519_sk.id_ed25519_sk
- 다음 접미사로 끝나는 모든 파일:
*.pem*.key*.history*_history
이름으로 파일 금지#
Git에서 파일 이름은 파일의 이름과 그 앞에 오는 모든 디렉터리를 포함합니다.
git push를 실행하면 푸시에 포함된 각 파일 이름이 Prohibited filenames의 정규
표현식과 비교됩니다.
이 기능은 RE2 구문을 사용하며, 긍정 전방 탐색과 부정 전방 탐색을 지원하지 않습니다.
정규 표현식으로 다음과 같이 처리할 수 있습니다.
- 리포지터리의 모든 위치에서 파일 이름을 일치시킵니다.
- 특정 위치의 파일 이름을 일치시킵니다.
- 파일 이름의 일부를 일치시킵니다.
- 확장자로 특정 파일 형식을 제외합니다.
- 여러 표현식을 결합해 여러 패턴을 제외합니다.
정규 표현식 예시#
다음 예시는 일반적인 정규식 문자열 경계 패턴을 사용합니다.
^: 문자열의 시작과 일치합니다.$: 문자열의 끝과 일치합니다.\.: 마침표 문자 자체와 일치합니다. 백슬래시가 마침표를 이스케이프합니다.\/: 슬래시 문자 자체와 일치합니다. 백슬래시가 슬래시를 이스케이프합니다.
특정 파일 형식 방지#
-
리포지터리의 모든 위치에
.exe파일을 푸시하지 못하게 하려면 다음과 같이 설정합니다.\.exe$
특정 파일 방지#
-
특정 구성 파일을 푸시하지 못하게 하려면 다음과 같이 설정합니다.
-
리포지터리 루트의 경우:
^config\.yml$ -
특정 디렉터리의 경우:
^directory-name\/config\.yml$
-
-
위치와 관계없이
install.exe라는 이름의 파일을 푸시하지 못하게 하는 예시는 다음과 같습니다.(^|\/)install\.exe$
패턴 결합#
여러 패턴을 하나의 표현식으로 결합할 수 있습니다. 다음 예시는 앞의 표현식을 모두 결합한 것입니다.
(\.exe|^config\.yml|^directory-name\/config\.yml|(^|\/)install\.exe)$
서명된 커밋 요구#
서명된 커밋은 Git 커밋의 진위와 무결성을 검증하는 데 사용하는 디지털 서명입니다. Reject unsigned commits 푸시 규칙을 사용하면 GitLab이 만든 커밋은 서명되지 않은 상태로 두면서 외부 기여자에게는 서명된 커밋을 강제할 수 있습니다.
Reject unsigned commits 푸시 규칙을 활성화하면 다음과 같이 동작합니다.
- GitLab 외부에서 (
git push로) 푸시한 커밋에는 유효한 암호학적 서명이 있어야 합니다. 서명되지 않은 커밋은 거부됩니다. - GitLab UI 나 API로 만든 커밋은 서명이 없어도 허용됩니다. 이러한 커밋은 Web IDE, 머지 리퀘스트 작업, API 작업에서 나올 수 있습니다.
GitLab에서 만든 커밋은 이 규칙에서 제외되므로, 규칙을 활성화해도 서명되지 않은 커밋이 커밋 이력에 나타날 수 있습니다. 이 규칙은 외부 Git 클라이언트에서 푸시한 커밋만 검증합니다.
자세한 내용은 이슈 5361을 참고합니다.
서명은 지원되는 서명 방식으로 만들어야 합니다.
- GPG
- SSH
- X.509
서명이 유효하지 않거나 손상된 커밋은 거부됩니다.
규칙 활성화#
Reject unsigned commits 푸시 규칙을 활성화하려면 다음 단계를 수행합니다.
- 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
- 왼쪽 사이드바에서 Settings > Repository를 선택합니다.
- Push rules를 확장합니다.
- Reject unsigned commits를 선택합니다.
- Save push rules를 선택합니다.
Reject unsigned commits와 Web IDE#
프로젝트에 Reject unsigned commits 푸시 규칙이 설정되어 있으면 사용자는 기본적으로 GitLab Web IDE로 커밋을 만들 수 없습니다.
이 푸시 규칙이 설정된 프로젝트에서 Web IDE로 커밋할 수 있게 하려면 GitLab 관리자가
reject_unsigned_commits_by_gitlab 기능 플래그를 비활성화해야 합니다.
Feature.disable(:reject_unsigned_commits_by_gitlab)
이 기능 플래그를 비활성화하면 Web IDE에서 만든 커밋이 서명 없이 허용됩니다. 자세한 내용은 기능 활성화 또는 비활성화를 참고합니다.
DCO 인증을 거치지 않은 커밋 거부#
Developer Certificate of Origin(DCO)으로 서명된 커밋은 기여자가
해당 커밋에 기여한 코드를 직접 작성했거나 제출할 권리가 있음을 인증합니다.
프로젝트의 모든 커밋이 DCO를 준수하도록 요구할 수 있습니다. 이 푸시 규칙은 모든 커밋 메시지에
Signed-off-by: 트레일러를 요구하며, 트레일러가 없는 커밋은 거부합니다.
관련 주제#
문제 해결#
모든 프로젝트의 푸시 규칙 일괄 업데이트#
모든 프로젝트의 푸시 규칙을 동일하게 업데이트하려면 Rails 콘솔을 사용하거나, 푸시 규칙 API 엔드포인트로 각 프로젝트를 업데이트하는 스크립트를 작성합니다.
예를 들어 Rails 콘솔에서 Check whether the commit author is a GitLab user와 Do not allow users to remove Git tags with git push 체크박스를 활성화하고,
특정 이메일 도메인의 커밋만 허용하는 필터를 만들려면 다음과 같이 합니다.
데이터를 변경하는 명령은 올바르게 실행하지 않거나 적절한 조건이 아닐 때 손상을 일으킬 수 있습니다. 항상 테스트 환경에서 먼저 실행하고 복원할 수 있는 백업 인스턴스를 준비합니다.
Project.find_each do |p|
pr = p.push_rule || PushRule.new(project: p)
# Check whether the commit author is a GitLab user
pr.member_check = true
# Do not allow users to remove Git tags with `git push`
pr.deny_delete_tag = true
# Commit author's email
pr.author_email_regex = '@domain\.com$'
pr.save!
end