Git 서버 훅

Tier: Free, Premium, Ultimate Offering: Self-Managed
  • GitLab 12.8에서 사용이 시작되어 사용자 정의 훅을 대체했습니다.
  • GitLab 15.6에서 서버 훅을 Git 서버 훅으로 이름이 변경되었습니다.

Git 서버 훅(시스템 훅(system hooks)[(system_hooks.md)]이나 파일 훅(file hooks)[(file_hooks.md)]과 혼동하면 안 됨)은 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 명령을 위해 마이그레이션될 필요가 없습니다.

필수 조건:

저장소에 서버 훅을 설정하려면:

  1. 사용자 정의 훅이 포함된 tar 볼 생성:
    1. 서버 훅이 기대한 대로 작동하도록 코드를 작성합니다. Git 서버 훅은 모든 프로그래밍 언어로 작성할 수 있습니다. 해쉬방이 예상한 언어 유형을 반영하도록 합니다. 예를 들어, 스크립트가 루비인 경우 해쉬방은 아마도 #!/usr/bin/env ruby일 것입니다.

      • 단일 서버 훅을 만들려면 훅 유형과 일치하는 이름의 파일을 만듭니다. 예를 들어 pre-receive 서버 훅의 경우 파일 이름은 확장자 없이 pre-receive여야 합니다.
      • 여러 서버 훅을 만들려면 훅 유형과 일치하는 디렉터리를 만듭니다. 예를 들어 pre-receive 서버 훅의 경우 디렉터리 이름은 pre-receive.d여야 합니다. 해당 디렉터리에 훅 파일을 넣습니다.
    2. 서버 훅 파일이 실행 가능하고 백업 파일 패턴(*~)과 일치하지 않도록 합니다. 서버 훅은 tar 볼의 루트에 있는 custom_hooks 디렉터리에 있어야 합니다.
    3. tar 명령으로 사용자 정의 훅 아카이브를 만듭니다. 예를 들어, tar -cf custom_hooks.tar로 사용자 정의 훅을 만듭니다.
  2. hooks set 하위 명령을 필요한 옵션과 함께 실행하여 저장소에 Git 훅을 설정합니다. 예를 들어, cat custom_hooks.tar | sudo /opt/gitlab/embedded/bin/gitaly hooks set --storage <storage> --repository <relative path> --config <config path>와 같이 실행합니다.

    • 노드에 연결하기 위해 유효한 Gitaly 구성 파일 경로가 --config 플래그로 제공되어야 합니다.
    • 사용자 정의 훅 tar 볼이 stdin을 통해 전달되어야 합니다. 예를 들어, cat custom_hooks.tar | sudo /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 Area)을 선택합니다.
  2. 개요 > 프로젝트(Overview > Projects)로 이동하여 서버 훅을 추가하려는 프로젝트를 선택합니다.
  3. 나타나는 페이지에서 상대 경로(Relative path) 값을 찾습니다. 이 경로가 서버 훅이 위치해야 하는 곳입니다.
    • 해시된 저장을 사용하는 경우 해시된 저장 경로 번역(Translate hashed storage paths)을 참조하여 상대 경로를 해석하는 정보를 확인합니다.
    • 해시된 저장을 사용하지 않는 경우:
      • 리눅스 패키지 설치의 경우 경로는 일반적으로 /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 서버 훅은 모든 프로그래밍 언어로 작성할 수 있습니다. 스크립트가 루비인 경우 해쉬방이 아마도 #!/usr/bin/env ruby임을 확인합니다.
  8. 훅 파일이 백업 파일 패턴(*~)과 일치하지 않도록 확인합니다.
  9. Gitaly 클러스터를 사용하는 경우, 모든 Gitaly 노드에서이 프로세스를 반복해야 합니다. 자세한 내용은 Gitaly 클러스터의 서버 훅을 참조하세요.

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

Gitaly 클러스터의 서버 후크

만약 Gitaly 클러스터를 사용한다면, 개별 저장소는 Praefact 내의 여러 Gitaly 저장소로 복제될 수 있습니다. 결과적으로 후크 스크립트는 해당 저장소의 복제본을 가지고 있는 모든 Gitaly 노드로 복사되어야 합니다. 이를 위해 해당 버전에 맞는 사용자 지정 저장소 후크 설정을 위해 동일한 단계를 따르고 각 저장소에 대해 반복하면 됩니다.

스크립트를 복사할 위치는 저장소가 저장되는 위치에 달려 있습니다:

모든 저장소에 대한 전역 서버 후크 생성

모든 저장소에 적용되는 Git 후크를 만들려면 전역 서버 후크를 설정하세요. 전역 서버 후크는 또한 다음에도 적용됩니다:

  • 프로젝트 및 그룹 위키 저장소. 그들의 저장소 디렉토리 이름은 다음 형식을 따릅니다 <id>.wiki.git.
  • 프로젝트 아래의 디자인 관리 저장소. 그들의 저장소 디렉토리 이름은 다음 형식을 따릅니다 <id>.design.git.

서버 후크 디렉토리 선택

전역 서버 후크를 만들기 전에 해당 후크를 위한 디렉토리를 선택해야 합니다.

Linux 패키지 설치의 경우, 디렉토리는 gitlab.rb에서 gitaly['configuration'][:hooks][:custom_hooks_dir]로 설정됩니다. 다음 중 하나를 선택할 수 있습니다:

  • 기본 제안인 /var/opt/gitlab/gitaly/custom_hooks 디렉토리를 주석 처리 해제하여 사용합니다.
  • 나만의 설정을 추가하세요.

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

  • 디렉토리는 설정 파일에서 설정됩니다. 설정 파일의 위치는 GitLab 버전에 따라 다릅니다:
    • GitLab 13.1 이후 버전에 대해, 디렉토리는 [hooks] 섹션에서 gitaly/config.toml에 설정됩니다. 그러나, gitaly/config.toml의 값이 공백이거나 존재하지 않으면 GitLab은 gitlab-shell/config.ymlcustom_hooks_dir 값을 적용합니다.
    • GitLab 13.0 이전 버전에 대해, 디렉토리는 gitlab-shell/config.yml에 설정됩니다.
  • 기본 디렉토리는 /home/git/gitlab-shell/hooks 입니다.

전역 서버 후크 생성

모든 저장소에 대한 전역 서버 후크를 만들려면:

  1. GitLab 서버에서 구성된 전역 서버 후크 디렉토리로 이동합니다.
  2. 구성된 전역 서버 후크 디렉토리에서, 후크 유형과 일치하는 후크용 디렉토리를 생성합니다. 예를 들어 pre-receive 서버 후크의 경우 디렉토리 이름은 pre-receive.d여야 합니다.
  3. 이 새로운 디렉토리 안에 서버 후크를 추가하세요. Git 서버 후크는 모든 프로그래밍 언어로 작성될 수 있습니다. 상단에 있는 shebang가 언어 유형을 반영하도록 하세요. 예를 들어, 스크립트가 루비 언어로 되어 있다면 shebang는 아마도 #!/usr/bin/env ruby일 것입니다.
  4. 후크 파일을 실행 가능한 상태로 만들고, Git 사용자의 소유인지 확인하고, 백업 파일 패턴(*~)과 일치하지 않도록 확인하세요.

만약 서버 후크 코드가 올바르게 구현되었다면, 다음으로 트리거된 경우 Git 후크가 실행되어야 합니다. 서버 후크는 후크 유형 하위 디렉토리의 파일 이름에 따라 알파벳 순으로 실행됩니다.

저장소에 대한 서버 후크 제거

GitLab 15.11 이후
  • GitLab 15.11에서 소개, hooks set 명령어는 직접 파일 시스템 접근을 대체합니다.

전제 조건:

서버 후크를 제거하려면, 빈 tarball을 hooks set에 전달하여 저장소에 후크가 없어야 함을 나타내세요. 예를 들어:

cat empty_hooks.tar | sudo /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 13.2 이상) GitLab 프로젝트 경로.
GL_PROTOCOL (GitLab 13.2 이상) 이 변경에 사용된 프로토콜. 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 push 옵션의 수. Git pre-receive 문서 참조.
GIT_PUSH_OPTION_<i> i0부터 GIT_PUSH_OPTION_COUNT - 1까지인 push 옵션의 값. Git pre-receive 문서 참조.

사용자 정의 오류 메시지

커밋이 거부되거나 Git 후크 실행 중에 오류가 발생할 때 GitLab UI에 사용자 정의 오류 메시지를 표시할 수 있습니다. 사용자 정의 오류 메시지를 표시하려면 스크립트는 다음과 같아야 합니다:

  • 사용자 정의 오류 메시지를 스크립트의 stdout 또는 stderr에 보냅니다.
  • 각 메시지 앞에 GL-HOOK-ERR:을 붙입니다. 해당 접두사 앞에 문자가 나타나지 않아야 합니다.

예를 들어:

#!/bin/sh
echo "GL-HOOK-ERR: 나만의 커스텀 에러 메시지.";
exit 1