Vous pouvez voir des exemples de hooks de pré-réception pour GitHub Enterprise Server dans le dépôt github/platform-samples.
Écriture d’un script de hook de pré-réception
Un script de hook de pré-réception s’exécute dans un environnement de hook de pré-réception sur votre instance GitHub Enterprise Server. Quand vous créez un script de hook de pré-réception, tenez compte des variables d’entrée, de sortie, d’état de sortie et d’environnement disponibles.
Entrée ()
Après une poussée (push) et avant la mise à jour de toute référence pour le dépôt distant, le processus sur votre instance GitHub Enterprise Server appelle le script de hook de pré-réception. L’entrée standard pour le script, , est une chaîne contenant une ligne pour chaque référence à mettre à jour. Chaque ligne contient l’ancien nom d’objet et le nouveau nom d’objet pour la référence ainsi que le nom complet de la référence.
<old-value> SP <new-value> SP <ref-name> LF
Cette chaîne représente les arguments suivants.
| Argument | Description |
|---|---|
<old-value> | Ancien nom d’objet stocké dans la référence. Quand vous créez une nouvelle référence, la valeur initiale est de 40 zéros. |
<new-value> | Nouveau nom d’objet à stocker dans la référence. Quand vous supprimez une référence, la valeur est de 40 zéros. |
<ref-name> | Nom complet de la référence. |
Pour plus d’informations sur , consultez « git-receive-pack » dans la documentation Git. Pour plus d’informations sur les références, consultez « Références Git » dans Pro Git.
Sortie ()
La sortie standard du script, , est retournée au client. Toutes les instructions seront visibles par l’utilisateur sur la ligne de commande ou dans l’interface utilisateur.
État de sortie
L'état de sortie d'un script pré-receive détermine si le push sera accepté.
| Valeur de l’état de sortie | Action |
|---|---|
| 0 | La poussée sera acceptée. |
| Différent de zéro | La poussée sera refusée. |
Variables d'environnement
En plus de l’entrée standard de votre script de hook de pré-réception, GitHub Enterprise Server rend les variables suivantes disponibles dans l’environnement Bash pour l’exécution de votre script. Pour plus d’informations sur pour votre script de hook de pré-réception, consultez Entrée ().
Différentes variables d’environnement sont disponibles pour votre script de hook de pré-réception selon ce qui déclenche l’exécution du script.
- Toujours disponible
- Disponible pour les pushs à partir de l’interface web ou de l’API
- Disponible pour les fusions de pull requests
- Disponible pour les envois avec l'authentification SSH
Toujours disponible
Les variables suivantes sont toujours disponibles dans l’environnement de hook de pré-réception.
| Variable | Description | Valeur d'exemple |
|---|---|---|
$GIT_DIR | Chemin du dépôt distant sur l’instance | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git |
$GIT_OBJECT_DIRECTORY | Chemin d’accès vers un répertoire temporaire contenant les objets de l’envoi | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git/ objects/ghq_luvYC864B9j |
$GIT_QUARANTINE_PATH | Contient la même valeur que | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git/ objects/ghq_luvYC864B9j |
$GIT_ALTERNATE_OBJECT_ | Chemin d’accès au répertoire d’objets du référentiel sur l’instance | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git/objects |
$GIT_PUSH_OPTION_COUNT | Nombre d’options de poussée envoyées par le client avec . Pour plus d’informations, consultez « git-push » dans la documentation Git. | 1 |
$GIT_PUSH_OPTION_N | Où N est un entier commençant à 0. Cette variable contient la chaîne d’options de poussée envoyée par le client. La première option envoyée est stockée dans , la deuxième option envoyée est stockée dans et ainsi de suite. Pour plus d’informations sur les options de poussée, consultez « git-push » dans la documentation Git. | abcd |
$GIT_USER_AGENT | Chaîne d’agent utilisateur envoyée par le client Git qui a poussé les modifications | git/2.0.0 |
$GITHUB_REPO_NAME | Nom du référentiel mis à jour au format NOM/PROPRIÉTAIRE | octo-org/hello-enterprise |
$GITHUB_REPO_PUBLIC | Booléen indiquant si le dépôt mis à jour est public |
|
$GITHUB_USER_IP | Adresse IP du client à l’origine de la poussée | 192.0.2.1 |
$GITHUB_USER_LOGIN | Nom d'utilisateur du compte à l'origine du push | octocat |
Disponible pour les pushs à partir de l’interface web ou de l’API
La variable est disponible dans l’environnement de hook de pré-réception quand la mise à jour de la référence qui déclenche le hook s’effectue par le biais de l’interface web ou de l’API pour GitHub Enterprise Server. La valeur décrit l’action qui a mis à jour la référence.
| Valeur | Action | Plus d’informations |
|---|---|---|
auto-merge deployment api | Fusion automatique de la branche de base par le biais d’un déploiement créé avec l’API | AUTOTITRE |
blob#save | Modification du contenu d’un fichier dans l’interface web | AUTOTITRE |
branch merge api | Fusion d’une branche par le biais de l’API | AUTOTITRE |
branches page delete button | Suppression d’une branche dans l’interface web | AUTOTITRE |
git refs create api | Création d’une référence par le biais de l’API | AUTOTITRE |
git refs delete api | Suppression d’une référence par le biais de l’API | AUTOTITRE |
git refs update api | Mise à jour d’une référence par le biais de l’API | AUTOTITRE |
git repo contents api | Modification du contenu d’un fichier par le biais de l’API | AUTOTITRE |
merge | Fusion d’une pull request à l’aide de la fusion automatique | AUTOTITRE |
merge base into head | Mise à jour de la branche de sujet à partir de la branche de base lorsque la branche de base nécessite des vérifications d’état strictes (via Mettre à jour la branche dans une pull request, par exemple) | AUTOTITRE |
pull request branch delete button | Suppression d'une branche de sujet d'une pull request dans l'interface web | AUTOTITRE |
pull request branch undo button | Restauration d’une branche thématique à partir d’un pull request dans l’interface web | AUTOTITRE |
pull request merge api | Fusion d'une pull request via l'API | AUTOTITRE |
pull request merge button | Fusion d'une pull request dans l'interface web | AUTOTITRE |
pull request revert button | Restaurer une demande de tirage (pull request) | AUTOTITRE |
releases delete button | Suppression d’une version | AUTOTITRE |
stafftools branch restore | Restauration d’une branche à partir du tableau de bord de l’administrateur de site | AUTOTITRE |
tag create api | Création d’une balise via l’API | AUTOTITRE |
web branch create | Création d’une branche via l’interface Web | AUTOTITRE |
Disponible pour fusionner les pull requests
Les variables suivantes sont disponibles dans l’environnement de hook de pré-réception quand la poussée qui déclenche le hook est due à la fusion d’une demande de tirage.
| Variable | Description | Valeur d'exemple |
|---|---|---|
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN | Nom d'utilisateur du compte qui a soumis le pull request | octocat |
$GITHUB_PULL_REQUEST_HEAD | Nom de la branche du sujet de la pull request au format | octocat:fix-bug |
$GITHUB_PULL_REQUEST_BASE | Nom de la branche de base de la pull request au format | octocat:main |
Disponible pour les envois avec l'authentification SSH
| Variable | Description | Valeur d'exemple |
|---|---|---|
$GITHUB_PUBLIC_KEY_FINGERPRINT | Empreinte digitale de la clé publique pour l’utilisateur qui a poussé les modifications | a1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6 |
Définition des autorisations et poussée d’un hook de pré-réception sur GitHub Enterprise Server
Un script de hook de pré-réception est contenu dans un dépôt sur votre instance GitHub Enterprise Server. Un administrateur de site doit prendre en compte les autorisations du dépôt et veiller à ce que seuls les utilisateurs appropriés y aient accès.
Nous vous recommandons de centraliser les hooks dans un dépôt unique. Si le dépôt dans lequel sont centralisés les hooks est public, il peut être utilisé pour expliquer l'application des politiques. En outre, les contributions peuvent être acceptées par le biais de pull requests. Toutefois, les hooks de pré-réception ne peuvent être ajoutés qu’à partir de la branche par défaut. Pour un workflow de test, des duplications (fork) du dépôt avec une configuration doivent être utilisées.
-
Pour les utilisateurs Mac, vérifiez que les scripts ont des autorisations d’exécution :
sudo chmod +x SCRIPT_FILE.shPour Windows utilisateurs, vérifiez que les scripts disposent d’autorisations d’exécution :
git update-index --chmod=+x SCRIPT_FILE.sh -
Commitez et poussez sur le dépôt désigné pour les hooks de pré-réception sur votre instance GitHub Enterprise Server.
git commit -m "YOUR COMMIT MESSAGE" git push -
Créez le hook de pré-réception sur l’instance GitHub Enterprise Server.
Test des scripts avant réception localement
Vous pouvez tester un script de hook de pré-réception localement avant de le créer ou de le mettre à jour sur votre instance GitHub Enterprise Server. Vous pouvez, par exemple, créer un environnement Docker local qui jouera le rôle de dépôt distant pouvant exécuter le hook de pré-réception.
-
Vérifiez que Docker est installé localement.
-
Créez un fichier contenant :
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"] -
Créez un script de pré-réception de test nommé [nom_du_script]. Cet exemple de script rejette toutes les poussées, ce qui est utile pour verrouiller un dépôt :
#!/usr/bin/env bash echo "error: rejecting all pushes" exit 1 -
Vérifiez que les scripts ont des autorisations d’exécution :
chmod +x always_reject.sh -
À partir du répertoire contenant , générez une 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 -
Exécutez un conteneur de données qui contient une clé SSH générée :
docker run --name data pre-receive.dev /bin/true -
Copiez le hook de pré-réception de test dans le conteneur de données :
docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive -
Exécutez un conteneur d’applications qui exécute et exécute le hook. Notez l’ID de conteneur retourné :
$ docker run -d -p 52311:22 --volumes-from data pre-receive.dev > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58 -
Copiez la clé SSH générée à partir du conteneur de données sur l’ordinateur local :
docker cp data:/home/git/.ssh/id_ed25519 . -
Modifiez le dépôt distant d’un dépôt de test et poussez sur le dépôt dans le conteneur Docker. Cet exemple utilise , mais vous pouvez utiliser n’importe quel dépôt. Cet exemple suppose que votre ordinateur local (127.0.0.1) lie le port 52311, mais vous pouvez utiliser une autre adresse IP si Docker s’exécute sur un ordinateur distant.
$ 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'Notez que la poussée a été rejetée après l’exécution du hook de pré-réception et l’écho de la sortie du script.
Pour aller plus loin
- « Personnalisation de Git - Exemple de stratégie appliquée par Git » sur le site web Pro Git