Jenkins-Builds mit Webhooks auslösen

Beginner

Einführung

Webhook-Integrationen ermöglichen es Versionsverwaltungssystemen, Jenkins bei Änderungen an einem Repository zu benachrichtigen. Ein echter GitHub- oder GitLab-Webhook sendet eine HTTP-Anfrage an Jenkins. Für ein zuverlässiges Lab simulieren Sie diese Anfrage lokal mit curl, anstatt von einem externen Dienst abhängig zu sein.

In diesem Lab erstellen Sie ein lokales Git-Repository, konfigurieren einen Jenkins-Freestyle-Job, der Branch- und Commit-Parameter im Webhook-Stil akzeptiert, senden eine lokale Webhook-Anfrage und untersuchen das Protokoll des ausgelösten Builds.

Ein lokales Quell-Repository vorbereiten

In diesem Schritt erstellen Sie ein kleines Git-Repository, das als Versionsverwaltungssystem fungiert. Ein Webhook überträgt normalerweise den geänderten Branch und den Commit; daher speichern Sie diese Werte für die späteren Schritte.

Der Befehl git init -b main erstellt ein Repository mit einem main-Branch. Die git config-Befehle legen eine Autorenidentität fest, sodass der Commit ohne weitere Abfragen erstellt werden kann.

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"

Erstellen Sie eine Datei und committen Sie diese:

echo "webhook demo build" > app.txt
git add app.txt
git commit -m "Add webhook demo app"

Speichern Sie den Branch und die kurze Commit-ID in einer Umgebungsdatei. Der Befehl tee schreibt die Werte in eine Datei und gibt sie gleichzeitig aus, damit Sie sie überprüfen können.

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

Die Ausgabe sollte in etwa so aussehen:

WEBHOOK_BRANCH=main
WEBHOOK_COMMIT=...

Der Jenkins-Job wird innerhalb des Jenkins-Docker-Containers ausgeführt. Kopieren Sie das Repository nach /var/jenkins_home/webhook-repo, damit der Build-Prozess innerhalb des Containers darauf zugreifen kann:

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

Einen parametrisierten Jenkins-Job erstellen

In diesem Schritt erstellen Sie einen Jenkins-Freestyle-Job namens webhook-trigger-demo. Der Job akzeptiert zwei String-Parameter: WEBHOOK_BRANCH und WEBHOOK_COMMIT. Dies spiegelt die wichtigen Daten wider, die ein Webhook eines Versionsverwaltungssystems sendet.

Erstellen Sie die XML-Konfiguration für den Jenkins-Job. Der Shell-Befehl im Job gibt den Branch und den Commit aus und prüft anschließend, ob der Commit im lokalen Git-Repository existiert.

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

Kopieren Sie den Job in Jenkins und laden Sie den Controller mit dem während der Einrichtung erstellten Hilfsskript neu:

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

Bestätigen Sie, dass Jenkins den Job erkennt:

curl -fsS http://localhost:8080/job/webhook-trigger-demo/api/json | grep -o '"name":"webhook-trigger-demo"'

Die erwartete Ausgabe ist:

"name":"webhook-trigger-demo"

Eine Webhook-Payload-Datei erstellen

In diesem Schritt erstellen Sie eine JSON-Datei, die wie eine kleine Webhook-Payload eines Versionsverwaltungssystems aussieht. Echte Webhook-Payloads enthalten viele Felder. Dieses Lab beschränkt sich auf die für den Build notwendigen Felder: ref für den Branch und after für die Commit-ID.

Laden Sie die gespeicherten Branch- und Commit-Werte und schreiben Sie dann die JSON-Payload:

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

Verwenden Sie den JSON-Formatter von Python, um sicherzustellen, dass die Datei gültig und lesbar ist:

python3 -m json.tool /home/labex/project/local-webhook-payload.json

Sie sollten die Branch-Referenz refs/heads/main und die Commit-ID aus Ihrem Git-Repository sehen.

Die Webhook-Anfrage mit curl senden

In diesem Schritt simulieren Sie die Webhook-Zustellung. Jenkins verwendet ein Crumb-Token, um POST-Anfragen zu schützen. Daher fordert der Befehl zuerst ein Crumb an und speichert den entsprechenden Cookie-Speicher. Anschließend werden der Branch und der Commit als Build-Parameter an buildWithParameters gesendet.

Extrahieren Sie den Branch und den Commit aus der JSON-Payload in eine Shell-Umgebungsdatei:

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

Senden Sie nun die Jenkins-Build-Anfrage:

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

Warten Sie, bis Build #1 abgeschlossen ist:

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

Bestätigen Sie, dass der Build erfolgreich war:

curl -fsS http://localhost:8080/job/webhook-trigger-demo/1/api/json | grep -o '"result":"SUCCESS"'

Das Protokoll des ausgelösten Builds untersuchen

In diesem Schritt untersuchen Sie die Konsolenausgabe von Jenkins. Das Build-Protokoll ist der direkteste Beweis dafür, dass die Webhook-Payload den Job erreicht hat, da es den Branch, die Commit-ID und das Commit-Subject anzeigt.

Geben Sie die relevanten Konsolenzeilen aus:

curl -fsS http://localhost:8080/job/webhook-trigger-demo/1/consoleText | grep -E 'Webhook branch|Webhook commit|Commit subject'

Die Ausgabe sollte den main-Branch und das Commit-Subject enthalten:

Webhook branch: main
Webhook commit: ...
Commit subject: Add webhook demo app

Öffnen Sie Firefox über die Desktop-Oberfläche und besuchen Sie http://localhost:8080/job/webhook-trigger-demo/1/console. Die Seite "Console Output" sollte den Webhook-Branch, die Commit-ID und das Commit-Subject im Build-Protokoll anzeigen.

Jenkins webhook build console output

Zusammenfassung

Sie haben ein lokales Git-Repository erstellt, einen Jenkins-Job für die Annahme von Build-Parametern im Webhook-Stil konfiguriert, eine lokale Webhook-Anfrage mit curl gesendet und die Branch- und Commit-Informationen im Jenkins-Build-Protokoll verifiziert. Dies entspricht dem grundlegenden Ablauf, den Versionsverwaltungssysteme verwenden, um Jenkins über Repository-Änderungen zu benachrichtigen.