Creatief gebruik voor webhooks

Bronbeheer is de manier om software te ontwikkelen en met behulp van een repository-hostingservice kunt u uw code nog verder beheren.

Naast de vele voordelen van Bitbucket die we al hebben genoemd, kunt u ook webhooks instellen om processen te automatiseren en allerlei waarschuwingen en interacties te maken op basis van acties die in uw repository worden uitgevoerd. In dit artikel gaan we bekijken welke webhooks er zijn en hoe je ze kunt gebruiken, en we zullen een voorbeeld bekijken van het implementeren van code-implementatie via webhooks.

Wat is een Webhook?

Wanneer u bepaalde acties uitvoert in een Git-repository, hebt u de mogelijkheid een bepaald script aan te roepen. Dit wordt een haak genoemd en er zijn verschillende soorten haken in Git. U kunt bijvoorbeeld een script uitvoeren net voordat u wijzigingen in de repository doorvoert of voordat u naar de externe repository pusht.

Deze voorbeelden zijn voor een lokale repository. Bij gebruik van een repository-hostingservice zoals Bitbucket, hebt u echter de mogelijkheid om webhooks uit te voeren. Deze lijken erg op een Git-hook, maar in plaats van een script uit te voeren, stuur je een HTTP-verzoek naar een bepaalde URL, waarbij de payload varieert op basis van het type webhook.

Uw workflow verbeteren

Hoewel het niet moeilijk is, kan het implementeren van uw code op een productieserver zeer tijdrovend en een echte plaag zijn. Het is echter een noodzakelijke stap in elke moderne applicatie-ontwikkeling. In een lokale repository zou je een script kunnen maken dat je code bouwt elke keer dat je iets commit of samenvoegt met je master branch, en wanneer je met Bitbucket werkt, zou dit niet anders hoeven te zijn. Om dit te emuleren, zullen we profiteren van de POST-hook van Bitbucket.

De POST-haak instellen

De eerste stap om de POST-hook in te stellen voor een gegeven repository is om de repository op zijn plaats te hebben. Voor deze tutorial ga ik een aangepaste versie van Bootstrap's Jumbotron-voorbeeld gebruiken. Je kunt de repository van Bitbucket pakken of hem eenvoudig in je account gieten. Dit voorbeeld is hetzelfde als Bootstrap's Jumbotron, maar met behulp van RequireJS en het beheren van afhankelijkheden via npm en Bower.

Zodra je de repository op zijn plaats hebt, is het tijd om de POST-hook in te stellen. Ga naar het overzicht van de repository, navigeer naar instellingen, en ga naar de haken sectie. Selecteer voor het haaktype POST, en voer de URL in om het HTTP-verzoek te verzenden zodra de repository is gepusht. Dit is alles wat u moet doen aan de kant van Bitbucket om uw implementatieproces via webhooks te automatiseren.


Behandel het haakverzoek

Nadat je de POST-hook voor je repository hebt geconfigureerd, is het volgende dat je moet doen het vangen van het verzoek en in dit geval klonen en bouwen we de repository in het openbare HTML-pad. Hiervoor gaan we NodeJS gebruiken met ExpressJS. Laten we het script maken dat zal omgaan met het klonen, installeren, bouwen en verplaatsen van de applicatie. Het is een bash-script dat we kunnen uitvoeren vanaf onze NodeJS-server.

# / bin / bash git clone $ 1 cd tuts-webhooks npm install bower install node_modules / requirejs / bin / r.js -o build.js rm build / build.txt rm -rf / usr / share / nginx / www / tuts- webhooks.bitslice.net/html/* mv build / * /usr/share/nginx/www/tuts-webhooks.bitslice.net/html/. cd ... / rm -rf tuts-webhooks

Dit script zorgt voor alle stappen die nodig zijn om de applicatiecode te krijgen, evenals het bouwen, optimaliseren en verplaatsen van het resultaat naar de openbare serverlocatie. De $ 1 verwijst naar het eerste argument van het script, dat in dit geval de URL van de repository is. Merk echter op dat de paden zijn ingesteld op de paden in mijn server en dat de uwe waarschijnlijk anders zal zijn, dus werk ze bij zodat het script correct werkt.

Als dit script is geïnstalleerd, kunnen we het handmatig uitvoeren met de URL van de repository en een productieversie van onze website ophalen. We willen het echter niet handmatig uitvoeren, en dit is waar NodeJS en het POST-verzoek van Bitbucket zullen schitteren. Laten we een server maken die zal reageren op de POST-haakverzoek en het vorige script zal uitvoeren.

Package.json

De beschrijver voor de server die de POST-haakaanvragen behandelt, is als volgt.

"name": "WebHooksTutsPlus", "description": "Servertoepassing die wordt gebruikt voor het opvangen van verzoeken vanuit de Tuts Bitbucket Webhooks-repository.", "version": "1.0.0", "private": true, "dependencies": "body-parser": "~ 1.0.x", "express": "4.xx"

De enige afhankelijkheden voor deze eenvoudige server zijn Express en body-parser voor het afhandelen van de payload van de JSON-aanvragen.

NodeJS Server

Nu voor de eigenlijke NodeJS-server gaat de code als volgt.

var bodyParser = require ('body-parser'), express = require ('express'), app = express (); var site = require ('./routers/site'); app.use (bodyParser.json ()); app.use (bodyParser.urlencoded ()); app.get ('/', functie (req, res, next) res.send ('Hooks listener running');); app.use ('/ site', site); app.listen (9090);

Dit is een heel eenvoudige webserver die luistert naar de 9090-poort van de localhost. Op regel 10 hebben we een methode die naar de serverbasis-URL luistert en antwoordt met een tekstbericht om te controleren of de server actief is. Nu, voor het script dat de POST-hook daadwerkelijk behandelt, voeg je het volgende script toe en plaats je het in de _routers_ map.

var express = require ('express'), router = express.Router (); router.post ('/', functie (req, res, volgende) var payload = JSON.parse (req.param ('payload')), repo = payload.canon_url + payload.repository.absolute_url, exec = require ( 'child_process') .exec; exec ('./site.sh' + repo + 'site', functie (error, stdout, stderr) ); res.json (message: 'Site updated'); ); module.exports = router;

Deze router luistert naar POST-aanvragen voor de URL van de 'site'. Het bouwt gewoon de repository-URL van de payload van het verzoek en voert ons eerder gemaakte script uit met de URL van de repository. Voor de eenvoud hanteren we niet de uitvoer van de NodeJS-exec-methode of controleren we fouten in de uitvoering van het script.

Dat is het! Nu na elke push naar uw repository, zal uw site de code automatisch bouwen, optimaliseren en implementeren. Vergeet niet om het een paar minuten te geven om alle afhankelijkheden te installeren en de code te compileren.

Veiligheidsoverwegingen

OK, dat is goed: onze site wordt automatisch bijgewerkt wanneer we wijzigingen in de repository pushen. Maar op dit moment valideren we geen informatie bij het uitvoeren van het updateproces. Een van de meest elementaire controles die we kunnen en moeten uitvoeren, is de oorsprong van het verzoek en Bitbucket geeft ons de IP's waaruit de POST-hook kan komen. Met deze informatie kunnen we onze server nu aanpassen om alleen de website te updaten wanneer het verzoek van deze oorsprong komt. Voeg de volgende code toe bovenaan onze routermethode.

if (req.ip! = '131.103.20.165' && req.ip! = '131.103.20.166') res.json (message: 'Untrusted origin'); terug te keren; 

Merk op dat als Bitbucket zijn uitgaande IP's zou updaten, dit onderdeel zou moeten worden bijgewerkt. Een ander ding om rekening mee te houden is dat, althans in mijn geval, ik nginx als een omgekeerde proxy gebruik, dus op dit moment req.ip oproep zal terugkeren 127.0.0.1 en zal niet werken. Om dit op te lossen, moeten we onze server laten weten dat hij de proxy vertrouwt en het originele IP gebruikt. Eenvoudig genoeg: we hoeven alleen de volgende code boven de eerste toe te voegen app.use () bel op onze server.js.

app.enable ('trust proxy');

En dat is alles, nu onze req.ip geeft het originele IP-adres en we kunnen controleren op de uitgaande adressen van Bitbucket.

Speciale overwegingen

In dit voorbeeld wordt een NodeJS-server gebruikt om de aanvraag af te handelen en de server luistert naar de localhost's poort 9090. Daarom, om dit te laten werken, gebruik ik nginx als een reverse proxy om het externe verzoek door te geven aan de NodeJS-server. Het instellen van nginx als een omgekeerde proxy valt buiten het bestek van deze tutorial, maar het is belangrijk om een ​​gelijkwaardige configuratie te vermelden en te gebruiken tijdens het volgen. Vergeet ook niet om de npm installeren commando alvorens de server voor de eerste keer te starten.

Conclusie

Gedurende deze reeks hebben we enkele echt coole mogelijkheden en manieren gezien om te profiteren van de mogelijkheden van Bitbucket. En we hebben net het oppervlak van webhooks gekrast. Er zijn veel verschillende triggers en informatie van elke haak (lees welke andere informatie wordt doorgegeven in een POST-hook van Bitbucket), dus je kunt het bijvoorbeeld instellen om meldingen te ontvangen wanneer iemand je repository opzoekt. Of, aan de meer geavanceerde kant van het spectrum, kunt u een mobiele applicatie maken om pushmeldingen te krijgen wanneer bepaalde acties worden uitgevoerd.

Laat eventuele opmerkingen, vragen en andere feedback achter in de opmerkingen hieronder.