Skip to main content

Crear un script de ganchos de pre-recepción

Usa los scripts de los ganchos de pre-recepción para crear requisitos para aceptar o rechazar una subida en función de los contenidos.

Puede ver ejemplos de enlaces de recepción previa para GitHub Enterprise Server en el repositorio github/platform-samples.

Escribir un script de ganchos de pre-recepción

Un script de ganchos de pre-recepción se ejecuta en un ambiente de ganchos de pre-recepción en tu instancia de GitHub Enterprise Server. Cuando creas un script de gancho de pre-recepción, considera las entradas, resultados, estado de salida y variables de ambiente.

Entrada (stdin)

Después de que tenga lugar un envío de cambios y antes de que se actualice cualquier referencia para el repositorio remoto, el proceso git-receive-pack en tu instancia de GitHub Enterprise Server invoca el script de gancho de pre-recepción. La entrada estándar para el script, stdin, es una cadena que contiene una línea para cada referencia que se va a actualizar. Cada línea contiene el nombre anterior del objeto para la referencia, el nombre nuevo del objeto para la referencia, y el nombre completo de la referencia.

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

Esta secuencia representa los siguientes argumentos.

ArgumentoDescripción
<old-value>Nombre del objeto anterior almacenado en la referencia.
Al crear una referencia nueva, el valor es de 40 ceros.
<new-value>Nombre del objeto nuevo que se va a almacenar en la referencia.
Cuando se elimina una referencia, el valor es de 40 ceros.
<ref-name>El nombre completo de la referencia.

Para obtener más información sobre git-receive-pack, consulta git-receive-pack en la documentación de Git. Para obtener más información sobre las referencias, consulta Referencias de Git en Pro Git.

Salida (stdout)

La salida estándar del script, stdout, se devuelve al cliente. El usuario podrá ver cualquier instrucción de tipo echo en la línea de comandos o la interfaz de usuario.

Estado de salida

El estado de salida de un script de pre-recepción determina si la subida se aceptará.

Valor del estado de salidaAcción
0La subida será aceptada.
distinto de ceroLa subida será rechazada.

Variables de entorno

Además de la entrada estándar del script de enlace de recepción previa, stdin, GitHub Enterprise Server pone a disposición las siguientes variables en el entorno Bash para la ejecución del script. Para obtener más información sobre el stdin script de enlace de recepción previa, consulte "Entrada (stdin)".

Hay diversas variables de ambiente disponibles para tu script de gancho de pre-recepción dependiendo de lo que active a dicho script para su ejecución.

Siempre está disponible

Las siguientes variables siempre están disponibles en el ambiente de gancho de pre-recepción.

VariableDescripciónValor de ejemplo
$GIT_DIR
Ruta al repositorio remoto en la instancia/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git
$GIT_PUSH_OPTION_COUNT
El número de opciones de envío de cambios que envió el cliente con --push-option. Para obtener más información, consulta git-push en la documentación de Git.1
$GIT_PUSH_OPTION_N
Esta variable, donde N es un número entero que comienza con 0, contiene la cadena de opción de envío de cambios que envió el cliente. La primera opción que se envió se almacena en GIT_PUSH_OPTION_0, la segunda opción en GIT_PUSH_OPTION_1, etc. Para obtener más información sobre las opciones de envío de cambios, consulta git-push en la documentación de Git.abcd
$GIT_USER_AGENT
El cliente de Git que subió los cambios envía la secuencia de usuario-agentegit/2.0.0
$GITHUB_REPO_NAME
Nombre del repositorio que se está actualizando en formato NOMBRE/PROPIETARIOocto-org/hello-enterprise
$GITHUB_REPO_PUBLIC
Valor booleano que representa si el repositorio que se está actualizando es público
  • true: La visibilidad del repositorio es pública
  • false: La visibilidad del repositorio es privada o interna
$GITHUB_USER_IP
La dirección IP del cliente que inició la subida192.0.2.1
$GITHUB_USER_LOGIN
El nombre de usuario de la cuenta que inició la subidaoctocat

Disponible para subidas desde la interface web o API

La variable $GITHUB_VIA se encuentra disponible en el entorno del enlace de recepción previa cuando la actualización de la referencia que activa el enlace ocurre desde la interfaz web o la API para GitHub Enterprise Server. El valor describe la acción que actualizó la referencia.

ValueAcciónMás información
auto-merge deployment api
Fusión automática de la rama base a través del despliegue que se creó con la APIPuntos de conexión de la API de REST para implementaciones
blob#save
Cambio al contenido de un archivo en la interface webEditar archivos
branch merge api
Fusión de una rama a través de la APIPuntos de conexión de la API de REST para ramas y su configuración
branches page delete button
Borrado de una rama en la interface webCrear y eliminar ramas en tu repositorio
git refs create api
Creación de una referencia a través de la APIPuntos de conexión de la API de REST para referencias de Git
git refs delete api
Borrado de una referencia a través de la APIPuntos de conexión de la API de REST para referencias de Git
git refs update api
Actualización de una referencia a tracvés de la APIPuntos de conexión de la API de REST para referencias de Git
git repo contents api
Cambio al contenido de un archivo a través de la APIPuntos de conexión de la API de REST para el contenido del repositorio
mergeCombinación de una solicitud de incorporación de cambios mediante combinación automáticaFusionar una solicitud de cambios automáticamente
merge base into head
Actualización de la rama puntual de una rama base cuando la rama base necesita comprobaciones de estado estrictas (mediante Actualizar rama en una solicitud de incorporación de cambios, por ejemplo)Acerca de las ramas protegidas
pull request branch delete button
Eliminación de una rama puntual desde una solicitud de cambios en la interfaz webEliminar y restaurar ramas en una solicitud de extracción
pull request branch undo button
Restablecimiento de una rama puntual desde una solicitud de cambios en la interfaz webEliminar y restaurar ramas en una solicitud de extracción
pull request merge api
Combinación de una solicitud de incorporación de cambios a través de la APIPuntos de conexión de la API de REST para solicitudes de incorporación de cambios
pull request merge button
Combinación de una solicitud de cambios en la interfaz webCombinación de una solicitud de incorporación de cambios
pull request revert button
Reversión de una solicitud de extracciónRevertir una solicitud de extracción
releases delete button
Eliminación de un lanzamientoAdministrar lanzamientos en un repositorio
stafftools branch restore
Restablecimiento de una rama desde el panel de administrador del sitioAdministrar la instancia desde la interfaz del usuario web
tag create api
Creación de una etiqueta a través de la APIPuntos de conexión de la API de REST para etiquetas de Git
web branch create
Creación de una rama desde la interfaz webCrear y eliminar ramas en tu repositorio

Disponible para las fusiones de solicitudes de cambio

Las siguientes variables se encuentran disponibles en el ambiente de gancho de pre-recepción cuando la subida que activa el gancho se debe a la fusión de una solicitud de cambios.

VariableDescripciónValor de ejemplo
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN
Nombre de usuario de la cuenta que creó la solicitud de cambiosoctocat
$GITHUB_PULL_REQUEST_HEAD
Nombre de la rama puntual de la solicitud de incorporación de cambios, con el formato USERNAME:BRANCHoctocat:fix-bug
$GITHUB_PULL_REQUEST_BASE
Nombre de la rama base de la solicitud de incorporación de cambios, con el formato USERNAME:BRANCHoctocat:main

Disponible para las subidas utilizando autenticación por SSH

VariableDescripciónValor de ejemplo
$GITHUB_PUBLIC_KEY_FINGERPRINT
La huella dactilar de la llave pública para el usuario que subió los cambiosa1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6

Establecer permisos y subidas a un ganchos de pre-recepción para GitHub Enterprise Server

Un script de gancho de pre-recepción figura en un repositorio de tu instancia de GitHub Enterprise Server. Un administrador del sitio debe tener en cuenta los permisos del repositorio y garantizar que solo los usuarios correspondientes tengan acceso.

Recomendamos los ganchos de consolidación a un solo repositorio. Si el repositorio del enlace consolidado es público, puede usar README.md para explicar la aplicación de políticas. Además, las contribuciones pueden aceptarse mediante solicitudes de extracción. Sin embargo, los ganchos de pre-recepción solo pueden agregarse desde la rama por defecto. Para un flujo de trabajo de prueba, se deben usar las bifurcaciones del repositorio con la configuración.

  1. Para usuarios de Mac, asegúrate de que los scripts tengan permisos de ejecución:

    sudo chmod +x SCRIPT_FILE.sh
    

    Para usuarios de Windows, asegúrate de que los scripts tengan permisos de ejecución:

    git update-index --chmod=+x SCRIPT_FILE.sh
    
  2. Confirma y sube al repositorio designado para los ganchos de pre-recepción en tu instancia de GitHub Enterprise Server.

    git commit -m "YOUR COMMIT MESSAGE"
    git push
    
  3. Cree el enlace de recepción previa en la instancia de GitHub Enterprise Server.

Probar scripts de pre-recepción localmente

Puedes probar un script de gancho de pre-recepción localmente antes de que lo crees o actualices en tu instancia de GitHub Enterprise Server. Un método es crear un entorno de Docker local para que actúe como un repositorio remoto que pueda ejecutar el gancho de pre-recepción.

  1. Asegúrese de que Docker está instalado localmente.

  2. Cree un archivo denominado Dockerfile.dev que contenga:

    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. Cree un script de recepción previa de prueba denominado always_reject.sh. Este script del ejemplo rechazará todas las subidas, lo cual es útil para bloquear un repositorio:

    #!/usr/bin/env bash
    
    echo "error: rejecting all pushes"
    exit 1
    
  4. Asegúrese de que los scripts always_reject.sh tengan permisos de ejecución:

    chmod +x always_reject.sh
    
  5. Desde el directorio que contiene Dockerfile.dev, compile una imagen:

    $ 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. Ejecutar un contenedor de datos que contiene una clave SSH generada:

    docker run --name data pre-receive.dev /bin/true
    
  7. Copie el enlace always_reject.sh de recepción previa de prueba en el contenedor de datos:

    docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
    
  8. Ejecute un contenedor de la aplicación que ejecute sshd y ejecute el enlace. Toma nota del id del contenedor que se devolvió:

    $ docker run -d -p 52311:22 --volumes-from data pre-receive.dev
    > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
    
  9. Copilar la clave SSH generada desde el contenedor de datos hasta la máquina local:

    docker cp data:/home/git/.ssh/id_ed25519 .
    
  10. Modifique el repositorio remoto de un repositorio de prueba e insértelo en el repositorio test.git dentro del contenedor de Docker. En este ejemplo se usa git@github.com:octocat/Hello-World.git, pero puede usar cualquier repositorio que desee. Este ejemplo asume que tu máquina local (127.0.01) es el puerto vinculante 52311, pero puedes usar una dirección IP diferente si el docker está ejecutándose en una máquina remota.

    $ 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'
    

    Observa que la subida fue rechazada después de ejecutar el ganchos de pre-recepción y de hace eco la salida del script.

Información adicional