Git 서버 훅

Tier: Free, Premium, Ultimate Offering: Self-managed
  • 서버 훅에서 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 명령어에 대한 접근이 없는 경우 서버 훅의 대안으로는 다음이 있습니다:

Geo는 서버 훅을 보조 노드에 복제하지 않습니다.

리포지토리에 대한 서버 훅 설정

GitLab 15.11 및 이후 버전
  • GitLab 15.11에서 도입된 hooks set 명령은 직접 파일 시스템 액세스를 대체합니다. 기존 Git 훅은 hooks set 명령을 위해 마이그레이션할 필요가 없습니다.

전제 조건:

  • 저장소 이름, Gitaly 구성 파일의 경로(리눅스 패키지 인스턴스의 기본값은 /var/opt/gitlab/gitaly/config.toml), 및 리포지토리에 대한 리포지토리 상대 경로.
  • 훅에 필요한 모든 언어 런타임 및 유틸리티는 Gitaly를 실행하는 각 서버에 설치되어 있어야 합니다.

리포지토리에 대한 서버 훅을 설정하려면:

  1. 사용자 정의 훅이 포함된 tarball을 생성합니다:
    1. 서버 훅이 기대한 대로 작동하도록 코드를 작성합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 언어 유형을 반영하는 셰뱅이 맨 위에 있어야 합니다. 예를 들어, 스크립트가 Ruby로 작성된 경우 셰뱅은 아마도 #!/usr/bin/env ruby일 것입니다.

      • 단일 서버 훅을 생성하려면, 훅 유형과 일치하는 이름의 파일을 생성합니다. 예를 들어, pre-receive 서버 훅의 경우 파일 이름은 확장자가 없는 pre-receive이어야 합니다.
      • 여러 서버 훅을 생성하려면, 훅 유형과 일치하는 훅을 위한 디렉토리를 생성합니다. 예를 들어, pre-receive 서버 훅의 경우 디렉토리 이름은 pre-receive.d이어야 합니다. 해당 디렉토리에 훅을 위한 파일을 넣습니다.
    2. 서버 훅 파일이 실행 가능하게 하고, 백업 파일 패턴(*~)과 일치하지 않도록 확인합니다. 서버 훅은 tarball의 루트에 있는 custom_hooks 디렉토리에 있어야 합니다.
    3. tar 명령어로 사용자 정의 훅 아카이브를 생성합니다. 예를 들어, tar -cf custom_hooks.tar custom_hooks입니다.
  2. 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>입니다.
  3. Gitaly 클러스터를 사용하는 경우, 모든 Gitaly 노드에서 hooks set 서브 커맨드를 실행해야 합니다. 자세한 내용은 Gitaly 클러스터의 서버 훅을 참조하세요.

서버 훅 코드를 올바르게 구현한 경우, 다음 Git 훅이 트리거될 때 실행되어야 합니다.

GitLab 15.10 및 이전 버전

리포지토리에 대한 서버 훅을 생성하려면:

  1. 왼쪽 사이드바에서 하단에 있는 Admin를 선택합니다.
  2. 개요 > 프로젝트로 이동하고 서버 훅을 추가할 프로젝트를 선택합니다.
  3. 표시되는 페이지에서 상대 경로의 값을 찾습니다. 이 경로가 서버 훅이 위치해야 할 곳입니다.
    • 해시 저장소를 사용하는 경우, 해시 저장소 경로 변환에 대한 정보를 참조하세요.
    • 해시 저장소를 사용하지 않는 경우:
      • 리눅스 패키지 설치의 경우 경로는 일반적으로 /var/opt/gitlab/git-data/repositories/<group>/<project>.git입니다.
      • 직접 컴파일한 설치의 경우 경로는 일반적으로 /home/git/repositories/<group>/<project>.git입니다.
  4. 파일 시스템에서 올바른 위치에 custom_hooks라는 새 디렉토리를 만듭니다.
  5. custom_hooks 디렉토리에서:
    • 단일 서버 훅을 만들려면 훅 유형과 일치하는 이름의 파일을 생성합니다. 예를 들어, pre-receive 서버 훅의 경우 파일 이름은 확장자가 없는 pre-receive여야 합니다.
    • 여러 서버 훅을 만들려면 훅 유형과 일치하는 훅을 위한 디렉토리를 만듭니다. 예를 들어, pre-receive 서버 훅의 경우 디렉토리 이름은 pre-receive.d여야 하며, 훅의 파일을 해당 디렉토리에 넣습니다.
  6. 서버 훅 파일을 실행 가능하게 만들고 Git 사용자에게 소유권이 있는지 확인합니다.
  7. 서버 훅이 기대대로 작동하도록 코드를 작성합니다. Git 서버 훅은 어떤 프로그래밍 언어로도 작성할 수 있습니다. 언어 유형을 반영하는 셰뱅이 맨 위에 있어야 합니다. 예를 들어, 스크립트가 Ruby로 작성된 경우 셰뱅은 아마도 #!/usr/bin/env ruby일 것입니다.
  8. 훅 파일이 백업 파일 패턴(*~)과 일치하지 않는지 확인합니다.
  9. Gitaly 클러스터를 사용하는 경우, 이 과정을 모든 Gitaly 노드에서 반복해야 합니다. 자세한 내용은 Gitaly 클러스터의 서버 훅을 참조하세요.

서버 훅 코드가 올바르게 구현되면, 다음 Git 훅이 트리거될 때 실행되어야 합니다.

Gitaly 클러스터에서의 서버 훅

Gitaly Cluster를 사용하는 경우, 개별 리포지토리는 Praefect의 여러 Gitaly 저장소에 복제될 수 있습니다.

결과적으로, 훅 스크립트는 리포지토리의 복사본을 가진 모든 Gitaly 노드에 복사되어야 합니다.

이를 수행하려면 해당 버전에 대한 사용자 정의 리포지토리 훅을 설정하는 동일한 단계를 따르고 각 저장소에 대해 반복합니다.

스크립트를 복사할 위치는 리포지토리가 저장된 위치에 따라 다릅니다:

모든 리포지토리를 위한 전역 서버 훅 생성

모든 리포지토리에 적용되는 Git 훅을 생성하려면 전역 서버 훅을 설정합니다. 전역 서버 훅은 다음에도 적용됩니다:

  • 프로젝트 및 그룹 위키 리포지토리. 이들의 저장소 디렉토리 이름은 <id>.wiki.git 형식입니다.

  • 프로젝트 내 디자인 관리 리포지토리. 이들의 저장소 디렉토리 이름은 <id>.design.git 형식입니다.

서버 훅 디렉토리 선택

전역 서버 훅을 생성하기 전에 디렉토리를 선택해야 합니다.

Linux 패키지 설치의 경우, 디렉토리는 gitlab.rbgitaly['configuration'][:hooks][:custom_hooks_dir] 아래에 설정됩니다. 다음 중 하나를 선택합니다:

  • 기본 제안인 /var/opt/gitlab/gitaly/custom_hooks 디렉토리를 주석 해제하여 사용합니다.

  • 자신만의 설정을 추가합니다.

자체 컴파일된 설치의 경우:

  • 디렉토리는 [hooks] 섹션의 gitaly/config.toml에 설정됩니다. 그러나 GitLab은 gitaly/config.toml의 값이 비어 있거나 존재하지 않을 경우 gitlab-shell/config.ymlcustom_hooks_dir 값을 존중합니다.

  • 기본 디렉토리는 /home/git/gitlab-shell/hooks입니다.

전역 서버 훅 생성

모든 리포지토리에 대한 전역 서버 훅을 생성하려면:

  1. GitLab 서버에서 설정된 전역 서버 훅 디렉토리로 이동합니다.

  2. 설정된 전역 서버 훅 디렉토리에서 훅 유형에 맞는 훅 디렉토리를 생성합니다. 예를 들어, pre-receive 서버 훅의 경우 디렉토리 이름은 pre-receive.d여야 합니다.

  3. 이 새 디렉토리 안에 서버 훅을 추가합니다. Git 서버 훅은 모든 프로그래밍 언어로 작성할 수 있습니다. 스크립트의 맨 위에 있는 셰뱅이 언어 유형을 반영하는지 확인합니다. 예를 들어, 스크립트가 Ruby로 작성된 경우 셰뱅은 아마도 #!/usr/bin/env ruby일 것입니다.

  4. 훅 파일을 실행 가능하게 만들고, Git 사용자 소유로 설정하며 백업 파일 패턴(*~)과 일치하지 않도록 합니다.

서버 훅 코드가 제대로 구현되었다면, Git 훅이 다음에 트리거될 때 실행되어야 합니다. 훅은 훅 유형 하위 디렉토리의 파일 이름에 따라 알파벳순으로 실행됩니다.

저장소에서 서버 훅 제거하기

GitLab 15.11 및 이후 버전
  • 도입됨 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>
GitLab 15.10 및 이전 버전

서버 훅을 제거하려면:

  1. 디스크에 있는 저장소의 위치로 이동합니다.
  2. 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-receivepost-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