Archiv der Kategorie: Technologien

Low-Level: Configure Angular-Apps on different environments [How-To]

Disclaimer for german readers: Dieser Artikel beschäftigt sich mit technischen Details. Falls sie auf der Suche nach Heigh-Level-Erklärungen sind, werden Sie in andern Artikeln eher fündig.

It shouldn’t take a rebuild to reconfigure an app for a certain environment. It should be build once and in each deployed state (test, nightly, demo, pre-prod, staging, prod, etc) have the configuration that applies on the server, respectivly environment.

The most common way to configure an app in a certain environment is by using environment variables. You can easily set them through .env files in Docker, Vagrant, AWS and other service providers.

To archive that, let’s start at the server side: A JavaScript-application runs on a webserver. It consists out of plain text files. While running on a client’s browser, there is now way for the JavaScript to access server values such as environment variables during runtime.

We need to inject the values, that life inside our server into the text files of our JavaScript application.

First, prepare a file called env.template.js with the environment variables you expect.

(function (window) {
    window["env"] = window["env"] || {};

    // Environment variables TEMPLATE
    window["env"]["title"] = "${TITLE}"; 
})(this);

And again, there is no pre-existing mechanism. Here we can see, we prepare that file with placeholders ${XYZ} as strings. To inject the environment variables, that live on the server and thus can be differ from one environment to another.

To create a mechanism we need to run the following command on the server (this can be done during the deployment process to a certain environment, e.g. in an CI/CD-pipeline.

envsubst < /home/nonroot/htdocs/assets/env.template.js > /home/nonroot/htdocs/assets/env.js

What this does is, it takes all the environment variables, set to a certain value currently on the machine, and replaces all the placeholders ${XYZ} that match.

For example if there was an environment variable TITLE set to "This is a title", then any occurance of ${TITLE} inside the file would be replaced by „This is a title“ (without the quotes). After that the new resulting file is written into a new file, here

/home/nonroot/htdocs/assets/env.js

The contents of the new file would look like the following snippet shows.

(function (window) {
    window["env"] = window["env"] || {};

    // Environment variables TEMPLATE
    window["env"]["title"] = "This is a title"; 
})(this);

That is what we wanted to have. We had no pre-existing mechanism, that lets us access the environment variables on the server inside a certain environment. Now we have injected them very clean into our application.

We have them available, how to process them in our application?

There is nothing wrong with simply including the env.js file in our index.html, right into the header (of course you can export and import it, which would be slightly cleaner).


Now, if the environemnt variable TITLE was declared on the machine the scripts are running on, window['env']['title'] should hold the value, in our case "This is a title" as string. Globaly, everywhere in our application (maybe some kind of anti-pattern, you have the force. Seal it with dependency injection and so on) Easy?

Use the environment variable inside the environment files

The environment file in angular are a bit misleading. The implay, that you should have one file for each environment. I just look at environment.ts and environment.prod.ts. In the latter we can use our window[„env“] variable now.

export const environment = {
  production: true,
  title: window['env']['title'] || 'A default value for a title',
};

That’s it. Comment if you like.

GitHub Copilot: Eine leistungsfähige, umstrittene Autovervollständigung für Entwickler

Aus dem Englischen übersetzt von Darryl K. Taft. (Quelle: thenewstack.io)

Ich beschäftige mich schon seit langem mit der Anwendungsentwicklung und habe viele Durchbrüche erlebt. Einige fallen mir mehr ins Auge als andere, und Copilot von GitHub ist einer dieser Hingucker.

GitHub bezeichnet Copilot als seinen KI-Begleiter für das Pair-Programming für Entwickler.

Die Technologie ist wirklich vielversprechend. „GitHub Copilot zieht Kontext aus dem Code, an dem Sie arbeiten, und schlägt ganze Zeilen oder Funktionen vor“, erklärt GitHub-CEO Nat Friedman in einem Blogbeitrag zur Einführung der Technologie.

Copilot hilft Entwicklern, schnell alternative Wege zur Problemlösung zu finden, Tests zu schreiben und neue APIs zu erforschen, ohne mühsam auf Seiten wie Stack Overflow und im Internet nach Antworten suchen zu müssen, so Friedman. Und da es auf maschinellem Lernen basiert, lernt es bei der Benutzung. „Während Sie tippen, passt es sich an die Art und Weise an, wie Sie Ihren Code schreiben – damit Sie Ihre Arbeit schneller erledigen können“, sagte er.

Die Technologie befindet sich derzeit in der technischen Vorabversion und wird von den Nutzern innerhalb und außerhalb von Microsoft/GitHub sehr positiv bewertet, aber auch kritisiert.

„Ich bin beeindruckt davon, wie GitHub Copilot genau zu wissen scheint, was ich als nächstes eingeben möchte“, sagte Feross Aboukhadijeh, Gründer von Socket, einem Hersteller von Datenschutz- und Sicherheitssoftware, in einer Stellungnahme. „GitHub Copilot ist besonders hilfreich bei der Arbeit an React-Komponenten, wo es unheimlich genaue Vorhersagen macht. GitHub Copilot ist zu einem unverzichtbaren Teil meines Werkzeuggürtels für Programmierer geworden.“

Alex Polozov, ein leitender Forscher bei Microsoft Research, ist zwar nicht sonderlich überparteilich, twitterte aber: „Ich übertreibe nicht, Copilot wird zu den Top-3-Tech-Entwicklungen der 2020er Jahre gehören.“

GitHub Copilot ist ein Produkt der Partnerschaft zwischen Microsoft und dem KI-Forschungs- und Einsatzunternehmen OpenAI, in das Microsoft vor zwei Jahren 1 Milliarde Dollar investiert hat.

Friedman erklärte, dass „GitHub Copilot von OpenAI Codex angetrieben wird, einem neuen KI-System, das von OpenAI entwickelt wurde.“

OpenAI Codex verfügt über ein umfassendes Wissen darüber, wie Menschen Code verwenden, und ist bei der Codegenerierung wesentlich leistungsfähiger als GPT-3, unter anderem, weil es auf einem Datensatz trainiert wurde, der eine viel größere Konzentration von öffentlichem Quellcode enthält, erklärte Friedman.

Einige Leute scheinen besorgt zu sein, dass es Code generiert, der mit Code identisch ist, der unter Open-Source-Lizenzen generiert wurde, die keine abgeleiteten Werke zulassen, und der dann von einem Entwickler unwissentlich verwendet wird.

GitHub lehnte es ab, einen Sprecher für diese Nachricht zu interviewen und verwies mich auf die recht ausführliche FAQ der technischen Vorschau. Auf meine Frage nach den Datenquellen, die Copilot verwenden würde, antwortete GitHub beispielsweise wie folgt: „Es wurde auf eine Auswahl von englischem Sprach- und Quellcode aus öffentlich zugänglichen Quellen trainiert, einschließlich (aber nicht beschränkt auf) Code in öffentlichen Repositories auf GitHub.“

But which ones?

„Mit Sicherheit verwenden sie die GitHub-Repos. Und auf jeden Fall die öffentlichen“, sagt Ronald Schmelzer, Analyst bei Cognilytica, das sich auf KI-Forschung und -Analyse spezialisiert hat. „Die Frage ist natürlich, ob sie auch die privaten GitHub-Repos nutzen. Und mit oder ohne Zustimmung der Nutzer? Weitere Quellen könnten vielleicht Stack Overflow und andere Orte sein, an denen Menschen Code zur Kommentierung veröffentlichen. Aber das ist von zweifelhafter Natur, was die Qualität angeht.“

Da Copilot auf öffentlich verfügbarem Quellcode und natürlicher Sprache trainiert wurde, versteht es außerdem sowohl Programmier- als auch menschliche Sprachen. Dies ermöglicht es Entwicklern, eine Aufgabe auf Englisch zu beschreiben, und GitHub Copilot liefert dann den entsprechenden Code, so das Unternehmen.
Unterstützt mehrere Sprachen

Ein attraktives Merkmal von GitHub Copilot ist, dass es mit einer breiten Palette von Frameworks und Sprachen funktioniert, aber diese technische Vorschau funktioniert besonders gut für Python, JavaScript, TypeScript, Ruby und Go, so Friedman.

Und laut der technischen Vorschau-Seite: GitHub Copilot ist derzeit nur als Visual Studio Code-Erweiterung verfügbar. Es funktioniert überall dort, wo Visual Studio Code funktioniert – auf Ihrem Rechner oder in der Cloud auf GitHub Codespaces. Und es ist schnell genug, um es während der Eingabe zu verwenden.

„Copilot sieht wie ein potenziell fantastisches Lernwerkzeug aus – für Entwickler aller Fähigkeiten“, sagte James Governor, ein Analyst bei RedMonk. „Es kann Einstiegshürden beseitigen. Es kann beim Erlernen neuer Sprachen helfen und für Leute, die an polyglotten Codebasen arbeiten. Es setzt wohl das reiche Erbe von GitHub als erstklassiges Lernwerkzeug fort. Es ist noch zu früh, aber KI-gestützte Programmierung wird sich durchsetzen, und wo könnte man diese Erfahrung besser machen als auf GitHub?“
Ja, aber kann es skalieren?

Einige Beobachter sehen Copilot als nützlich für einfache Projekte, aber vielleicht noch nicht reif für die erste Zeit.

„Es ist eine sehr interessante Idee und sollte bei einfachen Beispielen gut funktionieren, aber ich bin gespannt, wie gut es bei komplexen Code-Problemen funktionieren wird“, sagt Eric Newcomer, Chief Technology Officer von Enterprise Infrastructure Software

Artikelbild zeigt Entscheidungsbaum für No-Code oder Low-Code-Anwendungen

No-Code: Apps ohne Entwicklungsteam

Die Idee, dass wir nun alle Projektleiter mit No-Code-Werkzeugen ausstatten und statt Excel-Listen mit den Mitarbeitern zu pflegen, gleich Apps generieren, optimiert generiert für Dateneingabe, Statusrückmeldungen, Arbeitsnachweise, you name it, bereit für den Produktivbetrieb, muss leider ein Wunsch bleiben.

Realistisch ist: Durch No-Code und Low-Code rücken die fachlichen und nicht-funktionalen Anforderungen näher an die Umsetzung. Die Umsetzung kann effektiver agieren. Für wenig exotische bzw. wenig innovative Geschäftsprozesse werden nicht mehr unbedingt spezielle Programmierer benötigt. Sodass Informationen durch die Organisation hinweg schneller und zuverlässig auflaufen und gesammelt werden können.

Besonders Prozessverantwortliche in Projekten oder Abteilung einer Organisation durften häufiger das Bedürfnis haben, Abläufe direkter beeinflussen zu können, als ständig durch alle Phasen der Softwareentwicklung zu müssen. Ein Exceldokument hier, ein Abrechnungsbogen da und zu dem spezielle Anforderungen vom Kunden. Für diese Prozesse gleich eine Entwicklermannschaft zu beauftragen, ist mindestens aufwändig und immernoch keine schneller Prozess. In den wenigsten Fällen ist es überhaupt finanziell sinnvoll. Schön wäre es, wenn nichttechnisches Personal die Workflows zusammenklicken könnten, oder?

Dieses Versprechen macht uns Low-Code und No-Code.

Den Wunsch, dieses lästige „Programmieren“ klickbar zu machen und damit die Möglichkeiten, die Programmierern im Allgemeinen vorbehalten sind, allen zugänglich zu machen, gibt es schon seit je her. Und gute Entwickler arbeiten auch selbst daran, sich selbst überflüssig zu machen. Seit der Nutzen von Software für Unternehmen oder Privatpersonen klar wurde, ist das praktisch so.

Den Entwickler herausrationalisieren

Gleich zu Beginn von Internet und Hypertextdokumenten (HTML) gab es im Officepaket von Microsoft das zweifelhaft berühmt gewordeme „Frontpage“. Die Idee war damals schon klar: Lasst und das lästige Programmieren aus der Gleichung kürzen, damit jeder Webseiten bauen kann. Das hat nicht funktioniert, zu komplex die Aufgabe. Mit Internetdiensten, die den Desktopnanwendungen in Funktion und Bedienung immer ähnlicher wurden (heute Progressive Webapps, abgekürzt PWA), war schnell klar: Das ist kein Problem, was man durch Ziehen und Klicken lösen kann.

Die Software „WordPress“ füllt diese Lücke seit Jahrzehnten bestmöglich aus, was ihr Beliebtheitsgrade widerspiegelt. Kleine- und mittlere Unternehmen klicken sich aus unzähligen Plugins ihre Webprojekte zusammen. Längst nicht nur einfach Internetseiten, sondern rudimäntare Plattformen, Communities, Webshops, Terminabspracheformulare, Feedbackfunktionen und andere Webapplikation (ich denke, man darf sie so nennen) werden da zusammen geklickt. Sicherlich bereits die Anfänge von Low-Code und No-Code.

Ein Spaß ist das meistens jedoch auch nicht und längst vermisst der Enduser bei den Ergebnissen eine gewisse Beständigkeit, Robustheit und Sauberkeit. Die Eingabemasken zu Erstellung der Applikation enthalten jetzt natürlich die Komplexität, mit der normalerweise die Programmierer in ihrem Code umgehen müssen. Jetzt werden unzählige Entscheidungsbäume, Automatisierungsregeln, Datentypen und sonstige komplexe Aufgaben eben über eine entsprechende komplexe Eingabemaske gelöst.

Der klare Vorteil ist schonmal, dass nun keine eigene Sprache gelernt werden muss. Es ist also möglich, so zu gewünschten Ergebnissen zu kommen. Man wird weniger auf Softwareingenieure angewiesen sein. Irgendjemand – muss weiterhin sagen, wie das Zusammenspiel von verschiedenen Anwendungen ablaufen soll, worauf es beim Komponieren von Anwendungen ankommt, wo die Anwendungen im Gesamtunternehmen, im Gesamtprojekt einzuodnen sind. Doch sie werden nicht mehr ständig für die gesamten Phasen der Anwendungsentwicklung benötigt.

Interessant ist dieser Trend auf jeden Fall. Das größte Problem, was wir an unnötigen Overhead derzeit noch haben, ist, dass viele Prozesse von den Entwickler wieder und wieder neu entwickelt werden. Diese Arbeitszeitverschwendung könnte durch Low-Code und No-Code bald der Vergangenheit angehören. Denn komplizierte Datenbankgestaltungen könnten tatsächlich der Vergangenehit angehören.

Ingesamt kann also der Einsatz von No-Code dazu führen, dass ein Entwicklerteam innerhalb eines Projektes oder Unternehmens effizienter und schlanker wird. Auch wird es möglich, dass juniorigere Kollegen robustere Ergebnisse erzielen, da sie durch den No-Code-Ansatz nicht anders können, als bereits reife Arbeiten wiederzuverwenden und das Rad daher nicht immer wieder neu erfinden (wie sie es sonst tendenziell tun).

Dockerimage für CI/CD mit Sloppy CLI

In CI/CD-Situationen, also in Situationen, in denen wir automatisiert gewisse Aussagen über und Aufgaben am aktuellen Entwicklungsstand einer Software vornehmen wollen, sind wir häufig auf die Kommandozeile angewiesen.

TL;DR: Das Runner-Image z.B. für GitLab ist auf DockerHub frei verfügbar dielok/sloppy-cicd. Wir werden die Dockerfile auch in Kürze bei Github veröffentlichen.

Über entsprechende Skripte, also aneinandergereihte Befehle, automatisieren wir dann den Prozess und visualisieren ihn in Form von sogenannten Build- und Deploymentpipelines.

Auch mit dem Cloud-Anbieter Sloppy muss dies natürlich irgendwie innerhalb eines Skriptes möglich sein, damit wir den Entwicklungsstand auch automatisiert veröffentlichen können. So kann die Anwendung auch letztlich von Endnutzern verwendet werden. Dies kann ein Server sein, oder ein ganzes Netzwerk aus Servern, daher sprechen wir von Umgebungen. Auf der sogenannten Produktivumgebung läuft die Anwendung für den Endverbraucher. Umgangssprachlich „Prod“.

Auch auf Umgebungen die nicht produktiv sind, müssen die aktuellen Entwicklungsstände ausgerollt werden können. Diese dienen beispielsweise den Tests der Qualitätssicherung, Demonstrationen für Stakeholder und der Beobachtung des Fortschritts durch Manager. Das soll so zuverlässig, einfach und schnell wie möglich ablaufen: Also automatisiert.

Das geht mit Sloppy im Handumdrehen. Super einfach ist ein neues Projekt (Umgebung) angelegt, Services, Apps in Form von Docker-Containern definiert.Nicht nur in dem UI. dem Portal von Sloppy. Sloppy bietet eine gut entwickelte CLI-Anwendung, mit der Apps, Services und Projekte verwaltet und gesteuert werden können.

Und so können auch die Deployment-Schritte in der Pipeline mit Sloppys CLI-Tool automatisiert werden. Das Skript für diesen Schritt ist dann gerade einmal zwei Zeilen lang:

script:
- export SLOPPY_APITOKEN="$SLOPPY_APITOKEN"
- sloppy change --image docker/container:${CI_COMMIT_REF_NAME} umgebung/service/app

(Auszug aus der CI/CD-Konfiguration für Gitlab)

Zu verbessern wäre, dass dieser Pipelineschritt noch wartet, bis das Deployment erfolgreich abgeschlossen wurde und der Service gestartet werden konnte.

Doch wie bekommt die Pipeline die Sloppy CLI, sodass der Befehl sloppy überhaupt zur Verfügung steht? Entweder lädt und installiert die Pipeline die Binaries bei jeder Ausführung dieses Schrittes oder die Anwendung wird bereits in den zugrundeliegendeliegenden Container installiert und steht immer gleich zur Verfügung.

Für unser Zwecke habe ich den Container mal erstellt und auf Docker Hub verfügbar gemacht: dielok/sloppy-cicd. Viele Erfolg.

Sloppy hat einen genialen Ansatz als Cloud-Anbieter

Wenn ich Sloppy richtig verstehe, wollen sie ein Cloud-Anbieter sein, der grundsätzlich bei den Großen mitmischt. Und ich denke, dass werden sie auch, denn Sloppy nicht aus dem Silicon Valley sondern aus Köln zeigt mir gerade, was AWS, Google Cloud und Azure eigentlich falsch machen.

Sloppy ist im Wesentlichen ein Cloud-Anbieter, der auf den Kern der Sache konzentriert ist: Container (ob jetzt Pod oder Docker oder oder) spezifizieren und und den Cluster hochfahren. Das, sowie die restlichen Aufgaben, die es im Operrationsumfeld gibt, sollten nicht, eigentlich nicht und hätten es nie müssen: Hexenwerk sein.

Beispielsweise etwas, was vollkommen unterschätzt ist: Die sogenannte Docker-Compose-Datei. Im eigenen Team habe ich es miterlebt: Docker-Compose wird so ein bißchen als Spiellösung abgetan. Es ist aber ein komplett ausreichendes, universelles Interface um Cluster im Allgemeine zu definieren. Ob das jetzt Kubernetes, OpenShift oder sonst was läuft.

Sloppy hat dies sofort erkannt. Mindestens über deren CLI-Tool kann man diese Docker-Compose-Datei hochladen und damit den gesamten Cluster hochfahren und konfigurieren. Ich finde es schon alleine bemerkenswert, dass so eine kleine Firma ein beachtliches, einfach zu nutzendes CLI-Tool entwickelt und den Users zu Verfügung stellt.

Die GUI ist bereits jetzt sehr gut verwendbar. Es lassen sich verschiedene Projekte erstellen. Verschiedene Zonen. Ich kann die Container (standarmäßig vom Docker-Hub) definieren und die Instanzen skalieren. Rolling-Deployments kommen gleich mit.

In CI/CD Pipeline kann ich ohne viel Aufwand Deploymentsteps definieren, die die Anwendungen auf die jeweiligen Umgebungen deployen bis durch auf die Produktionsumgebung.

Ich weiß nicht, welche Wünsche das offen bleiben, für welchen Anwendungsfall.

Evtl. gibt es diverse Compliantsrichtlinien, die sich ohne die Konfigurationsmöglichkeiten eines AWS oder Azure nicht realisieren lassen. Okay. Aber das ist doch dann die eigentliche Niesche.

Eigentlich könnten man sogar darauf wetten, dass sich herausstellen wir, dass der Sloppy-Ansatz eigentlich für die Masse geeigneter ist, als die großen Cloud-Anbieter. Denn der Betrieb via Sloppy erfüllt im Prinzip alles, was 95% der aktuellen Nutzer derzeit bei AWS und Co. nur kompliziert und umständlich und nicht so einfach bekommen. Das macht Sloppy schon sehr gut.

DevOps: Versionierungsstrategie bei Continuous Delivery

Setzen wir die Version aus dem Quelltext heraus? Sollte die CI/CD-Pipeline die Version setzen und womöglich auch einen Tag automatisiert im Version Control System (VCS, z.B. Git, Mercurial, Subversion) setzen?

Achtung: Dieser Artikel ist eher Low-Level und für Build-Engineers, Entwickler und Architekten geeignet.

TL;DR: Wenn der Kunde mit kryptischen Buildnummern oder Hashwerten und keine Aussage über die Kompatibilität in der Versionsbezeichnung nötig ist, kann der einfach mit jedem Commit bis auf die Produktion automatisiert werden.

Meist ist dies jedoch nicht der Fall. Die Anwendung besteht wahrscheinlich aus einem Backend und einem Frontend, wenn es sich um einen einfachen Fall handelt. In vielen Fällen haben wir bereits Microservice Infrastruktur mit mehreren Servicen, die über Schnittstellen miteinander kommunizieren und voneinander abhängen. Abwärtskompatibilitäten und Breaking-Changes wollen durch die Versionierung transparent gemacht werden.

Doch Breaking Changes in einem Softwarestand zu identifizieren, ist aus meiner Sicht nicht automatisiert möglich. Eventuell könnte man experimentell über Schnittstellenkontrakte und automatisierte Tests Abwärtskompatibilität automatisiert testen, das ist aber nur eine fixe Idee eines zu kreativen Entwicklers. Auch zwischen Patch und Minor-Release zu unterscheiden ist Ermessenssache. Der Punkt ist, um abhängige Anwendungen mittels der Versionsnummer über Major-Updates und wahrscheinliche oder sogar sichere Kompatibilitätsprobleme zu informieren, benötige ich einen Menschen.

Zum Einsatz kommt natürlich Semantic Versioning — Sie wissen schon: major.minor.patch-snapshot.

Das ist der manuelle Teil. Der automatisierte Teil ist relativ unproblematisch: Jeder Commit im VCS erzeugt über die CI/CD-Pipeline ein Artefact mit der Buildnummer (wahlweise dem Commit-Hash). So etwas wie meine-anwendung:4711, wobei 4711 die Buildnummer ist.

Dieses Artefakt – sei es ein Docker-Image, eine EXE, ein Tar-Archiv, eine Jar-Datei, whatever – wird üblicherweise in einem Artefaktspeicher abgelegt (Artifactory, Nexus, Docker Registry, etc.) und von dort dann weiter auf die entsprechenden Umgebungen bis hin zur Produktion ausgerollt: „deployt“. Dort werden dann verschiedene Integrationstests, Ende-zu-Ende-Tests, Abnahmetests und so weiter ausgeführt.

Bei einer Codebasis, einer Anwendung, die gepflegt, weiterentwickelt und ausgeliefert wird, ist das easy. Die Buildnummer ist zentrale Wahrheit. Was aber wenn x Anwendungen entwickelt werden und in einem Ökosystem zusammenspielen müssen. Was bedeutet in diesem Kontext ein „neuer Build“? Anwendung-1 ist bei Build 6364 während Anwendung-12 erst bei Build 56 ist. Wie komme ich hier zu allgemeinen, automatisierten Testaussagen. Das behandeln wir mal in einem anderen Artikel.

Für unser einfaches Szenarion kommt jetzt wieder die manuelle Versionierung ins Spiel. Denn ich möchte meine neue Version nicht als 4711 veröffentlichen. Eine oft genutzte Eigenschaft meiner Schnittstelle stand in der letzten Version 1.2.3 noch zur Verfügung, ist aber jetzt nicht mehr dabei. Es ist Zeit für eine Version 2.0.0.

Wie benennen wir jetzt also den Build 4711 mit 2.0.0? Manuelles Ändern des Dateinamens? Sicher nicht. Aus meiner Sicht ist das Folgende am einfachsten: Wir nutzen Tags, falls uns VCS das hergibt (Git kann das natürlich).

Die Buildnummer ist nichts weiter als die fortlaufende Nummer der Pipelineausführung, durch die das Artefakt erzeugt wurde. Dieser Pipelinedurchlauf läuft auf einem bestimmten Codestand, der wiederum in einem Commit im VCS eindeutig enthalten ist.

Indem wir manuell einen Tag 2.0.0 auf diesen der Buildnummer 4711 eindeutig zugeordneten Commit setzen, lösen wir ein Event aus. Dieses Event triggert eine Pipeline, die nun das Artefakt nicht mit der Buildnummer, sondern der Tag-Bezeichnung versieht.

Jetzt ist es noch wichtig, die Artefakte vielleicht systematisch aufzuräumen, aber auch das ist ein Thema für einen weiteren Artikel.

Wirtschaftlicher Nutzen von CI/CD

Produktinnovation ist in einer digitalisierten Welt der Schlüssel zum Erfolg. Um sich vom Wettbewerb abzuheben, sollen Innovationen so rasch wie möglich und voll funktionsfähig an den Markt gebracht werden. Doch konventionelle Entwicklungsmethoden sind meist schwerfällig und bremsen die Time-to-Market. Um die Zeitspanne zwischen Entwicklung und Marktveröffentlichung zu verkürzen, sind in der Vergangenheit effektive Ansätze entwickelt worden.

Bei konventionellen Vorgehensweisen, vergehen teilweise Monate bis es zu einem Release kommt. Zunächst müssen alle Fehler behoben und Funktionen entwickelt bzw. erweitert werden. Erst danach folgt ein großes Update. Dabei werden beinahe alle Änderungen und Anpassungen manuell durchgeführt und der Prozess wird dementsprechend anfälliger für Fehler. Der gesamte Prozess ist wenig flexibel sorgt oftmals für komplexe Workarounds für die Entwickler.

Eine Lösung für dieses umständliche Vorgehen muss her. Ein lohnender Ansatz soll den Entwicklungsprozess von Software vereinfachen und zugleich beschleunigen: Das CI/CD.

Unterschied zwischen Continuous Integration (CI) und Continuous Delivery (CD)

Was ist also CI/CI? CI bzw. CD steht für Continuous Integration bzw. Continuous Delivery. Continuous Integration (CI) ermöglicht eine kontinuierliche Integration von neuem Code in ein gemeinsames Repository während Continuous Delivery (CD) für die Überführung des Codes von Repository in die Produktion zuständig ist.

Durch die Anwendung von CI/CD können sowohl die Fehlerquote als auch der Release-Zyklus minimiert werden. Im ersten Schritt, der Continuous Integration, testet der Entwickler den von ihm produzierten Teil des Codes bevor er ihn in das Controle-Repository übermittelt. Danach folgt meist eine neue Quellcode-Version, welche mittels Unit-Tests auf Fehler geprüft und in Testumgebungen eingefügt wird. Hier werden auch ganzheitliche Systemtests durchgeführt. Wenn der neue Teil des Codes erfolgreich alle Tests durchlaufen hat, wird das Team automatisch benachrichtigt. Zudem werden Informationen über die Anzahl der Tests und der gefundenen Fehler gesammelt.

Continuous Delivery (CD) setzt dort an, wo Continuous Integration endet. Bevor Software in die Produktionsumgebung übermittelt wird, werden Systemtests, Unit-Tests (inklusive API-Tests und Lasttests) und Integrationstests durchgeführt. Diese Tests sind allesamt Teil von Continuous Delivery und werden automatisch durchgeführt. Über den kompletten CI/CD-Prozess hinweg, können Fehlermeldungen rasch und direkt über Feedback-Kanäle an die Entwickler weitergeleitet werden.

Nachfolgend sind die relevantesten Vorteile von CI/CD aufgelistet, die letztlich in einer Kostensenkung resultieren.

  • Kleine Schritte: Statt große Teile des Codes auf einmal zu integrieren und in späterer Folge deren Fehler umständlich zu beheben, werden bei CI/CD mehrere kleinere Teile in das Repository eingefügt. Das Continuous Testing wird dadurch erleichtert, weil nur kleinere Stücke untersucht werden müssen und mögliche Probleme somit eher gefunden werden.
  • Kürzere Release Rates: Durch das rasche Erkennen und Beheben von Fehlern, können mehrere kleinere Code-Teile in kürzeren Abständen released werden. Dies ist allerdings nur möglich, wenn in einem kontinuierlichen Prozess entwickelt und der Code in einem releasefähigen Zustand gehalten wird.
  • Ordentlicher Backlog: Wird CI/CD in den Entwicklungsprozess integriert, so verändert sich die Fehlerquote im Backlog. Da kleinere Fehler rascher gefunden werden, kann sich das Team auf kritische Probleme konzentrieren.
  • Einfache Wartung: Mithilfe von Microservices können einzelne Bereiche eines Systems heruntergefahren werden ohne das restliche System betroffen ist. Somit können Wartungsarbeiten nahezu unbemerkt stattfinden.
  • Continuous Feedback: Durch die regelmäßige Integration des Codes, entsteht eine verlässliche und kontinuierliche Feedbackschleife. In dieser befinden sich vor allem Entwickler. Deren Rückmeldung zu Pipeline Build-Fehler, Merging-Problemen, Architektur-Rückschlägen usw. ist enorm wichtig für den gesamten Prozess.

Darauf sollte geachtet werden

Den Entwicklern soll die Arbeit mit dem CI/CD-Ansatz erleichtert werden, weshalb ein einfacher Prozessaufbau essentiell ist. Je weniger sie sich mit dem eigentlichen Prozess und manuellen Aufgaben aufhalten, desto effektiver kann gearbeitet werden. Zudem sollten Entwickler bis auf wenige Ausnahmen, direkt am Master-Branch arbeiten um eine sofortige Integration und das zugehörige Testen zu ermöglichen.

Wird CI/CD in den Entwicklungsprozess von Software integriert, so müssen automatisierte Tests auf allen Ebenen durchgeführt werden. Dies schließt mitunter Unit-, Integrations- und Systemtests ein, genauso wie automatisierte Tests für Funktionalität, Benutzerfreundlichkeit, Leistung, Last, Stress und Sicherheit durchgeführt werden müssen. Erst dann kann von CI/CD ganzheitlich profitiert werden.

Als nützliche Tools erweisen sich beispielsweise Repository-Management-Systeme wie Gitlab und Bitbucket oder Services für die Build-Automatisierung wie Jenkins oder eben auch Gitlab. Beispiele für die Testautomatisierung sind das Tool Katalon Studio oder jUnit in der Javawelt. Aber die Auswahl ist praktisch unendlich.

Fazit

Continuous Integration und Continuous Deployment zerstückeln den Entwicklungsprozess in kleine Teile. Diese Teile werden in regelmäßigen Abständen in ein gemeinsames Repository integriert und nach dem Testen dem Kunden rasch zur Verfügung gestellt. Sie sind ein zentrale Teil der DevOps-Methodik. Der gesamte Entwicklungsprozess wird übersichtlicher und flexibler, dadurch werden Fehler einfacher gefunden und behoben. Um mit der Konkurrenz mitzuhalten bzw. diese sogar zu übertreffen und unnötige Fehlersuche zu vermeiden, ist die Integration von CI/CD in den Entwicklungsprozess also eine einfache, effektive aber auch mittlerweile unverzichtbare Methode.

Entwickler schaffen sich ab: WebAssembly, jHipster und Low-Code – und das ist gut so

Wir machen uns überflüssig. Meine These: Und das ist gut so. Wir wollen es noch nicht wahr haben und genießen derzeit noch eine Art Schutzposition. Während es Mangel an IT-Kräften gibt und die Digitalisierung für viele Bereiche Stellenabbau bedeutet entwickeln sich die Technologien paradox. Paradox ist es aber nur auf den ersten Blick.
Die scheinbare Paradoxie: Entwickler werden durch ihre eigene Digitalisierung selbst von den Auswirkungen auf den minimierten Arbeitskräftebedarf betroffen sein. Nicht langfristig, sondern es steht kurz bevor! Wie kann das sein?

Entwickler sind derzeit noch in einer Position, dass die Digitalisierung so langsam akzeptiert ist, in manchen Bereichen bereits Fahrt aufnimmt, aber so richtig verankert in vielen Bereichen noch nicht ist. Auch mit dem Pandemieschub ist im Allgemeinen die Führungskraft abhängig von ihren Technologieberatern, meist Entwickler, die Aufgaben planen und Aufwände einschätzen. Überliche Muster dabei sind: Backendentwicklung ist sehr aufwändig im Vergleich zur Frontendentwicklung, native Appentwicklung ist keine einfache Webentwicklung und zu einem gegeben Design benötigt es grafikaffine Entwickler, die dies auch Umsetzen können. Die Entwicklung verrät dem Management natürlich nur zögerlich, dass diese Aufgaben heute zu einem Bruchteil des Aufwandes zu erledigen sind.
Die drei Kernbereiche, aus denen die Aufwände für die Entwicklung entstehen, sind kurz davor zu fallen.

Kernbereich 1: Backendentwicklung wird durch Standgeneratoren ersetzt

Die Backendentwicklung hat den Ruf, das eigentliche Feld des hochspezialisierten Entwicklers zu sein. Das ist historisch so gewachsen. Betriebssystementwicklung (Linux-Kernel, etc.), Algorithmenentwicklung (Facebook, Google) sind das Herzstück der jeweiligen Innovationen. Und in der Tat, überall dort, wo es viel neue Businesslogik zu entwickeln gibt, werden auch in Zukunft noch die spezialisierten Entwickler benötigt. Doch für die meisten Geschäftsmodelle gibt es heute Frameworks, die in dem Backendbereich eingesetzt wird. Dazu kommen Generatoren, wie jHipster, die nicht nur große Teile des Backends einfach auf Basis von standardisierten Diagrammen automatisiert erzeugen können. Auch Swagger geht nach dem Konzept „Interface-First“ vor. Gar nicht so unglaublich aber wahr: Eigentlich braucht man nur beschreiben, welche Daten ausgetauscht werden sollen und schon steht fast das gesamte Backend. Und das ist ein sinnvoller Fortschritt, der dort vollzogen wird. Warum sollen die immerselben Businesslogiken von der Backendtruppe immer wieder auf neue händisch eingetippt werden? Oder warum soll der Entwickler sich Stunden aufschreiben, in denen er eigentlich nur Altes kopiert und sich ansonsten auf die faule Haut legt?

Da wir bereits von Businesslogik sprechen, die früher üblicherweise im Backend angesiedelt war, so kommt der eine oder andere vielleicht auf die Idee, dass diese nun einfach in die Frontendentwicklung abwandert und dann eben dort stattfindet. Das ist nicht richtig. Sie wandert zwar im Zuge der ebenfalls richtigen Evolution von klassischen, serverabhängigen, mehrseitigen Anwendungen in richtung Singlepage-Application oder PWA (Progressive Web Apps) also Anwendungen, die eher unabhängig von einem Server funktionieren und deshalb viel Businesslogik in der Anwedung selbst und nicht im Server haben. Doch diese wird bereits von den entsprechenden Generator wie jHipster gleich mitgeneriert.

Kernbereich 2: Spezialisten für native Appentwicklung

Derzeit ist es sinnvoll für Innovationen, mit einem plattformunabhängigen Framework App für mobile Geräte zu entwickeln. Einfach weil es günstiger ist, gleich für mehrere Plattformen zu entwickeln. Besser und hochwertiger allerdings ist die native Entwicklung für jede Plattform im Speziellen. Also eigens für Apple (iOS) und eigens für Android. Dafür benötigt man spezielle Swift oder Java-Entwickler. WebAssambly ist die nächste Evolutionsstufe: So wie Website einfach von eine Domain geladen werden, können mit WebAssembly schon heute native Apps entwickelt werden, die nicht über einen AppStore geladen werden müssen, sondern einfach über eine Domain abgerufen werden können. Und diese werden, sobald es die entsprechenden Phones dafür gibt, gleichmaßen gut auf dem Phone, dem Tablet und dem Desktop laufen. Schnell, nativ entwickelt.

Kernbereich 3: Frontendentwickler ablösen

Zu meiner Anfangszeit gab es Microsoft Frontend. Wer mit diesem Tool glaubte, Webentwicklung betreiben zu können, wurde schnell eines besseren belehrt. Das Tool wurde praktisch zu einem Witz unter allen Menschen, die sich mit der Entwicklung von Software oder auch nur einfachen Webseiten im Web beschätigten. Auch andere Tools, die Frontends irgendwie grafisch entwickeln lassen wollten, erreicht nie den Wartbarkeits und Erweiterbarkeits und Sauberkeitsanspruch echter Softwareentwickler. Heute gibt es allerdings die ersten Tools, wie WebFlow, die einen Grafiker in die Lage versetzen, seine Designs quasi direkt in diesem Tool umzusetzen, mit den üblichen Werkzeugen, mit leicht ungewohnter Herangehensweise. Ist diese Herangehensweise in gewissen Blöcken zu denken, allerdings akzeptiert, so generiert der Design gleich das gesamt Frontend. Ein Entwickler stöpselt bloß noch die Details zusammen. So ein Tools ist beispielsweise WebFlow.

Was für den Entwickler bleibt ist Zusammenstöpseln: Das werden die Waldundwiesenentwickler übernehmen. Davon wird der Bedarf dann in Zukunft gewaltig abnehmen. Und neue Businesslogik für echte Innovationen wird weiterhin benötigt. Das wiederum werden die besten Spezialisten auf ihrem Gebiet ausführen.