Me gustaría ejecutar pruebas unitarias antes de cada envío de git y, si las pruebas fallan, cancelar el envío, pero ni siquiera puedo encontrar el gancho pre-push, solo hay pre-commit y pre-rebase.
Me gustaría ejecutar pruebas unitarias antes de cada envío de git y, si las pruebas fallan, cancelar el envío, pero ni siquiera puedo encontrar el gancho pre-push, solo hay pre-commit y pre-rebase.
Respuestas:
Prefiero ejecutar la prueba en un pre-commit-hook. Porque el cambio ya está registrado al comprometerse. Empujar y tirar solo intercambia información sobre cambios ya registrados. Si una prueba falla, ya tendrá una revisión "rota" en su repositorio. Ya sea que lo esté presionando o no.
Git consiguió el pre-push
gancho en el 1.8.2
lanzamiento.
pre-push
Script de muestra : https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
Notas de la versión 1.8.2 que hablan sobre el nuevo gancho pre-push: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Git obtuvo el gancho pre-push en la versión 1.8.2.
Los ganchos previos al empuje son lo que necesitaba junto con los ganchos previos al compromiso. Además de proteger una sucursal, también pueden proporcionar seguridad adicional combinada con ganchos de confirmación previa.
Y para ver un ejemplo sobre cómo usar (tomado, adoptado y mejorado de esta bonita entrada )
Ejemplo simple para iniciar sesión en vagrant, ejecutar pruebas y luego presionar
#!/bin/bash
# Run the following command in the root of your project to install this pre-push hook:
# cp git-hooks/pre-push .git/hooks/pre-push; chmod 700 .git/hooks/pre-push
CMD="ssh vagrant@192.168.33.10 -i ~/.vagrant.d/insecure_private_key 'cd /vagrant/tests; /vagrant/vendor/bin/phpunit'"
protected_branch='master'
# Check if we actually have commits to push
commits=`git log @{u}..`
if [ -z "$commits" ]; then
exit 0
fi
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [[ $current_branch = $protected_branch ]]; then
eval $CMD
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "failed $CMD"
exit 1
fi
fi
exit 0
Como puede ver, el ejemplo usa una rama protegida, sujeta al gancho pre-push.
Si está utilizando la línea de comandos, la forma más sencilla de hacerlo es escribir un script push que ejecute sus pruebas unitarias y, si tienen éxito, complete el push.
Editar
A partir de git 1.8.2, esta respuesta está desactualizada. Vea la respuesta de manojlds arriba.
No hay un gancho para ello, porque un push no es una operación que modifica su repositorio.
Sin embargo, puede hacer los controles en el lado receptor, en el post-receive
gancho. Ahí es donde normalmente rechazaría un empujón entrante. La ejecución de pruebas unitarias puede ser un poco intensiva para hacer en un gancho, pero eso depende de usted.
Para el registro, hay un parche para Git 1.6 que agrega un gancho pre-push . No sé si funciona contra 1.7.
En lugar de meterse con eso, puede ejecutar un script push como lo recomienda @kubi. También puede convertirlo en una tarea de Rake para que esté en su repositorio. ruby-git podría ayudar con esto. Si verifica el repositorio de destino, puede ejecutar pruebas solo al enviarlo al repositorio de producción.
Finalmente, puede ejecutar sus pruebas en su pre-commit
gancho, pero verifique con qué rama se está comprometiendo. Entonces podría tener, digamos, una production
rama que requiera que todas las pruebas pasen antes de aceptar una confirmación, pero master
no le importa. limerick_rake puede ser útil en ese escenario.
El script vinculado por la respuesta altamente votada muestra los parámetros, etc. del pre-push
gancho ( $1
es el nombre remoto, $2
URL) y cómo acceder a las confirmaciones (las líneas read
de stdin tienen estructura <local ref> <local sha1> <remote ref> <remote sha1>
)
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
if [ "$remote_sha" = $z40 ]
then
# New branch, examine all commits
range="$local_sha"
else
# Update to existing branch, examine new commits
range="$remote_sha..$local_sha"
fi
# Check for WIP commit
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
if [ -n "$commit" ]
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0