소개
웹훅 (Webhook) 통합을 사용하면 소스 제어 시스템이 리포지토리 변경 사항을 Jenkins 에 알릴 수 있습니다. 실제 GitHub 나 GitLab 웹훅은 Jenkins 로 HTTP 요청을 보냅니다. 안정적인 실습을 위해 외부 서비스에 의존하는 대신 curl을 사용하여 해당 요청을 로컬에서 시뮬레이션합니다.
이번 실습에서는 로컬 Git 리포지토리를 생성하고, 웹훅 스타일의 브랜치 및 커밋 매개변수를 허용하는 Jenkins 프리스타일 작업을 구성한 뒤, 로컬 웹훅 요청을 보내고 트리거된 빌드 로그를 검사합니다.
로컬 소스 리포지토리 준비
이 단계에서는 소스 제어 시스템 역할을 할 작은 Git 리포지토리를 생성합니다. 웹훅은 일반적으로 변경된 브랜치와 커밋 정보를 포함하므로, 이후 단계를 위해 해당 값들을 저장해 둡니다.
git init -b main 명령어는 main 브랜치를 가진 리포지토리를 생성합니다. git config 명령어는 작성자 정보를 설정하여 프롬프트 없이 커밋을 생성할 수 있도록 합니다.
cd /home/labex/project
mkdir -p webhook-repo
cd webhook-repo
git init -b main
git config user.email "labex@example.com"
git config user.name "LabEx Webhook"
파일을 생성하고 커밋합니다:
echo "webhook demo build" > app.txt
git add app.txt
git commit -m "Add webhook demo app"
브랜치와 짧은 커밋 ID 를 환경 파일에 저장합니다. tee 명령어는 값을 파일에 기록함과 동시에 출력하여 확인할 수 있게 해줍니다.
COMMIT=$(git rev-parse --short=12 HEAD)
BRANCH=$(git branch --show-current)
printf 'WEBHOOK_BRANCH=%s\nWEBHOOK_COMMIT=%s\n' "$BRANCH" "$COMMIT" | tee /home/labex/project/webhook-values.env
출력 결과는 다음과 비슷해야 합니다:
WEBHOOK_BRANCH=main
WEBHOOK_COMMIT=...
Jenkins 작업은 Jenkins Docker 컨테이너 내부에서 실행됩니다. 빌드 프로세스가 컨테이너 내부에서 리포지토리를 읽을 수 있도록 /var/jenkins_home/webhook-repo로 복사합니다:
docker exec jenkins rm -rf /var/jenkins_home/webhook-repo
docker cp /home/labex/project/webhook-repo jenkins:/var/jenkins_home/webhook-repo
docker exec -u root jenkins chown -R jenkins:jenkins /var/jenkins_home/webhook-repo
매개변수화된 Jenkins 작업 생성
이 단계에서는 webhook-trigger-demo라는 이름의 Jenkins 프리스타일 작업을 생성합니다. 이 작업은 WEBHOOK_BRANCH와 WEBHOOK_COMMIT이라는 두 개의 문자열 매개변수를 허용합니다. 이는 소스 제어 웹훅이 전송하는 중요한 데이터를 반영합니다.
Jenkins 작업 구성 XML 을 생성합니다. 작업 내의 셸 명령어는 브랜치와 커밋을 출력한 다음, 로컬 Git 리포지토리에 해당 커밋이 존재하는지 확인합니다.
cat > /home/labex/project/webhook-trigger-demo-config.xml <<'XML'
<?xml version='1.1' encoding='UTF-8'?>
<project>
<actions/>
<description>Build triggered by a local webhook payload.</description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
<hudson.model.StringParameterDefinition>
<name>WEBHOOK_BRANCH</name>
<description>Branch name from the webhook payload.</description>
<defaultValue>main</defaultValue>
<trim>true</trim>
</hudson.model.StringParameterDefinition>
<hudson.model.StringParameterDefinition>
<name>WEBHOOK_COMMIT</name>
<description>Commit id from the webhook payload.</description>
<defaultValue></defaultValue>
<trim>true</trim>
</hudson.model.StringParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
</properties>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>set -e
echo "Webhook branch: $WEBHOOK_BRANCH"
echo "Webhook commit: $WEBHOOK_COMMIT"
echo "Source repository: /var/jenkins_home/webhook-repo"
git -C /var/jenkins_home/webhook-repo rev-parse --verify "$WEBHOOK_COMMIT^{commit}"
git -C /var/jenkins_home/webhook-repo show --no-patch --format='Commit subject: %s' "$WEBHOOK_COMMIT"</command>
<configuredLocalRules/>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
XML
작업을 Jenkins 로 복사하고 설정 과정에서 생성된 헬퍼 스크립트를 사용하여 컨트롤러를 다시 로드합니다:
docker exec jenkins mkdir -p /var/jenkins_home/jobs/webhook-trigger-demo
docker cp /home/labex/project/webhook-trigger-demo-config.xml jenkins:/var/jenkins_home/jobs/webhook-trigger-demo/config.xml
/home/labex/project/reload-jenkins.sh
Jenkins 에서 작업이 보이는지 확인합니다:
curl -fsS http://localhost:8080/job/webhook-trigger-demo/api/json | grep -o '"name":"webhook-trigger-demo"'
예상 출력 결과는 다음과 같습니다:
"name":"webhook-trigger-demo"
웹훅 페이로드 파일 생성
이 단계에서는 작은 소스 제어 웹훅 페이로드처럼 보이는 JSON 파일을 생성합니다. 실제 웹훅 페이로드에는 많은 필드가 포함되어 있지만, 이 실습에서는 빌드에 필요한 필드인 브랜치용 ref와 커밋 ID 용 after만 유지합니다.
저장된 브랜치와 커밋 값을 불러온 뒤 JSON 페이로드를 작성합니다:
cd /home/labex/project
source webhook-values.env
cat > local-webhook-payload.json <<JSON
{
"ref": "refs/heads/${WEBHOOK_BRANCH}",
"after": "${WEBHOOK_COMMIT}",
"repository": {
"full_name": "labex/webhook-demo"
}
}
JSON
Python 의 JSON 포맷터를 사용하여 파일이 유효하고 읽을 수 있는지 확인합니다:
python3 -m json.tool /home/labex/project/local-webhook-payload.json
refs/heads/main 브랜치 참조와 Git 리포지토리의 커밋 ID 가 보여야 합니다.
curl 을 사용하여 웹훅 요청 보내기
이 단계에서는 웹훅 전달을 시뮬레이션합니다. Jenkins 는 POST 요청을 보호하기 위해 Crumb 토큰을 사용하므로, 먼저 Crumb 을 요청하여 일치하는 쿠키 저장소에 저장합니다. 그런 다음 브랜치와 커밋을 빌드 매개변수로 buildWithParameters에 전송합니다.
JSON 페이로드에서 브랜치와 커밋을 추출하여 셸 환경 파일에 저장합니다:
python3 - <<'PY' > /tmp/webhook-trigger.env
import json
from pathlib import Path
payload = json.loads(Path("/home/labex/project/local-webhook-payload.json").read_text())
branch = payload["ref"].split("/")[-1]
commit = payload["after"]
print(f"WEBHOOK_BRANCH={branch}")
print(f"WEBHOOK_COMMIT={commit}")
PY
source /tmp/webhook-trigger.env
이제 Jenkins 빌드 요청을 보냅니다:
CRUMB=$(curl -fsS -c /tmp/jenkins-webhook-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-webhook-build.cookies -H "$CRUMB" \
--data-urlencode "WEBHOOK_BRANCH=${WEBHOOK_BRANCH}" \
--data-urlencode "WEBHOOK_COMMIT=${WEBHOOK_COMMIT}" \
-X POST http://localhost:8080/job/webhook-trigger-demo/buildWithParameters
빌드 #1이 완료될 때까지 기다립니다:
until curl -fsS http://localhost:8080/job/webhook-trigger-demo/1/api/json >/tmp/webhook-build-1.json 2>/dev/null && grep -q '"building":false' /tmp/webhook-build-1.json; do
echo "Waiting for webhook build #1..."
sleep 3
done
빌드가 성공했는지 확인합니다:
curl -fsS http://localhost:8080/job/webhook-trigger-demo/1/api/json | grep -o '"result":"SUCCESS"'
트리거된 빌드 로그 검사
이 단계에서는 Jenkins 콘솔 출력을 검사합니다. 빌드 로그는 브랜치, 커밋 ID, 커밋 제목을 보여주므로 웹훅 페이로드가 작업에 도달했다는 가장 직접적인 증거입니다.
관련 콘솔 라인을 출력합니다:
curl -fsS http://localhost:8080/job/webhook-trigger-demo/1/consoleText | grep -E 'Webhook branch|Webhook commit|Commit subject'
출력에는 main 브랜치와 커밋 제목이 포함되어야 합니다:
Webhook branch: main
Webhook commit: ...
Commit subject: Add webhook demo app
데스크톱 인터페이스에서 Firefox 를 열고 http://localhost:8080/job/webhook-trigger-demo/1/console에 접속합니다. 콘솔 출력 페이지의 빌드 로그에서 웹훅 브랜치, 커밋 ID, 커밋 제목을 확인할 수 있습니다.

요약
로컬 Git 리포지토리를 생성하고, 웹훅 스타일의 빌드 매개변수를 허용하도록 Jenkins 작업을 구성했으며, curl을 사용하여 로컬 웹훅 요청을 보내고 Jenkins 빌드 로그에서 브랜치와 커밋 정보를 확인했습니다. 이는 소스 제어 시스템이 리포지토리 변경 사항을 Jenkins 에 알릴 때 사용하는 핵심 흐름과 동일합니다.