はじめに
Webhook 統合を使用すると、ソース管理システムはリポジトリに変更があった際に Jenkins へ通知を送ることができます。GitHub や GitLab の実際の Webhook は、Jenkins に対して HTTP リクエストを送信します。この実験では、外部サービスに依存することなく、curl を使用してローカル環境でそのリクエストをシミュレートします。
この実験では、ローカルの Git リポジトリを作成し、Webhook 形式のブランチおよびコミットパラメータを受け入れる Jenkins のフリースタイルジョブを設定します。その後、ローカルで Webhook リクエストを送信し、トリガーされたビルドログを検査します。
ローカルソースリポジトリの準備
このステップでは、ソース管理システムとして機能する小さな Git リポジトリを作成します。通常、Webhook には変更されたブランチとコミットの情報が含まれるため、後のステップで使用するためにこれらの値を保存しておきます。
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 という 2 つの文字列パラメータを受け入れます。これは、ソース管理の Webhook が送信する重要なデータを模倣したものです。
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"
Webhook ペイロードファイルの作成
このステップでは、ソース管理の Webhook ペイロードのような JSON ファイルを作成します。実際の Webhook ペイロードには多くのフィールドが含まれますが、この実験ではビルドに必要なフィールド(ブランチ用の 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 を使用した Webhook リクエストの送信
このステップでは、Webhook の配信をシミュレートします。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 のコンソール出力を検査します。ビルドログは、Webhook ペイロードがジョブに到達したことを示す最も直接的な証拠であり、ブランチ、コミット 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 にアクセスしてください。「Console Output」ページには、ビルドログ内に Webhook のブランチ、コミット ID、コミットの件名が表示されているはずです。

まとめ
ローカルの Git リポジトリを作成し、Webhook 形式のビルドパラメータを受け入れるように Jenkins ジョブを設定し、curl を使用してローカルの Webhook リクエストを送信し、Jenkins ビルドログでブランチとコミットの証拠を確認しました。これは、ソース管理システムがリポジトリの変更を Jenkins に通知する際に使用するのと同じコアフローです。