Skip to main content

Création d’un script de hook de pré-réception

Utilisez des scripts de hook de pré-réception pour créer des conditions d’acceptation ou de rejet d’une poussée (push) en fonction du contenu.

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 (stdin)

Après une poussée (push) et avant la mise à jour de toute référence pour le dépôt distant, le processus git-receive-pack sur votre instance GitHub Enterprise Server appelle le script de hook de pré-réception. L’entrée standard pour le script, stdin, 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.

ArgumentDescription
<old-value>Ancien nom d’objet stocké dans la référence.
Quand vous créez une référence, la valeur 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 git-receive-pack, 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 (stdout)

La sortie standard du script, stdout, est retournée au client. Toutes les instructions echo 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 de pré-réception détermine si la poussée sera acceptée.

Valeur de l’état de sortieAction
0La poussée sera acceptée.
Différent de zéroLa poussée sera refusée.

Variables d'environnement

En plus de l’entrée standard de votre script de hook de pré-réception, stdin, GitHub Enterprise Server rend les variables suivantes disponibles dans l’environnement Bash pour l’exécution de votre script. Pour plus d’informations sur stdin pour votre script de hook de pré-réception, consultez « Entrée (stdin) ».

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

Les variables suivantes sont toujours disponibles dans l’environnement de hook de pré-réception.

VariableDescriptionValeur 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_PUSH_OPTION_COUNT
Nombre d’options de poussée envoyées par le client avec --push-option. 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 GIT_PUSH_OPTION_0, la deuxième option envoyée est stockée dans GIT_PUSH_OPTION_1 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 modificationsgit/2.0.0
$GITHUB_REPO_NAME
Nom du référentiel mis à jour au format NOM/PROPRIÉTAIREocto-org/hello-enterprise
$GITHUB_REPO_PUBLIC
Booléen indiquant si le dépôt mis à jour est public
  • true : la visibilité du dépôt est publique
  • false : la visibilité du dépôt est privée ou interne
$GITHUB_USER_IP
Adresse IP du client à l’origine de la poussée192.0.2.1
$GITHUB_USER_LOGIN
Nom d’utilisateur du compte à l’origine de la pousséeoctocat

Disponible pour les poussées à partir de l’interface web ou de l’API

La variable $GITHUB_VIA 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.

ValeurActionPlus d’informations
auto-merge deployment api
Fusion automatique de la branche de base par le biais d’un déploiement créé avec l’APIPoints de terminaison d’API REST pour les déploiements
blob#save
Modification du contenu d’un fichier dans l’interface webModification de fichiers
branch merge api
Fusion d’une branche par le biais de l’APIPoints de terminaison d’API REST pour les branches et leurs paramètres
branches page delete button
Suppression d’une branche dans l’interface webCréation et suppression de branches dans votre référentiel
git refs create api
Création d’une référence par le biais de l’APIPoints de terminaison d’API REST pour les références Git
git refs delete api
Suppression d’une référence par le biais de l’APIPoints de terminaison d’API REST pour les références Git
git refs update api
Mise à jour d’une référence par le biais de l’APIPoints de terminaison d’API REST pour les références Git
git repo contents api
Modification du contenu d’un fichier par le biais de l’APIPoints de terminaison d’API REST pour les contenus du référentiel
mergeFusion d’une demande de tirage (pull request) à l’aide de la fusion automatiqueFusion automatique d'une demande de tirage
merge base into head
Mise à jour de la branche de rubrique à 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 demande de tirage (pull request), par exemple)À propos des branches protégées
pull request branch delete button
Suppression d’une branche de rubrique d’une demande de tirage (pull request) dans l’interface webSuppression et restauration de branches dans une demande de tirage
pull request branch undo button
Restauration d’une branche de rubrique à partir d’une demande de tirage (pull request) dans l’interface webSuppression et restauration de branches dans une demande de tirage
pull request merge api
Fusion d’une demande de tirage (pull request) via l’APIPoints de terminaison d’API REST pour les demandes de tirage (pull request)
pull request merge button
Fusion d’une demande de tirage (pull request) dans l’interface webFusion d’une demande de tirage
pull request revert button
Revenir à la dernière version d’une demande de tirage (pull request)Restauration d’une demande de tirage (pull request)
releases delete button
Suppression d’une versionGestion des mises en production dans un référentiel
stafftools branch restore
Restauration d’une branche à partir du tableau de bord de l’administrateur de siteGéstion de votre instance à partir de l’IU WEB.
tag create api
Création d’une balise via l’APIPoints de terminaison d’API REST pour les balises Git
slumlord (#SHA)
Commiter via la SubversionPrise en charge des clients Subversion
web branch create
Création d’une branche via l’interface WebCréation et suppression de branches dans votre référentiel

Disponible pour les fusions de demandes de tirage

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.

VariableDescriptionValeur d'exemple
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN
Nom d’utilisateur du compte qui a créé la demande de tirageoctocat
$GITHUB_PULL_REQUEST_HEAD
Nom de la branche de rubrique de la demande de tirage au format USERNAME:BRANCHoctocat:fix-bug
$GITHUB_PULL_REQUEST_BASE
Nom de la branche de base de la demande de tirage au format USERNAME:BRANCHoctocat:main

Disponible pour les poussées à l’aide de l’authentification SSH

VariableDescriptionValeur d'exemple
$GITHUB_PUBLIC_KEY_FINGERPRINT
Empreinte digitale de la clé publique pour l’utilisateur qui a poussé les modificationsa1: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, README.md peut être utilisé pour expliquer les applications de stratégie. En outre, les contributions peuvent être acceptées par le biais de demandes de tirage. 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.

  1. Pour les utilisateurs Mac, vérifiez que les scripts ont des autorisations d’exécution :

    sudo chmod +x SCRIPT_FILE.sh
    

    Pour les utilisateurs Windows, vérifiez que les scripts ont des autorisations d’exécution :

    git update-index --chmod=+x SCRIPT_FILE.sh
    
  2. 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
    
  3. Créez le hook de pré-réception sur l’instance GitHub Enterprise Server.

Test des scripts pré-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.

  1. Vérifiez que Docker est installé localement.

  2. Créez un fichier Dockerfile.dev 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"]
    
  3. Créez un script de pré-réception de test nommé always_reject.sh. 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
    
  4. Vérifiez que les scripts always_reject.sh ont des autorisations d’exécution :

    chmod +x always_reject.sh
    
  5. À partir du répertoire contenant Dockerfile.dev, 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
    
  6. 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
    
  7. Copiez le hook de pré-réception de test always_reject.sh dans le conteneur de données :

    docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
    
  8. Exécutez un conteneur d’applications qui exécute sshd et exécute le hook. Notez l’ID de conteneur retourné :

    $ docker run -d -p 52311:22 --volumes-from data pre-receive.dev
    > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
    
  9. 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 .
    
  10. Modifiez le dépôt distant d’un dépôt de test et poussez sur le dépôt test.git dans le conteneur Docker. Cet exemple utilise git@github.com:octocat/Hello-World.git, 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