Je voudrais exécuter des tests unitaires avant chaque Git Push et si les tests échouent, annulez le Push, mais je n'arrive même pas à trouver le hook pré-Push.
Je préférerais exécuter le test avec un crochet de pré-validation. Parce que le changement est déjà enregistré lors de la validation. Poussez et tirez uniquement sur les informations d’échange concernant les modifications déjà enregistrées. Si un test échoue, vous avez déjà une révision "cassée" dans votre référentiel. Que vous le poussiez ou pas.
Git a eu le hook pre-Push
dans la version 1.8.2
.
Exemple de script pre-Push
: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-Push.sample
Notes de mise à jour 1.8.2 concernant le nouveau point d'ancrage pré-Push: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Git a obtenu le crochet pré-Push dans la version 1.8.2.
Les crochets de pré-push sont ce dont j'avais besoin avec les crochets de pré-validation. Outre la protection d'une branche, ils peuvent également fournir une sécurité supplémentaire combinée à des hooks de pré-validation.
Et pour un exemple sur la façon d'utiliser (pris et adopté et amélioré de cette entrée de Nice )
Exemple simple pour vous connecter à vagrant, exécuter des tests, puis Push
#!/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 [email protected] -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
Comme vous pouvez le voir, l'exemple utilise une branche protégée, sujet du hook pre-Push.
Si vous utilisez la ligne de commande, le moyen le plus simple consiste à écrire un script Push qui exécute vos tests unitaires et, s’ils réussissent, termine le Push.
Modifier
Depuis git 1.8.2, cette réponse est obsolète. Voir la réponse de manojlds ci-dessus.
Il n'y a pas de crochet pour cela, car un Push n'est pas une opération qui modifie votre référentiel.
Vous pouvez toutefois effectuer les vérifications du côté destinataire, à l’aide du crochet post-receive
. C’est là que vous rejetteriez généralement un Push entrant. Exécuter des tests unitaires peut être un peu intensif, mais c'est à vous de décider.
Pour mémoire, il y a un patch dans Git 1.6 qui ajoute un hook pré-Push . Je ne sais pas si cela fonctionne contre 1.7.
Plutôt que de jouer avec cela, vous pourriez exécuter un script Push comme @kubi recommandé. Vous pouvez également en faire une tâche Rake afin que ce soit dans votre référentiel. Ruby-git pourrait aider avec cela. Si vous vérifiez le référentiel cible, vous pouvez exécuter des tests uniquement lorsque vous appuyez sur le référentiel de production.
Enfin, vous pouvez exécuter vos tests dans votre hook pre-commit
tout en vérifiant quelle branche est validée. Ensuite, vous pourriez avoir une branche, disons une production
qui exige que tous les tests soient réussis avant d'accepter un commit, mais votre master
s'en fiche. limerick_rake peut être utile dans ce scénario.
Le script lié par la réponse hautement votée montre les paramètres, etc., au crochet pre-Push
($1
est le nom distant, $2
URL) et comment accéder aux commits (les lignes read
de stdin ont la structure <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