Skip to main content

Vorab-Empfangs-Hook-Skript erstellen

Mit pre-receive-Hook-Skripts kannst du Anforderungen für das Akzeptieren oder Ablehnen eines Pushes abhängig von den Inhalten erstellen.

Beispiele für Pre-Receive-Hooks für GitHub Enterprise Server sind im Repository github/platform-samples enthalten.

Ein 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. Beachten Sie beim Erstellen eines Pre-Receive-Hook-Skripts die verfügbaren Eingaben, Ausgaben, den Beendigungsstatus sowie die 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 der Referenz, den neuen Objektnamen der Referenz und den vollständigen Namen der Referenz.

<old-value> SP <new-value> SP <ref-name> LF

Diese Zeichenfolge stellt die folgenden Argumente dar.

ArgumentBESCHREIBUNG
<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.

Rückgabestatus

Der Beendigungsstatus eines Pre-Receive-Skripts gibt an, ob der Push akzeptiert wird.

Wert des BeendigungsstatusAktion
0Der Push wird akzeptiert.
ungleich nullDer 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](#always-available)
    
  •         [Verfügbar für Pushvorgänge über die Weboberfläche oder die API](#available-for-pushes-from-the-web-interface-or-api)
    
  •         [Verfügbar für Pull Request-Merges](#available-for-pull-request-merges)
    
  •         [Verfügbar für Pushvorgänge unter Verwendung der SSH-Authentifizierung](#available-for-pushes-using-ssh-authentication)
    

Immer verfügbar

Die folgenden Variablen sind immer in der Pre-Receive-Hook-Umgebung verfügbar.

VariableBESCHREIBUNGBeispielwert
$GIT_DIR
Pfad zum Remoterepository der Instanz/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git
$GIT_OBJECT_DIRECTORY
Pfad zu einem temporären Verzeichnis, das die Objekte aus dem Push enthält/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git/
objects/ghq_luvYC864B9j
$GIT_QUARANTINE_PATH
Enthält denselben Wert wie $GIT_OBJECT_DIRECTORY/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git/
objects/ghq_luvYC864B9j
$GIT_ALTERNATE_OBJECT_
DIRECTORIES
Pfad zum Objektverzeichnis des Repositorys in der Instanz/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git/objects
$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 hatgit/2.0.0
$GITHUB_REPO_NAME
Name des Repositorys, das aktualisiert wird, im Format NAME/BESITZERocto-org/hello-enterprise
$GITHUB_REPO_PUBLIC
Boolescher Wert, der angibt, ob das aktualisierte Repository öffentlich ist
  • true: Das Repository ist öffentlich
  • false: Die Sichtbarkeit des Repositorys ist privat oder eingeschränkt.
$GITHUB_USER_IP
Die IP-Adresse des Clients, der den Push initiiert hat192.0.2.1
$GITHUB_USER_LOGIN
Der Benutzername für das Konto, das den Push initiiert hatoctocat

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.

WertAktionWeitere Informationen
auto-merge deployment api
Automatischer Merge des Basisbranches über eine Bereitstellung, die mit der API erstellt wurde
          [AUTOTITLE](/rest/deployments#create-a-deployment) |

|

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 in der 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 mit Auto-Merge | 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 Themen-Branches aus einem Pull Request in der Weboberfläche | Branches in einem Pull Request löschen und wiederherstellen | |
pull request merge api
| Zusammenführen eines Pull Request über die API | REST-API-Endpunkte für Pullanforderungen | |
pull request merge button
| Zusammenführen eines Pull Requests über die Weboberfläche | Einen Pull Request zusammenführen | |
pull request revert button
| Rückgängigmachung eines Pull Requests | Einen Pull Request rückgängig machen | |
releases delete button
| Einen Release löschen | 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 | |
web branch create
| Erstellung eines Zweigs über die Webschnittstelle | 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.

VariableBESCHREIBUNGBeispielwert
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN
Benutzername des Kontos, das den Pull Request erstellt hatoctocat
$GITHUB_PULL_REQUEST_HEAD
Der Name des Pull-Request-Topic-Branches im Format USERNAME:BRANCH
          <span style="white-space: nowrap;">octocat:fix-bug</span> |

|

$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

VariableBESCHREIBUNGBeispielwert
$GITHUB_PUBLIC_KEY_FINGERPRINT
Der Fingerabdruck des öffentlichen Schlüssels des Benutzers oder der Benutzerin, der die Änderungen vorgenommen hat.a1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6

Berechtigungen festlegen und einen Pre-Receive-Hook an GitHub Enterprise Server übermitteln

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.

  1. Stelle für Mac-Benutzer sicher, dass die Skripts über Ausführungsberechtigungen verfügen:

    sudo chmod +x SCRIPT_FILE.sh
    

    Stellen Sie für Windows Benutzer sicher, dass die Skripts über Ausführungsberechtigungen verfügen:

    git update-index --chmod=+x SCRIPT_FILE.sh
    
  2. 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
    
  3.        [Erstelle den Pre-Receive-Hook](/admin/policies/enforcing-policy-with-pre-receive-hooks/managing-pre-receive-hooks-on-the-github-enterprise-server-appliance#creating-pre-receive-hooks) 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.

  1. Stelle sicher, dass Docker lokal installiert ist.

  2. 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"]
    
  3. 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
    
  4. Stelle sicher, dass das Skript always_reject.sh über Ausführungsberechtigungen verfügt:

    chmod +x always_reject.sh
    
  5. 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
    
  6. Führe einen Datencontainer aus, der einen generierten SSH-Schlüssel enthält:

    docker run --name data pre-receive.dev /bin/true
    
  7. Kopiere den Test-Pre-Receive Hook always_reject.sh in den Datencontainer:

    docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
    
  8. 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
    
  9. Kopiere den generierten SSH-Schlüssel aus dem Datencontainer auf den lokalen Computer:

    docker cp data:/home/git/.ssh/id_ed25519 .
    
  10. Ändere den Remotezugriff eines Testrepositorys, und führe einen Push in das Repository test.git innerhalb des Docker-Containers aus. In diesem Beispiel wird git@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 Lektüre

  •         [Anpassen von Git – eine mit Git erzwungene Beispielrichtlinie](https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy) auf der _Pro Git-Website_