So konfigurieren Sie den Git Post Commit Hook

126

Wie kann ein Build von Jenkins aus ausgelöst werden?
Wie konfiguriere ich Git Post Commit Hook?

Meine Anforderung ist, dass bei Änderungen im Git-Repository für ein bestimmtes Projekt automatisch der Jenkins-Build für dieses Projekt gestartet wird.

Im Jenkins-Trigger-Build-Abschnitt habe ich den Trigger-Build remote ausgewählt.
Im .gitVerzeichnis befindet sich das Hooks-Verzeichnis, in dem die Post-Commit-Datei konfiguriert werden muss.
Ich bin verwirrend, wie man von dort aus einen Build auslöst (ich weiß, dass wir teilweise den Befehl curl verwenden sollten).


curl cmbuild.aln.com/jenkins/view/project name/job/myproject/buildwithparameters?Branch=feat-con

Ich habe diesen Befehl in mein Git-Server-Hooks-Verzeichnis gestellt (Post-Commit-Hook).
Immer wenn die Änderungen im Repository vorgenommen werden, wird die automatische Erstellung ausgeführt.

Ich möchte das Änderungsset einchecken, ob in mindestens einer Java-Datei der Build gestartet werden soll.
Angenommen, die Entwickler haben nur XML-Dateien oder Eigenschaftendateien geändert, die der Build nicht starten soll.
Zusammen mit an xml, dass die .javaDateien wird die Build starten soll.

Phanikumar Raja
quelle
Ich habe meine Antwort bearbeitet, um den zweiten Teil Ihrer Frage zu beantworten.
VonC

Antworten:

164

Wie unter " Polling muss sterben: Auslösen von Jenkins-Builds über einen Git-Hook " erwähnt, können Sie Jenkins über ein neues Commit benachrichtigen:

Mit dem neuesten Git-Plugin 1.1.14 (das ich gerade erst veröffentlicht habe) können Sie dies jetzt einfacher tun, indem Sie einfach den folgenden Befehl ausführen:

curl http://yourserver/jenkins/git/notifyCommit?url=<URL of the Git repository>

Dadurch werden alle Jobs gescannt, die zum Auschecken der angegebenen URL konfiguriert sind. Wenn sie auch mit Abfragen konfiguriert sind, wird die Abfrage sofort ausgelöst (und wenn dadurch eine Änderung gefunden wird, die einen Build wert ist, wird nacheinander ein Build ausgelöst. )

Dadurch kann ein Skript gleich bleiben, wenn Jobs in Jenkins kommen und gehen.
Wenn Sie mehrere Repositorys unter einer einzigen Repository-Hostanwendung (z. B. Gitosis) haben, können Sie ein einzelnes Post-Receive-Hook-Skript für alle Repositorys freigeben. Schließlich erfordert diese URL auch für gesicherte Jenkins keine Authentifizierung, da der Server nichts direkt verwendet, was der Client sendet. Es wird eine Abfrage ausgeführt, um zu überprüfen, ob eine Änderung vorliegt, bevor ein Build tatsächlich gestartet wird.

Wie hier erwähnt , stellen Sie sicher , die richtige Adresse für Ihren Jenkins - Server zu verwenden:

Da wir Jenkins als eigenständigen Webserver auf Port 8080 ausführen, sollte die URL ohne Folgendes lauten /jenkins:

http://jenkins:8080/git/notifyCommit?url=git@gitserver:tools/common.git

Um diesen letzten Punkt zu bekräftigen, fügt ptha in den Kommentaren hinzu :

Es mag offensichtlich sein, aber ich hatte Probleme mit:

curl http://yourserver/jenkins/git/notifyCommit?url=<URL of the Git repository>. 

Der URL- Parameter sollte genau mit der Repository-URL Ihres Jenkins-Jobs übereinstimmen .
Beim Kopieren von Beispielen habe ich in unserem Fall das Protokoll weggelassen ssh://und es hat nicht funktioniert.


Sie können auch einen einfachen Post-Receive-Hook verwenden, wie in " Push-basierte Builds mit Jenkins und GIT ".

#!/bin/bash
/usr/bin/curl --user USERNAME:PASS -s \

http://jenkinsci/job/PROJECTNAME/build?token=1qaz2wsx

Konfigurieren Sie Ihren Jenkins-Job so, dass er Builds remote auslösen und ein Authentifizierungstoken verwenden kann ( 1qaz2wsxin diesem Beispiel).

Dies ist jedoch ein projektspezifisches Skript, und der Autor erwähnt eine Möglichkeit, es zu verallgemeinern.
Die erste Lösung ist einfacher, da sie nicht von der Authentifizierung oder einem bestimmten Projekt abhängt.


Ich möchte in Änderungssatz einchecken, ob mindestens eine Java-Datei vorhanden ist, die der Build starten soll.
Angenommen, die Entwickler haben nur XML-Dateien oder Eigenschaftendateien geändert, dann sollte der Build nicht gestartet werden.

Grundsätzlich kann Ihr Build-Skript:

  • Fügen Sie git notesbeim ersten Aufruf eine Build-Notiz (siehe ) ein
  • Rufen Sie bei den nachfolgenden Aufrufen die Liste der Commits zwischen HEADIhrem Build-Kandidaten für den Build und dem Commit ab, auf das durch git notes'build' ( git show refs/notes/build) verwiesen wird : git diff --name-only SHA_build HEAD.
  • Ihr Skript kann diese Liste analysieren und entscheiden, ob der Build fortgesetzt werden soll.
  • Erstellen / verschieben Sie in jedem Fall Ihr git notes' build' nach HEAD.

Mai 2016: cwhsu weist in den Kommentaren auf folgende mögliche URL hin:

Sie können nur verwenden, curl --user USER:PWD http://JENKINS_SERVER/job/JOB_NAME/build?token=YOUR_TOKENwenn Sie die Trigger-Konfiguration in Ihrem Artikel festlegen

http://i.imgur.com/IolrOOj.png


Juni 2016 polaretto weist darauf hin , in den Kommentaren :

Ich wollte hinzufügen, dass Sie mit ein wenig Shell-Scripting die manuelle URL-Konfiguration vermeiden können, insbesondere wenn Sie viele Repositorys in einem gemeinsamen Verzeichnis haben.
Zum Beispiel habe ich diese Parametererweiterungen verwendet, um den Repo-Namen zu erhalten

repository=${PWD%/hooks}; 
repository=${repository##*/} 

und dann benutze es wie:

curl $JENKINS_URL/git/notifyCommit?url=$GIT_URL/$repository
VonC
quelle
hi von wie du beim ersten aufruf gesagt hast ich muss ein build notes setzen. mein erster aufruf ist das lesen der .java datei wann immer der entwickler die änderungen in git repo überträgt. Ich bin neu in all diesen Dingen, deshalb frage ich jeden Schritt. Bitte macht es nichts aus und ich muss diese Aufgabe erledigen.
Phanikumar Raja
Das ist sehr hilfreich für mich. Ich habe Git Hook mit Hilfe dieses Themas geschrieben. Tnx Jungs!
Kirill Bazarov
Ich musste den Curl-Aufruf zur Post-Receive-Datei hinzufügen, was aus dieser Antwort nicht ganz klar hervorgeht. Trotzdem sehr hilfreich!
Magnilex
1
@IgorGanapolsky im Hooks-Ordner Ihres Bare Repo, der Commits erhält und Jenkins rufen muss: yourRepo.git/hooks/post-receive
VonC
2
Es mag offensichtlich sein, aber ich hatte Probleme mit : curl http://yourserver/jenkins/git/notifyCommit?url=<URL of the Git repository>. Der URL- Parameter sollte genau mit der Repository-URL Ihres Jenkins-Jobs übereinstimmen . Beim Kopieren von Beispielen habe ich das Protokoll weggelassen , in unserem Fall ssh: // und es hat nicht funktioniert.
ptha
17

Hoffe das hilft: http://nrecursions.blogspot.in/2014/02/how-to-trigger-jenkins-build-on-git.html

Es ist nur eine Frage der Verwendung curl, um einen Jenkins-Job mithilfe der von git bereitgestellten Git-Hooks auszulösen.
Der Befehl

curl http://localhost:8080/job/someJob/build?delay=0sec

kann einen Jenkins-Job ausführen, wobei someJobder Name des Jenkins-Jobs lautet.

Suchen Sie nach dem hooksOrdner in Ihrem versteckten .git-Ordner. Benennen Sie die post-commit.sampleDatei in um post-commit. Öffnen Sie es mit Notepad, entfernen Sie die : NothingZeile und fügen Sie den obigen Befehl ein.

Das ist es. Immer wenn Sie ein Commit durchführen, löst Git die in der Datei definierten Post-Commit-Befehle aus.

Nav
quelle
Nach dem Festschreiben von der Entwicklungsmaschine wird Post-Receive aufgerufen, nicht Post-Commit. Überprüft durch Einfügen von Protokollanweisungen in beide Hooks. Lese ich die Dokumente falsch, sollte es nicht ein Post-Commit sein, das aufgerufen wird?
Shirish Hirekodi
@ Shirish: Das ist seltsam. Vielleicht machen Sie etwas anders
Nav
Dies wird erfolgreich erstellt, wenn ich die letzte Änderung festgeschrieben habe, aber nicht erstellt, wenn ich Änderungen festschreibe ... ???
3

Da die vorherige Antwort ein Beispiel dafür gezeigt hat, wie der vollständige Hook aussehen könnte, ist hier der Code meines funktionierenden Post-Receive-Hooks:

#!/usr/bin/python

import sys
from subprocess import call

if __name__ == '__main__':
    for line in sys.stdin.xreadlines():
        old, new, ref = line.strip().split(' ')
        if ref == 'refs/heads/master':
            print "=============================================="
            print "Pushing to master. Triggering jenkins.        "
            print "=============================================="
            sys.stdout.flush()
            call(["curl", "-sS", "http://jenkinsserver/git/notifyCommit?url=ssh://user@gitserver/var/git/repo.git"])

In diesem Fall löse ich Jenkins-Jobs nur aus, wenn ich auf Master und nicht auf andere Zweige drücke.

Zitrax
quelle
1
Wie bindet man dieses Python-Skript in Jenkins? Oder führen Sie es nur einmal aus?
IgorGanapolsky
Jenkins kennt diesen Hook nicht. Der Hauptteil ist das Laden der notifyCommit-URL auf den Jenkins-Server, wodurch eine Umfrage ausgelöst wird. Ich denke, das Polling ist aktiviert, aber ohne Zeitplan auf der Jenkins-Seite.
Zitrax
Wo befindet sich dieses Python-Skript? Ich
gehe
1
Späte Antwort - aber der Skriptspeicherort befindet sich auf dem Git-Server in Hooks / Post-Receive. Lesen Sie mehr über Git Hooks, um mehr zu erfahren.
Zitrax
3

Ich möchte zu den obigen Antworten hinzufügen, dass es etwas schwieriger wird, wenn die Jenkins-Autorisierung aktiviert ist.

Nach dem Aktivieren wurde eine Fehlermeldung angezeigt, dass ein anonymer Benutzer eine Leseberechtigung benötigt.

Ich habe zwei mögliche Lösungen gesehen:

1: Ändern meines Hakens auf:

curl --user name:passwd -s http://domain?token=whatevertokenuhave

2: Festlegen der projektbasierten Autorisierung.

Die ersteren Lösungen haben den Nachteil, dass ich mein passwd in der Hook-Datei verfügbar machen musste. In meinem Fall inakzeptabel.

Der zweite funktioniert für mich. In den globalen Authentifizierungseinstellungen musste ich Overall> Read for Anonymous user aktivieren. In dem Projekt, das ich auslösen wollte, musste ich Job> Erstellen und Job> Für Anonym lesen aktivieren.

Dies ist immer noch keine perfekte Lösung, da Sie das Projekt jetzt in Jenkins ohne Anmeldung sehen können. Es gibt vielleicht eine noch bessere Lösung mit dem früheren Ansatz mit http-Login, aber ich habe es nicht herausgefunden.

anhoppe
quelle