Wie man Node.js und GitHub-Webhooks zum Synchronisieren von Remote-Projekten verwendet

0 Aktien
0
0
0
0

Einführung

Bei der Zusammenarbeit mehrerer Entwickler an Projekten kann es frustrierend sein, wenn jemand Änderungen in ein Repository hochlädt und ein anderer kurz darauf an einer älteren Codeversion arbeitet. Solche Fehler machen es sinnvoll, ein Skript einzurichten, das die Repositories synchronisiert. Diese Methode lässt sich auch in einer Produktionsumgebung anwenden, um Hotfixes und andere Änderungen schnell durchzuführen.

Es gibt zwar auch andere Lösungen, um diese spezielle Aufgabe zu erledigen, aber das Schreiben eines eigenen Skripts ist eine flexible Option, die Raum für zukünftige Anpassungen lässt.

GitHub ermöglicht die Konfiguration von Webhooks für Ihre Repositories. Dabei handelt es sich um Ereignisse, die HTTP-Anfragen senden, sobald bestimmte Ereignisse eintreten. Beispielsweise können Sie sich per Webhook benachrichtigen lassen, wenn jemand einen Pull Request erstellt oder neuen Code hochlädt.

In dieser Anleitung erstellen Sie einen Node.js-Server, der auf GitHub-Webhook-Benachrichtigungen reagiert, sobald Sie oder jemand anderes Code auf GitHub hochlädt. Dieses Skript aktualisiert automatisch ein Repository auf einem Remote-Server mit der neuesten Codeversion, sodass Sie sich nicht mehr auf dem Server anmelden müssen, um neue Commits durchzuführen.

Voraussetzungen
  • Ein eingerichteter Ubuntu-Server inklusive eines Nicht-Root-Benutzers mit sudo-Berechtigungen und einer Firewall.
  • Git ist auf Ihrem lokalen Rechner installiert.
  • Node.js und npm werden mithilfe des offiziellen PPA auf dem Remote-Server installiert.
  • Ein Repository auf GitHub, das Ihren Projektcode enthält.

Schritt 1 – Webhook einrichten

Wir beginnen mit der Konfiguration eines Hooks für Ihr Repository. Dieser Schritt ist wichtig, da GitHub sonst nicht weiß, welche Ereignisse gesendet werden sollen und wohin diese gesendet werden sollen. Zuerst erstellen wir den Webhook und anschließend einen Server, der auf dessen Anfragen antwortet.

Melden Sie sich in Ihrem GitHub-Konto an und navigieren Sie zu dem Repository, das Sie überwachen möchten. Klicken Sie in der Menüleiste oben auf der Repository-Seite auf den Tab „Einstellungen“ und anschließend im linken Navigationsmenü auf „Webhooks“. Klicken Sie rechts oben auf „Webhook hinzufügen“ und geben Sie Ihr Kontopasswort ein, wenn Sie dazu aufgefordert werden. Die Seite sollte nun wie folgt aussehen:

  • Geben Sie im Feld „Payload-URL“ http://your_server_ip:8080 ein. Dies ist die Adresse und der Port des Node.js-Servers, den wir in Kürze beschreiben werden.
  • Ändern Sie den Inhaltstyp in application/json. Das von uns geschriebene Skript erwartet JSON-Daten und kann keine anderen Datentypen verarbeiten.
  • Geben Sie unter „Geheimnis“ ein geheimes Passwort für diesen Webhook ein. Sie verwenden dieses Passwort auf Ihrem Node.js-Server, um Anfragen zu authentifizieren und sicherzustellen, dass sie von GitHub gesendet werden.
  • Um festzulegen, welche Ereignisse diesen Webhook auslösen sollen, wählen Sie einfach das Push-Ereignis aus. Wir benötigen nur das Push-Ereignis, da der Code dann aktualisiert und mit unserem Server synchronisiert werden muss.
  • Aktivieren Sie das Kontrollkästchen „Aktiv“.
  • Überprüfen Sie die Felder und klicken Sie auf „Webhook hinzufügen“, um ihn zu erstellen.

Der Ping wird zunächst fehlschlagen, aber keine Sorge, Ihr Webhook ist jetzt konfiguriert. Klonen wir nun das Repository auf den Server.

Schritt 2 – Klonen Sie das Repository auf den Server

Unser Skript kann ein Repository aktualisieren, aber nicht initialisieren. Das holen wir jetzt nach. Melden Sie sich auf Ihrem Server an:

ssh sammy@your_server_ip

Stelle sicher, dass du dich in deinem Home-Verzeichnis befindest. Verwende dann Git, um dein Repository zu klonen. Ersetze dabei deinen GitHub-Benutzernamen durch „sammy“ und deinen GitHub-Projektnamen durch „hello_hapi“.

cd
git clone https://github.com/sammy/hello_hapi.git

Dadurch wird ein neues Verzeichnis erstellt, das Ihr Projekt enthält. Sie werden dieses Verzeichnis im nächsten Schritt verwenden.

Nachdem Ihr Projekt geklont wurde, können Sie das Webhook-Skript erstellen.

Schritt 3 – Webhook-Skript erstellen

Wir erstellen einen eigenen Server, der Webhook-Anfragen von GitHub empfängt. Dazu schreiben wir ein Node.js-Skript, das einen Webserver auf Port 8080 startet. Der Server empfängt Webhook-Anfragen, überprüft das von uns angegebene Geheimnis und lädt die neueste Codeversion von GitHub herunter.

Gehen Sie zu Ihrem Hauptmenü:

cd ~

Erstellen Sie ein neues Verzeichnis für Ihr Webhook-Skript mit dem Namen NodeWebhooks:

mkdir ~/NodeWebhooks

Wechseln Sie anschließend in das neue Verzeichnis:

cd ~/NodeWebhooks

Erstellen Sie eine neue Datei namens webhook.js im Verzeichnis NodeWebhooks.

nano webhook.js

Fügen Sie diese beiden Zeilen zum Skript hinzu:

/* Your codevar secret = "your_secret_here";
var repo = "/home/sammy/hello_hapi";... */

Die erste Zeile definiert eine Variable, die das in Schritt 1 erstellte Geheimnis speichert und bestätigt, dass die Anfragen von GitHub stammen. Die zweite Zeile definiert eine Variable, die den vollständigen Pfad zum Repository auf Ihrer lokalen Festplatte enthält, das Sie aktualisieren möchten. Dieser Pfad sollte auf das Repository verweisen, das Sie in Schritt 2 ausgecheckt haben.

Fügen Sie als Nächstes diese Zeilen hinzu, die die http- und crypto-Bibliotheken in das Skript importieren. Wir verwenden diese, um unseren Webserver und den geheimen Hash zu erstellen, damit wir ihn mit dem von GitHub erhaltenen Hash vergleichen können:

let http = require('http');
let crypto = require('crypto');

Fügen Sie als Nächstes die child_process-Bibliothek hinzu, damit Sie Shell-Befehle aus Ihrem Skript ausführen können:

const exec = require('child_process').exec;

Fügen Sie als Nächstes diesen Code hinzu, um einen neuen Webserver zu definieren, der GitHub-Webhook-Anfragen verarbeitet und, falls eine Anfrage gültig ist, die neue Version des Codes herunterlädt:

http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
if (req.headers['x-hub-signature'] == sig) {
exec('cd ' + repo + ' && git pull');
}
});
res.end();
}).listen(8080);

Die Funktion `http.createServer()` startet einen Webserver auf Port 8080, der eingehende Anfragen von GitHub entgegennimmt. Aus Sicherheitsgründen überprüfen wir, ob das in der Anfrage enthaltene Geheimnis mit dem in Schritt 1 beim Erstellen des Webhooks angegebenen Geheimnis übereinstimmt. Dieses Geheimnis wird im Header `x-hub-signature` als SHA1-Hashwert gesendet. Daher berechnen wir den Hashwert unseres Geheimnisses und vergleichen ihn mit dem von GitHub übermittelten Wert.

Wenn die Anfrage gültig ist, führen wir einen Shell-Befehl aus, um unser lokales Repository mit git pull zu aktualisieren.

Das fertige Skript sieht folgendermaßen aus:

const secret = "your_secret_here";
const repo = "~/your_repo_path_here/";
const http = require('http');
const crypto = require('crypto');
const exec = require('child_process').exec;
http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
if (req.headers['x-hub-signature'] == sig) {
exec('cd ' + repo + ' && git pull');
}
});
res.end();
}).listen(8080);

Wenn Sie der Anleitung zur Ersteinrichtung des Servers gefolgt sind, müssen Sie diesem Webserver die Kommunikation mit dem externen Web ermöglichen, indem Sie den Datenverkehr auf Port 8080 zulassen:

sudo ufw allow 8080/tcp

Jetzt, wo unser Skript steht, wollen wir sicherstellen, dass es auch ordnungsgemäß funktioniert.

Schritt 4 – Webhook-Test

Wir können unseren Webhook mit Node testen, indem wir ihn über die Kommandozeile ausführen. Starten Sie das Skript und lassen Sie den Prozess in Ihrem Terminal geöffnet:

cd ~/NodeWebhooks
nodejs webhook.js

Kehren Sie zu Ihrer Projektseite auf GitHub.com zurück. Klicken Sie in der Menüleiste oben auf Ihrer Repository-Seite auf den Tab „Einstellungen“ und anschließend im linken Navigationsmenü auf „Webhooks“. Klicken Sie neben dem in Schritt 1 eingerichteten Webhook auf „Bearbeiten“. Scrollen Sie nach unten, um den Abschnitt „Letzte Commits“ anzuzeigen (siehe Abbildung unten).

Klicken Sie auf die drei Punkte rechts, um die Schaltfläche „Erneut senden“ aufzurufen. Während der Node-Server läuft, klicken Sie auf „Erneut senden“, um die Anfrage erneut zu senden. Nachdem Sie die Anfrage bestätigt haben, erhalten Sie eine Erfolgsmeldung. Dies wird durch den Antwortcode 200 OK angezeigt, nachdem der Ping erneut zugestellt wurde.

Wir können nun sicherstellen, dass unser Skript im Hintergrund ausgeführt wird und beim Systemstart automatisch startet. Mit Strg+C wird der Node-Webhook-Server gestoppt.

Schritt 5 – Webhook als Systemd-Dienst installieren

systemd ist der Aufgabenmanager von Ubuntu zur Steuerung von Diensten. Wir werden einen Dienst starten, der es uns ermöglicht, unser Webhook-Skript beim Systemstart auszuführen und ihn anschließend wie jeden anderen Dienst mit systemd-Befehlen zu verwalten.

Erstellen Sie zunächst eine neue Servicedatei:

sudo nano /etc/systemd/system/webhook.service

Fügen Sie der Dienstdatei die folgende Konfiguration hinzu, die systemd mitteilt, wie das Skript ausgeführt werden soll. Dadurch wird systemd mitgeteilt, wo sich unser Node-Skript befindet, und unser Dienst wird beschrieben.

Ersetzen Sie Sami unbedingt durch Ihren Benutzernamen.

[Unit]
Description=Github webhook
After=network.target
[Service]
Environment=NODE_PORT=8080
Type=simple
User=sammy
ExecStart=/usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
Restart=on-failure
[Install]
WantedBy=multi-user.target

Aktivieren Sie den neuen Dienst so, dass er beim Systemstart automatisch gestartet wird:

sudo systemctl enable webhook.service

Starten Sie nun den Dienst:

sudo systemctl start webhook

Stellen Sie sicher, dass der Dienst gestartet ist:

sudo systemctl status webhook

Sie sehen die folgende Ausgabe, die anzeigt, dass der Dienst aktiv ist:

Output
● webhook.service - Github webhook
Loaded: loaded (/etc/systemd/system/webhook.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-08-17 19:28:41 UTC; 6s ago
Main PID: 9912 (nodejs)
Tasks: 6
Memory: 7.6M
CPU: 95ms
CGroup: /system.slice/webhook.service
└─9912 /usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js

Sie können nun neue Commits in Ihr Repository übertragen und die Änderungen auf Ihrem Server sehen.

Emulieren Sie das Repository von Ihrem Desktop-Gerät aus:

git clone https://github.com/sammy/hello_hapi.git

Ändern Sie eine der Dateien im Repository. Anschließend übertragen Sie die Änderung an GitHub und laden Ihren Code hoch.

git add index.js
git commit -m "Update index file"
git push origin master

Der Webhook wird aktiviert und Ihre Änderungen werden auf Ihrem Server angezeigt.

Ergebnis

Sie haben ein Node.js-Skript eingerichtet, das neue Commits automatisch in ein Remote-Repository überträgt. Mit diesem Verfahren können Sie weitere Repositories einrichten, die Sie überwachen möchten. Sie können es sogar so konfigurieren, dass beim Pushen Ihres Repositorys eine Website oder Anwendung in der Produktionsumgebung bereitgestellt wird.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Das könnte Ihnen auch gefallen