Git 서버 훅
- 서버 훅에서 Git 서버 훅으로 이름이 변경되었습니다. GitLab 15.6.
Git 서버 훅( system hooks 또는 file hooks와 혼동하지 마세요)은 GitLab 서버에서 사용자 정의 로직을 실행합니다. 이 훅을 사용하여 다음과 같은 Git 관련 작업을 수행할 수 있습니다:
- 특정 커밋 정책을 시행합니다.
- 리포지토리 상태에 따라 작업을 수행합니다.
Git 서버 훅은 pre-receive
, post-receive
, 그리고 update
서버 측 Git 훅을 사용합니다.
GitLab 관리자는 gitaly
명령어를 사용하여 서버 훅을 구성하며, 이 명령어는 또한:
- Gitaly 서버를 시작하는 데 사용됩니다.
- 여러 서브 커맨드를 제공합니다.
- Gitaly gRPC API에 연결합니다.
gitaly
명령어에 대한 접근이 없는 경우 서버 훅의 대안으로는 다음이 있습니다:
- Webhooks.
- GitLab CI/CD.
- 사용자 구성 가능한 Git 훅 인터페이스를 위한 Push rules.
Geo는 서버 훅을 보조 노드에 복제하지 않습니다.
리포지토리에 대한 서버 훅 설정
- GitLab 15.11에서 도입된
hooks set
명령은 직접 파일 시스템 액세스를 대체합니다. 기존 Git 훅은hooks set
명령을 위해 마이그레이션할 필요가 없습니다.
전제 조건:
-
저장소 이름, Gitaly 구성 파일의 경로(리눅스 패키지 인스턴스의 기본값은
/var/opt/gitlab/gitaly/config.toml
), 및 리포지토리에 대한 리포지토리 상대 경로. - 훅에 필요한 모든 언어 런타임 및 유틸리티는 Gitaly를 실행하는 각 서버에 설치되어 있어야 합니다.
리포지토리에 대한 서버 훅을 설정하려면:
- 사용자 정의 훅이 포함된 tarball을 생성합니다:
-
서버 훅이 기대한 대로 작동하도록 코드를 작성합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 언어 유형을 반영하는 셰뱅이 맨 위에 있어야 합니다. 예를 들어, 스크립트가 Ruby로 작성된 경우 셰뱅은 아마도
#!/usr/bin/env ruby
일 것입니다.- 단일 서버 훅을 생성하려면, 훅 유형과 일치하는 이름의 파일을 생성합니다. 예를 들어,
pre-receive
서버 훅의 경우 파일 이름은 확장자가 없는pre-receive
이어야 합니다. - 여러 서버 훅을 생성하려면, 훅 유형과 일치하는 훅을 위한 디렉토리를 생성합니다. 예를 들어,
pre-receive
서버 훅의 경우 디렉토리 이름은pre-receive.d
이어야 합니다. 해당 디렉토리에 훅을 위한 파일을 넣습니다.
- 단일 서버 훅을 생성하려면, 훅 유형과 일치하는 이름의 파일을 생성합니다. 예를 들어,
- 서버 훅 파일이 실행 가능하게 하고, 백업 파일 패턴(
*~
)과 일치하지 않도록 확인합니다. 서버 훅은 tarball의 루트에 있는custom_hooks
디렉토리에 있어야 합니다. - tar 명령어로 사용자 정의 훅 아카이브를 생성합니다. 예를 들어,
tar -cf custom_hooks.tar custom_hooks
입니다.
-
-
hooks set
서브 커맨드를 필수 옵션과 함께 실행하여 리포지토리에 대한 Git 훅을 설정합니다. 예를 들어,cat custom_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
.- 노드에 연결하는 유효한 Gitaly 구성에 대한 경로가 필요하며
--config
플래그에 제공됩니다. - 사용자 정의 훅 tarball은
stdin
을 통해 전달되어야 합니다. 예를 들어,cat custom_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
입니다.
- 노드에 연결하는 유효한 Gitaly 구성에 대한 경로가 필요하며
- Gitaly 클러스터를 사용하는 경우, 모든 Gitaly 노드에서
hooks set
서브 커맨드를 실행해야 합니다. 자세한 내용은 Gitaly 클러스터의 서버 훅을 참조하세요.
서버 훅 코드를 올바르게 구현한 경우, 다음 Git 훅이 트리거될 때 실행되어야 합니다.
리포지토리에 대한 서버 훅을 생성하려면:
- 왼쪽 사이드바에서 하단에 있는 Admin를 선택합니다.
- 개요 > 프로젝트로 이동하고 서버 훅을 추가할 프로젝트를 선택합니다.
- 표시되는 페이지에서 상대 경로의 값을 찾습니다. 이 경로가 서버 훅이 위치해야 할 곳입니다.
- 해시 저장소를 사용하는 경우, 해시 저장소 경로 변환에 대한 정보를 참조하세요.
-
해시 저장소를 사용하지 않는 경우:
- 리눅스 패키지 설치의 경우 경로는 일반적으로
/var/opt/gitlab/git-data/repositories/<group>/<project>.git
입니다. - 직접 컴파일한 설치의 경우 경로는 일반적으로
/home/git/repositories/<group>/<project>.git
입니다.
- 리눅스 패키지 설치의 경우 경로는 일반적으로
- 파일 시스템에서 올바른 위치에
custom_hooks
라는 새 디렉토리를 만듭니다. - 새
custom_hooks
디렉토리에서:- 단일 서버 훅을 만들려면 훅 유형과 일치하는 이름의 파일을 생성합니다. 예를 들어,
pre-receive
서버 훅의 경우 파일 이름은 확장자가 없는pre-receive
여야 합니다. - 여러 서버 훅을 만들려면 훅 유형과 일치하는 훅을 위한 디렉토리를 만듭니다. 예를 들어,
pre-receive
서버 훅의 경우 디렉토리 이름은pre-receive.d
여야 하며, 훅의 파일을 해당 디렉토리에 넣습니다.
- 단일 서버 훅을 만들려면 훅 유형과 일치하는 이름의 파일을 생성합니다. 예를 들어,
- 서버 훅 파일을 실행 가능하게 만들고 Git 사용자에게 소유권이 있는지 확인합니다.
- 서버 훅이 기대대로 작동하도록 코드를 작성합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 언어 유형을 반영하는 셰뱅이 맨 위에 있어야 합니다. 예를 들어, 스크립트가 Ruby로 작성된 경우 셰뱅은 아마도
#!/usr/bin/env ruby
일 것입니다. - 훅 파일이 백업 파일 패턴(
*~
)과 일치하지 않는지 확인합니다. - Gitaly 클러스터를 사용하는 경우, 이 과정을 모든 Gitaly 노드에서 반복해야 합니다. 자세한 내용은 Gitaly 클러스터의 서버 훅을 참조하세요.
서버 훅 코드가 올바르게 구현되면, 다음 Git 훅이 트리거될 때 실행되어야 합니다.
Gitaly 클러스터에서의 서버 훅
Gitaly Cluster를 사용하는 경우, 개별 리포지토리는 Praefect의 여러 Gitaly 저장소에 복제될 수 있습니다.
결과적으로, 훅 스크립트는 리포지토리의 복사본을 가진 모든 Gitaly 노드에 복사되어야 합니다.
이를 수행하려면 해당 버전에 대한 사용자 정의 리포지토리 훅을 설정하는 동일한 단계를 따르고 각 저장소에 대해 반복합니다.
스크립트를 복사할 위치는 리포지토리가 저장된 위치에 따라 다릅니다:
-
GitLab 15.2 및 이전 버전에서는 Gitaly Cluster가 GitLab 애플리케이션에서 보고하는 해시된 저장소 경로를 사용합니다.
-
GitLab 15.3 및 이후 버전에서는 새로운 리포지토리가 Praefect 생성 복제 경로를 사용하여 생성되며, 이는 해시된 저장소 경로가 아닙니다. 복제 경로는
-relative-path
를 사용하여 예상 GitLab 해시된 저장소 경로를 지정해 Praefect 리포지토리 메타데이터를 쿼리하여 식별할 수 있습니다.
모든 리포지토리를 위한 전역 서버 훅 생성
모든 리포지토리에 적용되는 Git 훅을 생성하려면 전역 서버 훅을 설정합니다. 전역 서버 훅은 다음에도 적용됩니다:
-
프로젝트 및 그룹 위키 리포지토리. 이들의 저장소 디렉토리 이름은
<id>.wiki.git
형식입니다. -
프로젝트 내 디자인 관리 리포지토리. 이들의 저장소 디렉토리 이름은
<id>.design.git
형식입니다.
서버 훅 디렉토리 선택
전역 서버 훅을 생성하기 전에 디렉토리를 선택해야 합니다.
Linux 패키지 설치의 경우, 디렉토리는 gitlab.rb
의 gitaly['configuration'][:hooks][:custom_hooks_dir]
아래에 설정됩니다. 다음 중 하나를 선택합니다:
-
기본 제안인
/var/opt/gitlab/gitaly/custom_hooks
디렉토리를 주석 해제하여 사용합니다. -
자신만의 설정을 추가합니다.
자체 컴파일된 설치의 경우:
-
디렉토리는
[hooks]
섹션의gitaly/config.toml
에 설정됩니다. 그러나 GitLab은gitaly/config.toml
의 값이 비어 있거나 존재하지 않을 경우gitlab-shell/config.yml
의custom_hooks_dir
값을 존중합니다. -
기본 디렉토리는
/home/git/gitlab-shell/hooks
입니다.
전역 서버 훅 생성
모든 리포지토리에 대한 전역 서버 훅을 생성하려면:
-
GitLab 서버에서 설정된 전역 서버 훅 디렉토리로 이동합니다.
-
설정된 전역 서버 훅 디렉토리에서 훅 유형에 맞는 훅 디렉토리를 생성합니다. 예를 들어,
pre-receive
서버 훅의 경우 디렉토리 이름은pre-receive.d
여야 합니다. -
이 새 디렉토리 안에 서버 훅을 추가합니다. Git 서버 훅은 모든 프로그래밍 언어로 작성할 수 있습니다. 스크립트의 맨 위에 있는 셰뱅이 언어 유형을 반영하는지 확인합니다. 예를 들어, 스크립트가 Ruby로 작성된 경우 셰뱅은 아마도
#!/usr/bin/env ruby
일 것입니다. -
훅 파일을 실행 가능하게 만들고, Git 사용자 소유로 설정하며 백업 파일 패턴(
*~
)과 일치하지 않도록 합니다.
서버 훅 코드가 제대로 구현되었다면, Git 훅이 다음에 트리거될 때 실행되어야 합니다. 훅은 훅 유형 하위 디렉토리의 파일 이름에 따라 알파벳순으로 실행됩니다.
저장소에서 서버 훅 제거하기
- 도입됨 GitLab 15.11에서,
hooks set
명령어는 파일 시스템에 직접 접근하는 것을 대체합니다.
사전 요구 사항:
- 저장소에 대한 저장소 이름 및 상대 경로.
서버 훅을 제거하려면, hook set
에 빈 tarball을 전달하여 저장소에 훅이 없도록 해야 합니다. 예를 들어:
cat empty_hooks.tar | sudo -u git -- /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>
서버 훅을 제거하려면:
- 디스크에 있는 저장소의 위치로 이동합니다.
-
custom_hooks
디렉터리에서 서버 훅을 삭제합니다.
연결된 서버 훅
GitLab은 서버 훅을 체인 방식으로 실행할 수 있습니다. GitLab은 다음 순서로 서버 훅을 검색하고 실행합니다:
- 내장된 GitLab 서버 훅. 이 서버 훅은 사용자가 사용자 정의할 수 없습니다.
-
<project>.git/custom_hooks/<hook_name>
: 프로젝트별 훅. 이 위치는 이전 호환성을 위해 유지됩니다. -
<project>.git/custom_hooks/<hook_name>.d/*
: 프로젝트별 훅을 위한 위치입니다. -
<custom_hooks_dir>/<hook_name>.d/*
: 편집기 백업 파일을 제외한 모든 실행 가능한 글로벌 훅 파일의 위치입니다.
서버 훅 디렉터리 내에서, 훅은:
- 알파벳 순서대로 실행됩니다.
- 훅이 비제로 값으로 종료되면 실행이 중지됩니다.
서버 훅에 제공되는 환경 변수
모든 환경 변수를 서버 훅에 전달할 수 있지만, 지원되는 환경 변수에만 의존해야 합니다.
모든 서버 훅에 대해 지원되는 GitLab 환경 변수는 다음과 같습니다:
환경 변수 | 설명 |
---|---|
GL_ID |
푸시를 시작한 사용자 또는 SSH 키의 GitLab 식별자입니다. 예: user-2234 또는 key-4 . |
GL_PROJECT_PATH |
GitLab 프로젝트 경로입니다. |
GL_PROTOCOL |
이 변경에 사용된 프로토콜입니다. 다음 중 하나: http (HTTP를 사용한 Git push ), ssh (SSH를 사용한 Git push ), 또는 web (모든 기타 작업). |
GL_REPOSITORY |
project-<id> 여기서 id 는 프로젝트의 ID입니다. |
GL_USERNAME |
푸시를 시작한 사용자의 GitLab 사용자 이름입니다. |
pre-receive
및 post-receive
서버 훅에 대해 지원되는 Git 환경 변수는 다음과 같습니다:
환경 변수 | 설명 |
---|---|
GIT_ALTERNATE_OBJECT_DIRECTORIES |
격리 환경에서의 대체 객체 디렉터리입니다. Git receive-pack 문서를 참조하십시오. |
GIT_OBJECT_DIRECTORY |
격리 환경에서의 GitLab 프로젝트 경로입니다. Git receive-pack 문서를 참조하십시오. |
GIT_PUSH_OPTION_COUNT |
푸시 옵션의 수입니다. Git pre-receive 문서를 참조하십시오. |
GIT_PUSH_OPTION_<i> |
0 에서 GIT_PUSH_OPTION_COUNT - 1 까지의 푸시 옵션의 값입니다. Git pre-receive 문서를 참조하십시오. |
사용자 정의 오류 메시지
커밋이 거부되거나 Git 훅에서 오류가 발생할 때 GitLab UI에 사용자 정의 오류 메시지를 표시할 수 있습니다. 사용자 정의 오류 메시지를 표시하려면 스크립트에서 다음을 수행해야 합니다:
-
사용자 정의 오류 메시지를 스크립트의
stdout
또는stderr
로 전송합니다. -
각 메시지를
GL-HOOK-ERR:
로 접두어를 붙이고, 접두어 앞에 다른 문자가 나타나지 않도록 합니다.
예를 들어:
#!/bin/sh
echo "GL-HOOK-ERR: 나의 사용자 정의 오류 메시지.";
exit 1