github/platform-samples
리포지토리에서 GitHub Enterprise Server에 대한 사전 수신 후크의 예를 볼 수 있습니다.
사전 수신 후크 스크립트 작성
GitHub Enterprise Server 인스턴스의 사전 수신 후크 환경에서 사전 수신 후크 스크립트가 실행됩니다. 사전 수신 후크 스크립트를 만들 때 사용 가능한 입력, 출력, 종료 상태 및 환경 변수를 고려합니다.
입력(stdin
)
푸시가 발생하고 원격 리포지토리에 대한 참조가 업데이트되기 전에 GitHub Enterprise Server 인스턴스의 git-receive-pack
프로세스가 사전 수신 후크 스크립트를 호출합니다. 스크립트에 대한 표준 입력 stdin
은 업데이트할 각 참조에 대한 줄을 포함하는 문자열입니다. 각 줄에는 ref의 이전 개체 이름, ref의 새 개체 이름 및 ref의 전체 이름이 포함됩니다.
<old-value> SP <new-value> SP <ref-name> LF
이 문자열은 다음 인수를 나타냅니다.
인수 | 설명 |
---|---|
<old-value> | ref에 저장된 이전 개체 이름입니다. 새 ref를 만들 때 값은 40개의 0입니다. |
<new-value> | ref에 저장할 새 개체 이름입니다. ref를 삭제하면 값은 40개의 0입니다. |
<ref-name> | ref의 전체 이름입니다. |
git-receive-pack
에 대한 자세한 내용은 Git 설명서에서 "git-receive-pack"을 참조하세요. ref에 대한 자세한 내용은 _Pro Git_의 "Git 참조"를 참조하세요.
출력(stdout
)
스크립트에 대한 표준 출력 stdout
은 클라이언트에 다시 전달됩니다. 명령줄 또는 사용자 인터페이스에서 모든 echo
문이 사용자에게 표시됩니다.
종료 상태
사전 수신 스크립트의 종료 상태는 푸시가 수락되는지 여부를 결정합니다.
종료 상태 값 | 작업 |
---|---|
0 | 푸시가 수락됩니다. |
0이 아닌 값 | 푸시가 거부됩니다. |
환경 변수
사전 수신 후크 스크립트에 대한 표준 입력 stdin
외에도 GitHub Enterprise Server는 스크립트 실행을 위해 Bash 환경에서 다음 변수를 사용할 수 있도록 합니다. 사전 수신 후크 스크립트의 stdin
에 대한 자세한 내용은 "입력(stdin
)"을 참조하세요.
스크립트를 실행할 트리거에 따라 사전 수신 후크 스크립트에 다양한 환경 변수를 사용할 수 있습니다.
항상 사용 가능
다음 변수는 항상 사전 수신 후크 환경에서 사용할 수 있습니다.
변수 | 설명 | 예제 값 |
---|---|---|
$GIT_DIR | 인스턴스의 원격 리포지토리 경로 | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git |
$GIT_PUSH_OPTION_COUNT | --push-option 이 있는 클라이언트에서 보낸 푸시 옵션 수입니다. 자세한 내용은 Git 설명서의 “git-push”를 참조하세요. | 1 |
$GIT_PUSH_OPTION_N | N이 0부터 시작하는 정수인 경우 이 변수에는 클라이언트에서 보낸 푸시 옵션 문자열이 포함됩니다. 전송된 첫 번째 옵션은 GIT_PUSH_OPTION_0 에 저장되고, 전송된 두 번째 옵션은 GIT_PUSH_OPTION_1 에 저장되는 식입니다. 푸시 옵션에 대한 자세한 내용은 Git 설명서의 "git-push"를 참조하세요. | abcd |
$GIT_USER_AGENT | 변경 내용을 푸시한 Git 클라이언트에서 보낸 사용자 에이전트 문자열 | git/2.0.0 |
$GITHUB_REPO_NAME | NAME/OWNER 형식으로 업데이트되는 리포지토리의 이름 | octo-org/hello-enterprise |
$GITHUB_REPO_PUBLIC | 업데이트되는 리포지토리가 퍼블릭인지 여부를 나타내는 부울 |
|
$GITHUB_USER_IP | 푸시를 시작한 클라이언트의 IP 주소 | 192.0.2.1 |
$GITHUB_USER_LOGIN | 푸시를 시작한 계정의 사용자 이름 | octocat |
웹 인터페이스 또는 API의 푸시에 사용 가능
$GITHUB_VIA
변수는 웹 인터페이스 또는 GitHub Enterprise Server에 대한 API를 통해 후크를 트리거하는 ref 업데이트가 발생할 때 사전 수신 후크 환경에서 사용할 수 있습니다. 값은 ref를 업데이트한 작업을 설명합니다.
값 | 작업 | 자세한 정보 |
---|---|---|
auto-merge deployment api | API를 사용하여 만든 배포를 통해 기본 분기 자동 병합 | "배포에 대한 REST API 엔드포인트" |
blob#save | 웹 인터페이스에서 파일의 콘텐츠로 변경 | "파일 편집" |
branch merge api | API를 통해 분기 병합 | "분기 및 해당 설정에 대한 REST API 엔드포인트" |
branches page delete button | 웹 인터페이스에서 분기 삭제 | "리포지토리 내에서 분기 만들기 및 삭제" |
git refs create api | API를 통해 ref 만들기 | "Git 참조에 대한 REST API 엔드포인트" |
git refs delete api | API를 통해 ref 삭제 | "Git 참조에 대한 REST API 엔드포인트" |
git refs update api | API를 통한 ref 업데이트 | "Git 참조에 대한 REST API 엔드포인트" |
git repo contents api | API를 통해 파일의 콘텐츠로 변경 | "리포지토리 콘텐츠에 대한 REST API 엔드포인트" |
merge | 자동 병합을 사용하여 끌어오기 요청 병합 | "끌어오기 요청 자동 병합" |
merge base into head | 기본 분기에 엄격한 상태 검사가 필요한 경우(예: 끌어오기 요청의 업데이트 분기를 통해) 기본 분기에서 토픽 분기 업데이트 | "보호된 분기 정보" |
pull request branch delete button | 웹 인터페이스의 끌어오기 요청에서 토픽 분기 삭제 | "끌어오기 요청에서 분기 삭제 및 복원" |
pull request branch undo button | 웹 인터페이스의 끌어오기 요청에서 토픽 분기 복원 | "끌어오기 요청에서 분기 삭제 및 복원" |
pull request merge api | API를 통해 끌어오기 요청 병합 | "끌어오기 요청에 대한 REST API 엔드포인트" |
pull request merge button | 웹 인터페이스 끌어오기 요청 병합 | "끌어오기 요청 병합" |
pull request revert button | 끌어오기 요청 되돌리기 | "끌어오기 요청 되돌리기" |
releases delete button | 릴리스 삭제 | "리포지토리에서 릴리스 관리" |
stafftools branch restore | 사이트 관리자 대시보드에서 분기 복원 | "관리 웹 UI에서 인스턴스 등록" |
tag create api | API를 통해 태그 만들기 | "Git 태그에 대한 REST API 엔드포인트" |
web branch create | 웹 인터페이스를 통해 분기 만들기 | "리포지토리 내에서 분기 만들기 및 삭제" |
끌어오기 요청 병합에 사용 가능
다음 변수는 후크를 트리거하는 푸시가 끌어오기 요청의 병합으로 인한 푸시인 경우 사전 수신 후크 환경에서 사용할 수 있습니다.
변수 | 설명 | 예제 값 |
---|---|---|
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN | 끌어오기 요청을 작성한 계정의 사용자 이름 | octocat |
$GITHUB_PULL_REQUEST_HEAD | 끌어오기 요청 토픽 분기의 이름(USERNAME:BRANCH 형식) | octocat:fix-bug |
$GITHUB_PULL_REQUEST_BASE | 끌어오기 요청 기본 분기의 이름(USERNAME:BRANCH 형식) | octocat:main |
SSH 인증을 사용하여 푸시에 사용 가능
변수 | 설명 | 예제 값 |
---|---|---|
$GITHUB_PUBLIC_KEY_FINGERPRINT | 변경 내용을 푸시한 사용자의 퍼블릭 키 지문 | a1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6 |
권한 설정 및 GitHub Enterprise Server에 사전 수신 후크 푸시
GitHub Enterprise Server 인스턴스의 리포지토리에 사전 수신 후크 스크립트가 포함되어 있습니다. 사이트 관리자는 리포지토리 권한을 고려하고 적절한 사용자만 액세스할 수 있도록 해야 합니다.
후크를 단일 리포지토리에 통합하는 것이 좋습니다. 통합 후크 리포지토리가 퍼블릭인 경우 정책 적용을 설명하는 데 README.md
를 사용할 수 있습니다. 또한 끌어오기 요청을 통해 기여를 수락할 수 있습니다. 그러나 사전 수신 후크는 기본 분기에서만 추가할 수 있습니다. 테스트 워크플로의 경우 구성이 있는 리포지토리의 포크를 사용해야 합니다.
-
Mac 사용자의 경우 스크립트에 다음 실행 권한이 있는지 확인합니다.
sudo chmod +x SCRIPT_FILE.sh
Windows 사용자의 경우 스크립트에 다음 실행 권한이 있는지 확인합니다.
git update-index --chmod=+x SCRIPT_FILE.sh
-
GitHub Enterprise Server 인스턴스에서 사전 수신 후크를 위해 지정된 리포지토리에 커밋하고 푸시합니다.
git commit -m "YOUR COMMIT MESSAGE" git push
-
GitHub Enterprise Server 인스턴스에 사전 수신 후크를 만듭니다.
로컬에서 사전 수신 스크립트 테스트
GitHub Enterprise Server 인스턴스에서 만들거나 업데이트하기 전에 사전 수신 후크 스크립트를 로컬에서 테스트할 수 있습니다. 한 가지 방법은 사전 수신 후크를 실행할 수 있는 원격 리포지토리 역할을 하는 로컬 Docker 환경을 만드는 것입니다.
-
로컬에 Docker가 설치되어 있는지 확인합니다.
-
다음을 포함하는
Dockerfile.dev
라는 파일을 만듭니다.FROM alpine:latest RUN \ apk add --no-cache git openssh bash && \ ssh-keygen -A && \ sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && \ adduser git -D -G root -h /home/git -s /bin/bash && \ passwd -d git && \ su git -c "mkdir /home/git/.ssh && \ ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P '' && \ mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && \ mkdir /home/git/test.git && \ git --bare init /home/git/test.git" VOLUME ["/home/git/.ssh", "/home/git/test.git/hooks"] WORKDIR /home/git CMD ["/usr/sbin/sshd", "-D"]
-
always_reject.sh
라는 테스트 사전 수신 스크립트를 만듭니다. 이 예제 스크립트는 리포지토리를 잠그는 데 유용한 모든 푸시를 거부합니다.#!/usr/bin/env bash echo "error: rejecting all pushes" exit 1
-
always_reject.sh
스크립트에 실행 권한이 있는지 확인합니다.chmod +x always_reject.sh
-
Dockerfile.dev
를 포함하는 디렉터리에서 이미지를 빌드합니다.$ docker build -f Dockerfile.dev -t pre-receive.dev . [+] Building 4.5s (8/8) FINISHED => [internal] load build definition from Dockerfile.dev 0.0s => => transferring dockerfile: 641B 0.0s => [internal] load .dockerignore 0.0s => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/alpine:latest 1.9s => [auth] library/alpine:pull token for registry-1.docker.io 0.0s => [1/3] FROM docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 0.0s => => resolve docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 0.0s => => sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 1.64kB / 1.64kB 0.0s => => sha256:25fad2a32ad1f6f510e528448ae1ec69a28ef81916a004d3629874104f8a7f70 528B / 528B 0.0s => => sha256:c1aabb73d2339c5ebaa3681de2e9d9c18d57485045a4e311d9f8004bec208d67 1.47kB / 1.47kB 0.0s => [2/3] RUN apk add --no-cache git openssh bash && ssh-keygen -A && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /e 2.3s => [3/3] WORKDIR /home/git 0.0s => exporting to image 0.1s => => exporting layers 0.1s => => writing image sha256:938447846e19a4328a85883fbd1ccf5eb919d97448cc7256efebf403d8b5a196 0.0s => => naming to docker.io/library/pre-receive.dev
-
생성된 SSH 키가 포함된 데이터 컨테이너를 실행합니다.
docker run --name data pre-receive.dev /bin/true
-
테스트 사전 수신 후크
always_reject.sh
를 데이터 컨테이너에 복사합니다.docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
-
sshd
및 후크를 실행하는 애플리케이션 컨테이너를 실행합니다. 반환되는 컨테이너 ID를 기록해 둡니다.$ docker run -d -p 52311:22 --volumes-from data pre-receive.dev > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
-
생성된 SSH 키를 데이터 컨테이너에서 로컬 컴퓨터로 복사합니다.
docker cp data:/home/git/.ssh/id_ed25519 .
-
테스트 리포지토리의 원격을 수정하고 Docker 컨테이너 내의
test.git
리포지토리로 푸시합니다. 이 예제에서는git@github.com:octocat/Hello-World.git
을 사용하지만 원하는 리포지토리를 사용할 수 있습니다. 이 예제에서는 로컬 컴퓨터(127.0.0.1)가 포트 52311을 바인딩하는 것으로 가정하지만, docker가 원격 머신에서 실행되는 경우 다른 IP 주소를 사용할 수 있습니다.$ git clone git@github.com:octocat/Hello-World.git $ cd Hello-World $ git remote add test git@127.0.0.1:test.git $ GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 52311 -i ../id_ed25519" git push -u test master > Warning: Permanently added '[127.0.0.1]:52311' (ECDSA) to the list of known hosts. > Counting objects: 7, done. > Delta compression using up to 4 threads. > Compressing objects: 100% (3/3), done. > Writing objects: 100% (7/7), 700 bytes | 0 bytes/s, done. > Total 7 (delta 0), reused 7 (delta 0) > remote: error: rejecting all pushes > To git@127.0.0.1:test.git > ! [remote rejected] master -> master (pre-receive hook declined) > error: failed to push some refs to 'git@192.168.99.100:test.git'
사전 수신 후크를 실행하고 스크립트의 출력을 에코한 후 푸시가 거부되었습니다.
추가 참고 자료
- Pro Git 웹 사이트의 “Git 사용자 지정 - Git 적용 정책 예제”