Continuous Integration: Was es ist und wie es funktioniert

Avatar of Jeff Wainwright
Jeff Wainwright am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Vor nicht allzu langer Zeit hatte ich ein rudimentäres Verständnis von Continuous Integration (CI) und dachte, es sei ein zusätzlicher Prozess, der Ingenieure zwingt, mehr Arbeit an bereits großen Projekten zu leisten. Mein Team begann, CI in Projekte zu implementieren, und nach einigen praktischen Erfahrungen erkannte ich die großen Vorteile, nicht nur für das Unternehmen, sondern auch für mich als Ingenieur! In diesem Beitrag werde ich CI, die von mir entdeckten Vorteile und wie man es kostenlos und schnell implementiert, beschreiben.

CI und Continuous Delivery (CD) werden normalerweise zusammen diskutiert. Sowohl CI als auch CD in einem Beitrag zu behandeln, ist sehr viel auf einmal zum Schreiben und Lesen, daher werden wir hier nur CI besprechen. Vielleicht werde ich CD in einem zukünftigen Beitrag behandeln. 😉

Inhaltsverzeichnis

Was ist CI?

Continuous Integration, wie ich es verstehe, ist ein Programmiermuster, das Tests, Sicherheitschecks und Entwicklungspraktiken kombiniert, um Code vertrauensvoll und kontinuierlich von einem Entwicklungszweig in einen produktionsbereiten Zweig zu pushen.

Microsoft Word ist ein Beispiel für CI. Wörter werden in das Programm eingegeben und gegen Rechtschreib- und Grammatikalgorithmen geprüft, um die allgemeine Lesbarkeit und Rechtschreibung eines Dokuments zu gewährleisten.

Warum CI überall verwendet werden sollte

Wir haben dies bereits kurz angesprochen, aber der größte Vorteil von CI, den ich sehe, ist, dass er viel Geld spart, indem er Ingenieure produktiver macht. Insbesondere bietet er schnellere Feedbackschleifen, einfachere Integration und reduziert Engpässe. Die direkte Korrelation von CI zu Unternehmenseinsparungen ist schwierig, da die Kosten für SaaS mit der Benutzerbasis skalieren. Wenn also ein Entwickler CI an das Unternehmen verkaufen möchte, kann die folgende Formel verwendet werden. Neugierig, wie viel es sparen kann? Mein Freund, David Inoa, hat die folgende Demo erstellt, um die Einsparungen zu berechnen.

Siehe den Pen Continuous Integration (CI) Company Cost Savings Estimator von David (@davidinoa) auf CodePen.

Was mich wirklich begeistert genug, um es von den Dächern zu schreien, ist, wie CI Ihnen und mir als Entwicklern zugute kommen kann!

Zunächst einmal spart Ihnen CI Zeit. Wie viel? Wir reden hier von Stunden pro Woche. Wie? Oh, das möchte ich Ihnen gerne erzählen! CI testet Ihren Code automatisch und teilt Ihnen mit, ob er in einen produktionsnahen Zweig zusammengeführt werden kann. Die Zeit, die Sie damit verbringen würden, Ihren Code zu testen und mit anderen zusammenzuarbeiten, um den Code für die Produktion vorzubereiten, ist sehr viel Zeit.

Dann ist da noch die Art und Weise, wie es hilft, Code-Erschöpfung zu verhindern. Es bietet Tools wie Greenkeeper, die automatisch Pull-Anfragen nach einer Code-Überprüfung einrichten und sogar zusammenführen können. Dies hält den Code auf dem neuesten Stand und ermöglicht es den Entwicklern, sich auf das zu konzentrieren, was wir wirklich tun müssen. Wissen Sie, wie Code schreiben oder das Leben genießen. Code-Updates in Paketen müssen in der Regel nur auf wichtige Versionsupdates geprüft werden, sodass weniger Aufwand erforderlich ist, jede Minor-Version auf Breaking Changes zu verfolgen, die Maßnahmen erfordern.

CI nimmt viel Rätselraten beim Aktualisieren von Abhängigkeiten ab, was sonst viel Recherche und Tests erfordern würde.

Keine Ausreden, nutze CI!

Wenn man mit Entwicklern spricht, endet die Unterhaltung normalerweise etwa so:

„Ich würde CI verwenden, aber… [Entschuldigung einfügen].“

Das ist für mich eine Ausrede! CI kann kostenlos sein. Es kann auch einfach sein. Es stimmt, dass die Vorteile von CI einige Kosten mit sich bringen, einschließlich monatlicher Gebühren für Tools wie CircleCI oder Greenkeeper. Aber das ist ein Tropfen auf den heißen Stein im Vergleich zu den langfristigen Einsparungen. Es stimmt auch, dass die Einrichtung Zeit braucht. Aber es ist erwähnenswert, dass die Leistung von CI für Open-Source-Projekte kostenlos genutzt werden kann. Wenn Sie Ihren Code privat halten müssen oder wollen und nicht für CI-Tools bezahlen möchten, können Sie Ihre eigene CI-Einrichtung mit einigen großartigen npm-Paketen erstellen.

Also, Schluss mit den Ausreden und bestaunt die Macht von CI!

Welche Probleme löst CI?

Bevor wir tiefer eintauchen, sollten wir die Anwendungsfälle für CI behandeln. Es löst viele Probleme und ist in vielen Situationen nützlich.

  • Wenn mehr als ein Entwickler gleichzeitig in einen Produktionszweig zusammenführen möchte
  • Wenn Fehler nicht vor dem Deployment erkannt oder behoben werden können
  • Wenn Abhängigkeiten veraltet sind
  • Wenn Entwickler lange warten müssen, um Code zusammenzuführen
  • Wenn Pakete von anderen Paketen abhängig sind
  • Wenn ein Paket aktualisiert wird und an mehreren Stellen geändert werden muss
CI testet Updates und verhindert, dass Fehler deployed werden.

Empfohlene CI-Tools

Betrachten wir die High-Level-Komponenten, die zur Erstellung einer CI-Feedbackschleife verwendet werden, mit einigen schnellen Code-Schnipseln, um CI noch heute für jedes Open-Source-Projekt einzurichten. Wir werden dies in verdauliche Abschnitte unterteilen.

Dokumentation

Um CI sofort für mich zum Laufen zu bringen, richte ich CI normalerweise so ein, dass meine anfängliche Dokumentation für ein Projekt getestet wird. Insbesondere verwende ich MarkdownLint und Write Good, da sie alle Funktionen und Möglichkeiten bieten, die ich benötige, um Tests für diesen Teil des Projekts zu schreiben.

Die gute Nachricht ist, dass GitHub Standardvorlagen bereitstellt und viele Inhalte kopiert werden können, um die Dokumentation schnell einzurichten. Lesen Sie mehr über die schnelle Einrichtung von Dokumentationen und die Erstellung einer Feedbackschleife für Dokumentationen.

Ich behalte eine package.json-Datei im Stammverzeichnis des Projekts und führe einen Skriptbefehl wie diesen aus

"grammar": "write-good *.md --no-passive",
"markdownlint": "markdownlint *.md"

Diese beiden Zeilen ermöglichen es mir, CI zu verwenden. Das ist alles! Ich kann jetzt CI ausführen, um Grammatik zu testen.

An diesem Punkt kann ich mit der Einrichtung von CircleCI und Greenkeeper fortfahren, um sicherzustellen, dass Pakete aktuell sind. Dazu kommen wir gleich.

Unit-Tests

Unit-Tests sind eine Methode zum Testen kleiner Codeblöcke (Units), um sicherzustellen, dass das erwartete Verhalten dieses Blocks wie beabsichtigt funktioniert.

Unit-Tests bieten viel Hilfe bei CI. Sie definieren die Codequalität und liefern Entwicklern Feedback, ohne Code pushen/mergen/hosten zu müssen. Lesen Sie mehr über Unit-Tests und die schnelle Einrichtung einer Feedbackschleife für Unit-Tests.

Hier ist ein Beispiel für einen sehr grundlegenden Unit-Test ohne Verwendung einer Bibliothek

const addsOne = (num) => num + 1 // We start with 1 as an initial value
  const numPlus1 = addsOne(3) // Function to add 3
  const stringNumPlus1 = addsOne('3') // Add the two functions, expect 4 as the value
    
  /**
    * console.assert
    * https://developer.mozilla.org/en-US/docs/Web/API/console/assert
    * @param test?
    * @param string
    * @returns string if the test fails
    **/
    
  console.assert(numPlus1 === 4, 'The variable `numPlus1` is not 4!')
  console.assert(stringNumPlus1 === 4, 'The variable `stringNumPlus1` is not 4!')

Mit der Zeit ist es schön, Bibliotheken wie Jest für Unit-Tests zu verwenden, aber dieses Beispiel gibt Ihnen eine Vorstellung davon, was wir betrachten.

Hier ist ein Beispiel für den gleichen Test oben mit Jest

const addsOne = (num) => num + 1

describe('addsOne', () => {
  it('adds a number', () => {
    const numPlus1 = addsOne(3)
    expect(numPlus1).toEqual(4)
  })
  it('will not add a string', () => {
    const stringNumPlus1 = addsOne('3')
    expect(stringNumPlus1 === 4).toBeFalsy();
  })
})

Mit Jest können Tests für CI mit einem Befehl in einer package.json wie diesem verknüpft werden:

"test:jest": "jest --coverage",

Das Flag --coverage konfiguriert Jest, um die Testabdeckung zu melden.

Sicherheitschecks

Sicherheitschecks helfen bei der Kommunikation von Code und Codequalität. Dokumentation, Dokumentvorlagen, Linter, Rechtschreibprüfer und Typenprüfer sind alles Sicherheitschecks. Diese Tools können automatisiert werden, um während Commits, in der Entwicklung, während CI oder sogar in einem Code-Editor ausgeführt zu werden.

Sicherheitschecks fallen in mehr als eine Kategorie von CI: Feedbackschleife und Tests. Ich habe eine Liste der Arten von Sicherheitschecks zusammengestellt, die ich normalerweise in ein Projekt einbaue.

All diese Prüfungen mögen wie eine weitere Ebene der Code-Abstraktion oder des Lernens erscheinen. Seien Sie also nachsichtig mit sich selbst und anderen, wenn dies überwältigend wirkt. Diese Tools haben meinem Team geholfen, Erfahrungslücken zu schließen, teilbare Team-Muster zu definieren und Entwicklern zu helfen, wenn sie unsicher sind, was ihr Code tut.

  • Committing, Merging, Kommunizieren: Tools wie husky, commitizen, GitHub Templates und Changelogs helfen dabei, CI mit sauberem Code am Laufen zu halten und bilden einen schönen Workflow für ein kollaboratives Teamumfeld.
  • Code definieren (Typenprüfer): Tools wie TypeScript definieren und kommunizieren Code-Schnittstellen – nicht nur Typen!
  • Linting: Dies ist die Praxis, sicherzustellen, dass etwas definierten Standards und Mustern entspricht. Es gibt Linter für fast alle Programmiersprachen, und Sie haben wahrscheinlich mit gängigen gearbeitet, wie ESlint (JavaScript) und Stylelint (CSS) in anderen Projekten.
  • Schreiben und kommentieren: Write Good hilft bei der Erkennung von Grammatikfehlern in der Dokumentation. Tools wie JSDoc, Doctrine und TypeDoc unterstützen beim Schreiben von Dokumentationen und fügen nützliche Hinweise in Code-Editoren hinzu. Beide können zu Markdown-Dokumentationen kompiliert werden.

ESlint ist ein gutes Beispiel dafür, wie diese Arten von Tools in CI implementiert werden. Zum Beispiel ist dies alles, was in package.json erforderlich ist, um JavaScript zu linten:

"eslint": "eslint ."

Offensichtlich gibt es viele Optionen, die es Ihnen ermöglichen, einen Linter so zu konfigurieren, dass er Ihren und den Coding-Standards Ihres Teams entspricht. Sie können jedoch sehen, wie praktisch die Einrichtung sein kann.

CI-Einrichtung auf hoher Ebene

Die Einrichtung von CI für ein Repository dauert oft nur sehr wenig Zeit, aber es gibt auch viele fortgeschrittene Konfigurationen, die wir bei Bedarf nutzen können. Betrachten wir eine schnelle Einrichtung und gehen dann zu einer fortgeschritteneren Konfiguration über. Selbst die einfachste Einrichtung ist vorteilhaft für das Sparen von Zeit und die Codequalität!

Zwei Funktionen, die Entwicklern Stunden pro Woche mit einfachem CI sparen können, sind automatische Abhängigkeitsaktualisierungen und Build-Tests. Abhängigkeitsaktualisierungen werden detaillierter hier beschrieben.

Build-Tests beziehen sich auf die Installation von node_modules während CI, indem eine Installation ausgeführt wird – zum Beispiel (npm install, wobei alle node_modules wie erwartet installiert werden. Dies ist eine einfache Aufgabe und schlägt tatsächlich fehl. Sicherzustellen, dass node_modules wie erwartet installiert wird, spart erheblich Zeit!

Schnelle CI-Einrichtung

CI kann automatisch sowohl für CircleCI als auch für Travis eingerichtet werden! Wenn ein gültiger test-Befehl bereits im package.json des Repositorys definiert ist, kann CI ohne weitere Konfiguration implementiert werden.

In einem CI-Tool wie CircleCI oder Travis kann das Repository nach dem Einloggen oder der Authentifizierung durchsucht werden. Von dort aus folgen Sie der Benutzeroberfläche des CI-Tools, um mit dem Testen zu beginnen.

Für JavaScript prüft CircleCI test im package.json eines Repositorys, um zu sehen, ob ein gültiges Testskript hinzugefügt wurde. Wenn dies der Fall ist, beginnt CircleCI automatisch mit der Ausführung von CI! Lesen Sie hier mehr über die automatische Einrichtung von CircleCI.

Erweiterte Konfigurationen

Wenn Unit-Tests unvollständig sind oder mehr Konfiguration benötigt wird, kann eine .yml-Datei für ein CI-Tool (wie CircleCI) hinzugefügt werden, in der die Ausführungs-Runner-Skripte erstellt werden.

Unten sehen Sie, wie eine benutzerdefinierte CircleCI-Konfiguration mit JavaScript-Linting (wieder mit ESlint als Beispiel) für CircleCI eingerichtet wird.

Zuerst führen Sie diesen Befehl aus:

mkdir .circleci && touch .circleci/config.yml

Fügen Sie dann Folgendes zur generierten Datei hinzu:

defaults: &defaults
  working_directory: ~/code
  docker:
    - image: circleci/node:10
  environment:
  NPM_CONFIG_LOGLEVEL: error # make npm commands less noisy
  JOBS: max <h3>https://gist.github.com/ralphtheninja/f7c45bdee00784b41fed
    version: 2
    jobs:
    build:
      <<: *defaults
      steps:
        - checkout
        - run: npm i
        - run: npm run eslint:ci

Nachdem diese Schritte abgeschlossen sind und nachdem CircleCI in GitHub konfiguriert wurde (mehr dazu hier), erkennt CircleCI .circleci/config.yml und lintet JavaScript in einem CI-Prozess, wenn ein Pull-Request eingereicht wird.

Ich habe einen Ordner mit Beispielen in diesem Demo-Repository erstellt, um Ideen für die Konfiguration von CI mit config.yml-Dateien zu zeigen. Sie können darauf für Ihr eigenes Projekt verweisen oder die Dateien als Ausgangspunkt verwenden.

Es gibt noch mehr CI-Tools, die eingerichtet werden können, um Entwicklern mehr Zeit zu sparen, wie z. B. Auto-Merging, Auto-Updating, Monitoring und vieles mehr!

Zusammenfassung

Wir haben hier viel behandelt! Zusammenfassend lässt sich sagen, dass die Einrichtung von CI sehr machbar ist und sogar kostenlos sein kann. Mit zusätzlicher Tooling (sowohl kostenpflichtig als auch Open-Source) können wir mehr Zeit zum Codieren haben und mehr Zeit, um weitere Tests für CI zu schreiben – oder mehr vom Leben außerhalb des Bildschirms zu genießen!

Hier sind einige Demo-Repositorys, die Entwicklern helfen, schnell einzurichten oder zu lernen. Fühlen Sie sich frei, sich innerhalb der Repositories mit Fragen, Ideen oder Verbesserungen zu melden.