Erlerne Continuous Delivery mit Bitbucket Pipelines
Sten Pittet
Gastautor
In diesem Leitfaden sehen wir uns an, wie du mit Bitbucket Pipelines einen Continuous Delivery-Workflow einführen kannst. Es lohnt sich also, weiterzulesen.
Uhrzeit
30 Minuten
Zielpublikum
Du bist neu bei Continuous Deployment und/oder Bitbucket Pipelines
Der Release einer neuen Funktion ist immer ein aufregender Moment, da du deinen Kunden neue Möglichkeiten bieten kannst. Ein Release kann aber auch riskant sein und viel Vorbereitung erfordern, sodass dein Team häufigen Releases zögerlich gegenübersteht. Und je länger du wartest, desto schwieriger wird das Deployment in die Produktion. Änderungen häufen sich an, es ist schwierig, den Umfang der Änderung zu verstehen, und es wird schwierig sein, die Ursachen zu identifizieren, wenn Probleme in der Produktion auftreten.
Eine einfache Möglichkeit, deinem Team diese Angst zu nehmen und die Kosten von Software-Deployments zu senken, besteht darin, den Vorgang zu automatisieren und häufiger kleinere Änderungen zu releasen. Zum einen sparst du so die vielen Arbeitsstunden, die normalerweise in die Vorbereitung des Release investiert werden. Zum anderen minderst du das mit dem Software-Deployment verbundene Risiko, weil der Umfang der einzelnen Releases deutlich geringer ist, was die Überwachung der Umgebungen und die Fehlerbehebung vereinfacht.
Diese Deployment-Automatisierung ist mit Bitbucket Cloud problemlos möglich. Für jedes deiner Repositorys kannst du eine Pipeline konfigurieren, die deinen Code automatisch bei jedem Push erstellt, testet und in deinen Umgebungen bereitstellt. In diesem Leitfaden sehen wir uns an, wie du mit Bitbucket Pipelines einen Continuous-Delivery-Workflow einführen kannst.
Vergleich zwischen Continuous Delivery und Continuous Deployment
Mit der Continuous Delivery stellst du sicher, dass dein Code jederzeit bereit für den Release ist, auch wenn du nicht jede Änderung für die Produktion bereitstellst. Es empfiehlt sich, deine Produktion so oft wie möglich upzudaten, um zu gewährleisten, dass der Umfang der Änderungen klein bleibt, aber letztendlich steuerst du den Rhythmus deines Releases.
Beim Continuous Deployment werden neue Änderungen, die in das Repository geschoben werden, automatisch in der Produktion bereitgestellt, wenn sie die Tests bestehen. Dies setzt deine Testkultur stärker in den Vordergrund (sprich: unter Druck), aber es ist eine großartige Möglichkeit, die Feedbackschleife mit deinen Kunden zu beschleunigen.
Einführung einer Continuous-Delivery-Pipeline
In diesem Beispiel werden wir die einfache node.js-App, die wir im Tutorial zu Continuous Integration erstellt haben, erweitern, indem wir eine Continuous-Delivery-Pipeline hinzufügen, die automatisch für das Staging bereitgestellt wird, wenn der Build den Test bestanden hat. Wir sehen uns zwei verschiedene Strategien für das Produktions-Deployment an: eine mit Branches und Pull-Anfragen und die andere mit benutzerdefinierten Pipelines und manuellen Triggern.
In beiden Beispielen verwenden wir eine einfache Node.js-Anwendung, die eine Hello-World-Nachricht in deinem Browser anzeigt. Wir stellen diese Anwendung mit beiden Methoden in auf Heroku gehosteten Staging- und Produktionsumgebungen bereit.
Unsere einfache Hello World-Anwendung
Vorbereitung des Deployments auf Heroku
Registriere dich als Erstes für Heroku.
Installiere dann die Heroku-CLI.
Aktualisiere package.json so, damit es ungefähr so aussieht:
{
"name": "cdtutorial",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"test": "mocha --exit"
},
"repository": {
"type": "git",
"url": "git+ssh://git@bitbucket.org/pmmquickstartguides01/cdtutorial.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://bitbucket.org/pmmquickstartguides01/cdtutorial/issues"
},
"homepage": "https://bitbucket.org/pmmquickstartguides01/cdtutorial#readme",
"dependencies": {
"express": "^4.17.3"
},
"devDependencies": {
"mocha": "^9.2.2",
"supertest": "^6.2.2"
}
}
Aktualisiere die Datei server.js so, damit sie in etwa so aussieht:
var express = require("express");
var app = express();
app.get("/", function (req, res) {
res.send("Hello World!");
});
app.listen(process.env.PORT || 3000, function () {
console.log("Example app listening on port 3000!");
});
module.exports = app;
Beachte die Änderung von app.listen(). Dies beinhaltet jetzt process.env.Port, das von Heroku festgelegt wurde.
Füge dem Stammverzeichnis des Beispiel-Repositorys ein Procfile hinzu, indem du Folgendes ausführst:
touch Procfile
Füge dann den folgenden Text zum Procfile hinzu:
web: npm start
Logge dich bei Heroku ein, klicke auf das Benutzersymbol in der oberen rechten Ecke, klicke auf Account Setting (Kontoeinstellung) und scrolle nach unten, um nach dem API-Schlüssel zu suchen.
Füge als Nächstes eine Umgebungsvariable zu Bitbucket Pipelines hinzu, damit das Deployment auf Heroku funktioniert:
- HEROKU_API_KEY: Du findest deinen API-Schlüssel in deinem Heroku-Konto.
Gehe zu "Pipelines > Environment variables" (Pipelines > Umgebungsvariablen) in deinen Repository-Einstellungen, um diese Variable hinzuzufügen.
Einrichtung von Umgebungsvariablen für das Deployment auf Heroku
In diesem Leitfaden verwenden wir Heroku. Sicherlich ist es möglich, dieses Beispiel an andere Hosting-Dienste anzupassen. Verwende diesen Leitfaden als Heroku-Referenz.
Continuous Delivery mit Branches als Gate zur Produktion
Diese Konfiguration ist für Teams geeignet, die über spezielle Release-Branches verfügen, die einem Deployment zugeordnet werden können. Außerdem kannst du Änderungen an einer Pull-Anfrage überprüfen, bevor sie in der Produktion bereitgestellt werden.
In dieser Konfiguration verwenden wir zwei verschiedene Branches, um Deployments auszulösen:
- main: Bei jedem Push zum main-Branch wird der Code nach den Tests in einer Staging-Umgebung bereitgestellt.
- production: Code, für den ein Merge in den Produktions-Branch durchgeführt wird, wird automatisch in der Produktionsumgebung veröffentlicht.
Erstelle den Produktions-Branch in Bitbucket Cloud, indem du auf Branches klickst.
Klicke dann auf Create branch (Branch erstellen).
Gib "production" ein und klicke auf Create (Erstellen).
Führe über das Stammverzeichnis des Beispiel-Repositorys Folgendes aus:
heroku create --remote staging
git push staging main
heroku create --remote production
git push production main
Um zu prüfen, ob dies ordnungsgemäß funktioniert hat, rufe Heroku in einem Browser auf und sieh nach, ob zwei Apps aufgeführt sind.
Führe auch Folgendes aus:
git remote -vv
In den erwarteten Ergebnissen werden drei "Remotes" enthalten sein. Einmal für Bitbucket und zweimal für Heroku. Bei einem wird es sich um ein Staging-Remote handeln, beim anderen um ein Produktions-Remote.
wmarusiak@C02F207NML7L cdTutorial % git remote -vv
origin git@bitbucket.org:pmmquickstartguides01/cdtutorial.git (fetch)
origin git@bitbucket.org:pmmquickstartguides01/cdtutorial.git (push)
production https://git.heroku.com/young-harbor-11356.git (fetch)
production https://git.heroku.com/young-harbor-11356.git (push)
staging https://git.heroku.com/boiling-refuge-14681.git (fetch)
staging https://git.heroku.com/boiling-refuge-14681.git (push)
Konfiguriere anschließend das Deployment in der Staging-Umgebung. Zu diesem Zweck nutzen wir Branch-spezifische Pipelines zum Erstellen einer Pipeline, die bei jedem Push im main-Branch ausgeführt wird. Nimm diese Änderung in deinem Terminal vor und pushe nach origin main.
bitbucket-pipelines.yml
image: node:16
clone:
depth: full
pipelines:
branches:
main:
- step:
name: deploy_to_staging
script:
- npm install
- npm test
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/boiling-refuge-1468.git main
Achte darauf, die git-push-URL für "main" durch die Staging-URL aus git remote -vv (siehe oben) zu ersetzen.
Wir haben jetzt eine Pipeline erstellt, die nach dem Entwickeln und Testen unserer Anwendung jeden Push zunächst im main-Branch und anschließend auf Heroku bereitstellt. Der Klonabschnitt am Anfang der Konfiguration stellt sicher, dass wir einen vollständigen Klon durchführen (andernfalls könnte Heroku den Git-Push ablehnen). Verschiebe diese Konfiguration einfach zu Bitbucket, um dein erstes automatisiertes Deployment in der Staging-Umgebung zu sehen.
Eine erfolgreiche Pipeline, die unsere Anwendung für das Staging bereitstellt
Wie du vielleicht vermutet hast, müssen wir nur eine weitere Branch-Pipeline hinzufügen, damit der Produktions-Branch automatisch in der Produktionsumgebung veröffentlicht werden kann, wenn Änderungen im Produktions-Branch gemergt werden. Nimm diese Änderung in deinem Terminal vor und pushe nach origin main.
bitbucket-pipelines.yml
image: node:16
clone:
depth: full
pipelines:
branches:
main:
- step:
name: deploy_to_staging
script:
- npm install
- npm test
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/thawing-river-12585.git main
production:
- step:
name: deploy_to_production
script:
- npm install
- npm test
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/fierce-basin-45507.git production:main
Stelle sicher, dass du die git-push-URL für "main" durch die Staging-URL aus git remote -vv und die git-push-URL für die Produktion durch die production-URL aus git remote -vv ersetzt.
Wir führen die Tests erneut im Produktions-Branch durch, um vor dem Release der Anwendung sicherzustellen, dass der Build durch nichts beeinträchtigt wurde.
Unsere Pipelines sind jetzt konfiguriert. Wir können den Produktions-Branch jetzt so einschränken, dass nur Merges per Pull-Anfrage akzeptiert werden. Navigiere dazu einfach in den Repository-Einstellungen zu Workflow > Branch-Berechtigungen. Dieser Schritt ist wichtig, um zu verhindern, dass Teammitglieder Änderungen direkt von ihrem lokalen Rechner an die Produktion übermitteln.
Konfiguration der Berechtigungen des Produktions-Branch
In dem hier abgebildeten Screenshot siehst du folgende Berechtigungen:
- Niemand hat Schreibzugriff.
- Nur ein Entwickler kann einen Merge in den Branch durchführen.
Wir haben auch einen Merge-Check hinzugefügt, um sicherzustellen, dass der Quell-Branch vor dem Merge des Codes mindestens einen grünen Build hat. Dadurch können wir Build-Zeit sparen und Entwickler daran hindern, einen Merge von fehlerhaftem Code in unseren Produktions-Branch durchzuführen.
Wenn dies erledigt ist, kannst du einen Pull Request erstellen, um den Code vom Haupt- in den Produktions-Branch zu mergen und anschließend die neuen Änderungen in deiner Produktionsumgebung veröffentlichen.
Erstellung einer Pull-Anfrage für einen Merge von Änderungen in die Produktion
Sobald du die Pull-Anfrage mergst, siehst du, wie für den Produktions-Branch eine neue Pipeline ausgelöst wird.
Nach Abschluss der Pipeline werden deine neuen Änderungen erfolgreich in der Produktionsumgebung bereitgestellt.
Die Produktionsumgebung ist auf dem neuesten Stand!
Du hast nun einen Workflow für Continuous Delivery mit Bitbucket Pipelines eingerichtet und kannst Pull-Anfragen sicher verwenden, um Code für deine Kunden zu veröffentlichen.
Die endgültige Quelle dieses Beispiels findest du im unten verlinkten Repository.
Continuous Delivery mit manuellem Trigger für den Release
Diese Konfiguration ist ideal für Teams, die Trunk-basierte Entwicklung praktizieren.
Mit Bitbucket Pipelines ist es möglich, benutzerdefinierte Pipelines zu konfigurieren, die manuell ausgelöst werden können. Sie können für verschiedene Zwecke verwendet werden: für lang andauernde Tests, die du nicht bei jedem Push ausführen möchtest, oder für bestimmte Aktionen, die du selbst kontrollieren möchtest. Wir werden eine benutzerdefinierte Pipeline verwenden, um einen Continuous Delivery-Workflow einzurichten, bei dem Pushs in den Haupt-Branch automatisch in einer Staging-Umgebung bereitgestellt werden und Commits manuell für die Produktion bereitgestellt werden können.
Wir haben nun unser Staging-Deployment eingerichtet und können unserer bitbucket-pipelines.yml-Konfiguration einfach eine benutzerdefinierte Pipeline hinzufügen, mit der wir manuell den Release in die Produktion auslösen werden.
bitbucket-pipelines.yml
image: node:16
clone:
depth: full
pipelines:
branches:
main:
- step:
name: deploy_to_staging
script:
- npm install
- npm test
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/thawing-river-12585.git main
custom:
prod-deployment:
- step:
name: deploy_to_production
script:
- npm install
- npm test
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/fierce-basin-45507.git production:main
Stelle sicher, dass du die git-push-URL für "main" durch die Staging-URL aus git remote -vv und die git-push-URL für die Produktion durch die production-URL aus git remote -vv ersetzt.
Nachdem du die neue Konfiguration in dein Bitbucket-Repository gepusht hast, kannst du im Commit unter dem Bereich "Commit information" (Commit-Informationen) auf den Link Run pipeline (Pipeline ausführen) klicken, um das Deployment in die Produktion auszulösen.
Die Aktion "Run pipeline" (Pipeline ausführen) listet die verfügbaren benutzerdefinierten Pipelines auf.
Klicke einfach auf die Schaltfläche Run (Ausführen), um zur Pipeline für das Produktions-Deployment weitergeleitet zu werden, in der du die Protokolle überwachen kannst.
Im Bereich "Commit information" (Commit-Informationen) der Pipeline siehst du den Namen der verwendeten benutzerdefinierten Pipeline. Du bist jetzt bereit, deine neue Bitbucket Pipelines-Konfiguration für Continuous Delivery zu verwenden, und du kannst deine Hello World-Produktion überprüfen, um sicherzustellen, dass alles gut gelaufen ist!
Unser Hello World-Programm wurde mit einem manuellen Trigger in der Produktion bereitgestellt.
Die endgültige Quelle dieses Beispiels findest du im unten verlinkten Repository.
Diesen Artikel teilen
Nächstes Thema
Lesenswert
Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.