Beispiele für Pre-Receive-Hooks für GitHub Enterprise Server sind im Repository github/platform-samples
enthalten.
Pre-Receive-Hook-Skript schreiben
Ein Pre-Receive-Hook-Skript wird in einer Pre-Receive-Hook-Umgebung auf Ihre GitHub Enterprise Server-Instance ausgeführt. Beachte beim Erstellen eines Pre-Receive-Hook-Skripts die verfügbaren Eingaben, Ausgaben, Beendigungsstatus und Umgebungsvariablen.
Eingabe (stdin
)
Nach einem Push und vor der Aktualisierung von Verweisen (refs) für das Remoterepository ruft der Prozess git-receive-pack
auf Ihre GitHub Enterprise Server-Instance das Pre-Receive-Hook-Skript auf. Die Standardeingabe für das Skript (stdin
) ist eine Zeichenfolge mit einer Zeile für jeden zu aktualisierenden Verweis. Dabei enthält jede Zeile den alten Objektnamen, den neuen Objektnamen und den vollständigen Namen des Verweises.
<old-value> SP <new-value> SP <ref-name> LF
Diese Zeichenfolge stellt die folgenden Argumente dar.
Argument | BESCHREIBUNG |
---|---|
<old-value> | Der alte Objektname, der im Verweis gespeichert ist. Wenn du einen neuen Verweis erstellst, umfasst der Wert 40 Nullen. |
<new-value> | Der neue Objektname, der im Verweis gespeichert werden soll. Wenn du einen Verweis löschst, umfasst der Wert 40 Nullen. |
<ref-name> | Der vollständige Name des Verweises. |
Weitere Informationen zu git-receive-pack
findest du unter git-receive-pack in der Git-Dokumentation. Weitere Informationen zu Verweisen findest du unter Git-Verweise in Pro Git.
Ausgabe (stdout
)
Die Standardausgabe für das Skript (stdout
) wird an den Client zurückgegeben. Alle echo
-Anweisungen sind für Benutzer*innen in der Befehlszeile oder auf der Benutzeroberfläche sichtbar.
Beendigungsstatus
Der Beendigungsstatus eines Pre-Receive-Skripts gibt an, ob der Push akzeptiert wird.
Wert des Beendigungsstatus | Aktion |
---|---|
0 | Der Push wird akzeptiert. |
ungleich null | Der Push wird abgelehnt. |
Umgebungsvariablen
Zusätzlich zur Standardeingabe für dein Pre-Receive-Hook-Skript (stdin
) stellt GitHub Enterprise Server in der Bash-Umgebung die folgenden Variablen für die Ausführung deines Skripts zur Verfügung. Weitere Informationen zu stdin
für dein Pre-Receive-Hook-Skript findest du unter Eingabe (stdin
).
Abhängig davon, wodurch die Skriptausführung ausgelöst wird, sind unterschiedliche Umgebungsvariablen für dein Pre-Receive-Hook-Skript verfügbar.
- Immer verfügbar
- Verfügbar für Pushvorgänge über die Weboberfläche oder die API
- Verfügbar für Pull Request-Merges
- Verfügbar für Pushvorgänge unter Verwendung der SSH-Authentifizierung
Immer verfügbar
Die folgenden Variablen sind immer in der Pre-Receive-Hook-Umgebung verfügbar.
Variable | BESCHREIBUNG | Beispielwert |
---|---|---|
$GIT_DIR | Pfad zum Remoterepository der Instanz | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git |
$GIT_PUSH_OPTION_COUNT | Die Anzahl von Pushoptionen, die vom Client mit --push-option gesendet wurden. Weitere Informationen findest du unter git-push in der Git-Dokumentation. | 1 |
$GIT_PUSH_OPTION_N | N entspricht hierbei einer ab 0 beginnenden Ganzzahl. Diese Variable enthält die Zeichenfolge der vom Client gesendeten Pushoption. Die erste gesendete Option wird in GIT_PUSH_OPTION_0 , die zweite in GIT_PUSH_OPTION_1 gespeichert usw. Weitere Informationen zu Pushoptionen findest du unter git-push in der Git-Dokumentation. | abcd |
$GIT_USER_AGENT | Benutzer-Agent-Zeichenfolge, die vom Git-Client gesendet wurde, der die Änderungen gepusht hat | git/2.0.0 |
$GITHUB_REPO_NAME | Name des Repositorys, das aktualisiert wird, im Format NAME/BESITZER | octo-org/hello-enterprise |
$GITHUB_REPO_PUBLIC | Boolescher Wert, der angibt, ob das aktualisierte Repository öffentlich ist |
|
$GITHUB_USER_IP | Die IP-Adresse des Clients, der den Push initiiert hat | 192.0.2.1 |
$GITHUB_USER_LOGIN | Der Benutzername für das Konto, das den Push initiiert hat | octocat |
Verfügbar für Pushvorgänge über die Weboberfläche oder die API
Die Variable $GITHUB_VIA
ist in der Pre-Receive-Hook-Umgebung verfügbar, wenn die Verweisaktualisierung, die den Hook auslöst, über die Weboberfläche oder die API für GitHub Enterprise Server erfolgt. Der Wert beschreibt die Aktion, durch die der Verweis aktualisiert wurde.
Wert | Aktion | Weitere Informationen |
---|---|---|
auto-merge deployment api | Automatischer Merge des Basisbranches über eine Bereitstellung, die mit der API erstellt wurde | REST-API-Endpunkte für Bereitstellungen |
blob#save | Ändern des Inhalts einer Datei über die Weboberfläche | Bearbeiten von Dateien |
branch merge api | Zusammenführen eines Branches über die API | REST-API-Endpunkte für Branches und deren Einstellungen |
branches page delete button | Löschen eines Branches über die Weboberfläche | Erstellen und Löschen von Branches in deinem Repository |
git refs create api | Erstellen eines Verweises über die API | REST-API-Endpunkte für Git-Verweise |
git refs delete api | Löschen eines Verweises über die API | REST-API-Endpunkte für Git-Verweise |
git refs update api | Aktualisieren eines Verweises über die API | REST-API-Endpunkte für Git-Verweise |
git repo contents api | Ändern des Inhalts einer Datei über die API | REST-API-Endpunkte für Repositoryinhalt |
merge | Zusammenführen eines Pull Requests über die Funktion für automatisches Zusammenführen | Automatisches Zusammenführen eines Pull Requests |
merge base into head | Aktualisieren des Topic-Branches anhand des Basisbranches, wenn der Basisbranch strikte Statusüberprüfungen erfordert (z. B. über Branch aktualisieren in einem Pull Request) | Informationen zu geschützten Branches |
pull request branch delete button | Löschen eines Topic-Branches aus einem Pull Request auf der Weboberfläche | Branches in einem Pull Request löschen und wiederherstellen |
pull request branch undo button | Wiederherstellen eines Topic-Branches aus einem Pull Request auf der Weboberfläche | Branches in einem Pull Request löschen und wiederherstellen |
pull request merge api | Zusammenführen einer Pull Requests über die API | „REST-API-Endpunkte für Pullanforderungen“ |
pull request merge button | Zusammenführen eines Topic-Branches aus einem Pull Request auf der Weboberfläche | Einen Pull Request zusammenführen |
pull request revert button | Wiederherstellen eines Pull Requests | Einen Pull Request rückgängig machen |
releases delete button | Löschen eines Release | Veröffentlichungen in einem Repository verwalten |
stafftools branch restore | Wiederherstellung eines Branches auf dem Websiteadministratoren-Dashboard | Verwalten Ihrer Instanz über die Web-Benutzeroberfläche |
tag create api | Erstellen eines Tags über die API | „REST-API-Endpunkte für Git-Tags“ |
slumlord (#SHA) | Committen über Subversion | Unterstützung für Subversion-Clients |
web branch create | Löschen eines Branches über die Webbenutzeroberfläche | Erstellen und Löschen von Branches in deinem Repository |
Verfügbar für Pull Request-Merges
Die folgenden Variablen sind in der Pre-Receive-Hook-Umgebung verfügbar, wenn der Push, der den Hook auslöst, aufgrund der Zusammenführung eines Pull Requests ein Push ist.
Variable | BESCHREIBUNG | Beispielwert |
---|---|---|
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN | Benutzername des Kontos, das den Pull Request erstellt hat | octocat |
$GITHUB_PULL_REQUEST_HEAD | Der Name des PR-Topic-Branches im Format USERNAME:BRANCH | octocat:fix-bug |
$GITHUB_PULL_REQUEST_BASE | Der Name des PR-Basisbranches im Format USERNAME:BRANCH | octocat:main |
Verfügbar für Pushvorgänge unter Verwendung der SSH-Authentifizierung
Variable | BESCHREIBUNG | Beispielwert |
---|---|---|
$GITHUB_PUBLIC_KEY_FINGERPRINT | Der Fingerabdruck des öffentlichen Schlüssels für die oder den Benutzer*in, die bzw. der die Änderungen gepusht hat | a1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6 |
Berechtigungen festlegen und einen Pre-Receive-Hook per Push-Vorgang an GitHub Enterprise Server übertragen
Ein Pre-Receive-Hook-Skript ist in einem Repository auf Ihre GitHub Enterprise Server-Instance enthalten. Ein Websiteadministrator muss die Repository-Berechtigungen beachten und sicherstellen, dass nur die richtigen Benutzer über Zugriff verfügen.
Es wird empfohlen, Hooks in einem einzelnen Repository zu konsolidieren. Wenn das konsolidierte Hook-Repository öffentlich ist, kann README.md
verwendet werden, um Richtlinienerzwingungen zu erläutern. Darüber hinaus können Beiträge über Pull Requests akzeptiert werden. Pre-Receive-Hooks können jedoch nur auf dem Standardbranch hinzugefügt werden. Für einen Test-Workflow sollten Forks des Repositorys mit entsprechender Konfiguration verwendet werden.
-
Stelle für Mac-Benutzer sicher, dass die Skripts über Ausführungsberechtigungen verfügen:
sudo chmod +x SCRIPT_FILE.sh
Stelle für Windows-Benutzer sicher, dass die Skripts über Ausführungsberechtigungen verfügen:
git update-index --chmod=+x SCRIPT_FILE.sh
-
Führe einen Commit und einen Push in das gewünschte Repository für Pre-Receive-Hooks auf Ihre GitHub Enterprise Server-Instance aus.
git commit -m "YOUR COMMIT MESSAGE" git push
-
Erstelle den Pre-Receive-Hook in der GitHub Enterprise Server-Instanz.
Pre-Receive-Skripts lokal testen
Du kannst ein Pre-Receive-Hook-Skript lokal testen, bevor du es in Ihre GitHub Enterprise Server-Instance erstellst oder aktualisierst. Eine Methode besteht darin, eine lokale Docker-Umgebung zu erstellen, die als ein Remote-Repository fungiert und als den Pre-Receive-Hook ausführen kann.
-
Erstelle eine Datei mit dem Namen
Dockerfile.dev
, die Folgendes enthält: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"]
-
Erstelle ein Pre-Receive-Testskript mit dem Namen
always_reject.sh
. Dieses Beispielskript lehnt alle Push-Vorgänge ab, was zum Sperren eines Repositorys nützlich ist:#!/usr/bin/env bash echo "error: rejecting all pushes" exit 1
-
Stelle sicher, dass das Skript
always_reject.sh
über Ausführungsberechtigungen verfügt:chmod +x always_reject.sh
-
Erstelle in dem Verzeichnis, das
Dockerfile.dev
enthält, ein Image:$ 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
-
Führe einen Datencontainer aus, der einen generierten SSH-Schlüssel enthält:
docker run --name data pre-receive.dev /bin/true
-
Kopiere den Pre-Receive-Testhook
always_reject.sh
in den Datencontainer:docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
-
Führe einen Anwendungscontainer aus, der
sshd
und den Hook ausführt. Beachte die zurückgegebene Container-ID.$ docker run -d -p 52311:22 --volumes-from data pre-receive.dev > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
-
Kopiere den generierten SSH-Schlüssel aus dem Datencontainer auf den lokalen Computer:
docker cp data:/home/git/.ssh/id_ed25519 .
-
Ändere den Remotezugriff eines Testrepositorys, und führe einen Push in das Repository
test.git
innerhalb des Docker-Containers aus. In diesem Beispiel wirdgit@github.com:octocat/Hello-World.git
verwendet, du kannst jedoch ein beliebiges Repository auswählen. In diesem Beispiel wird davon ausgegangen, dass dein lokaler Computer (127.0.0.1) Port 52311 bindet. Du kannst jedoch eine andere IP-Adresse verwenden, wenn Docker auf einem Remotecomputer ausgeführt wird.$ 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'
Beachte, dass der Push abgelehnt wurde, nachdem du den Pre-Receive-Hook ausgeführt und die Ausgabe des Skripts wiedergegeben hast.
Weiterführende Themen
- Anpassen von Git – eine mit Git erzwungene Beispielrichtlinie auf der Pro Git-Website