Das Konzept der Continuous Integration (CI) begegnete mir zum ersten Mal, als das Mozilla-Projekt startete. Der Prozess beinhaltete einen rudimentären Build-Server, was damals revolutionär war. Ich habe ein C++-Projekt gepflegt, dessen Erstellung und Verknüpfung zwei Stunden dauerte.
Wir führten selten einen sauberen Build durch, der zusätzliche Probleme verursachte, da fehlerhafter Code in das Projekt übernommen wurde.
Seit jenen alten Zeiten hat sich viel verändert. CI-Produkte sind allgegenwärtig und als Java-Entwickler genießen wir eine nie dagewesene Vielfalt an Möglichkeiten. Aber ich übertreibe mich selbst ... Fangen wir mit den Grundlagen an.
Kontinuierliche Integration ist eine Softwareentwicklungspraxis, bei der Codeänderungen automatisch erstellt und regelmäßig und konsistent getestet werden.
Das Ziel von CI besteht darin, Integrationsprobleme so schnell wie möglich zu erkennen und zu lösen und so das Risiko zu verringern, dass Fehler und andere Probleme in die Produktion gelangen.
CI geht oft Hand in Hand mit Continuous Delivery (CD), das darauf abzielt, den gesamten Softwarebereitstellungsprozess zu automatisieren, von der Code-Integration bis zur Bereitstellung in der Produktion.
Das Ziel von CD besteht darin, den Zeit- und Arbeitsaufwand für die Bereitstellung neuer Releases und Hotfixes zu reduzieren, sodass Teams den Kunden schneller und häufiger einen Mehrwert bieten können.
Mit CD gilt jede Codeänderung, die die CI-Tests besteht, als bereit für die Bereitstellung, sodass Teams jederzeit bedenkenlos neue Versionen bereitstellen können. Ich werde in diesem Beitrag nicht auf Continuous Delivery eingehen, aber ich werde darauf zurückkommen, da es viel zu besprechen gibt.
Ich bin ein großer Fan des Konzepts, aber es gibt einige Dinge, die wir im Auge behalten müssen.
Es gibt viele leistungsstarke Tools für die kontinuierliche Integration. Hier sind einige häufig verwendete Tools:
Jenkins : Jenkins ist eines der beliebtesten CI-Tools und bietet eine breite Palette an Plugins und Integrationen zur Unterstützung verschiedener Programmiersprachen und Build-Tools. Es ist Open Source und bietet eine benutzerfreundliche Oberfläche zum Einrichten und Verwalten von Build-Pipelines.
Es ist in Java geschrieben und war oft mein „Go-to-Tool“. Allerdings ist die Verwaltung und Einrichtung mühsam. Es gibt einige „Jenkins as a Service“-Lösungen, die auch das etwas mangelhafte Benutzererlebnis verbessern.
Beachten Sie, dass ich GitHub-Aktionen nicht erwähnt habe, auf die wir gleich noch eingehen werden. Beim Vergleich von CI-Tools sind mehrere Faktoren zu berücksichtigen:
Generell ist Jenkins für seine Vielseitigkeit und umfangreiche Plugin-Bibliothek bekannt, was es zu einer beliebten Wahl für Teams mit komplexen Build-Pipelines macht. Travis CI und CircleCI sind für ihre Benutzerfreundlichkeit und Integration mit gängigen SCM-Tools bekannt, was sie zu einer guten Wahl für kleine bis mittlere Teams macht.
GitLab CI/CD ist eine beliebte Wahl für Teams, die GitLab für die Quellcodeverwaltung nutzen, da es integrierte CI/CD-Funktionen bietet. Bitbucket Pipelines ist eine gute Wahl für Teams, die Bitbucket für ihre Quellcodeverwaltung nutzen, da es sich nahtlos in die Plattform integrieren lässt.
Das Hosting von Agenten ist ein wichtiger Faktor, der bei der Auswahl einer CI-Lösung berücksichtigt werden muss. Es gibt zwei Hauptoptionen für das Agenten-Hosting: cloudbasiert und vor Ort.
Bei der Auswahl einer CI-Lösung ist es wichtig, die spezifischen Bedürfnisse und Anforderungen Ihres Teams zu berücksichtigen.
Wenn Sie beispielsweise über eine große und komplexe Build-Pipeline verfügen, ist eine On-Premise-Lösung wie Jenkins möglicherweise die bessere Wahl, da Sie damit mehr Kontrolle über die zugrunde liegende Infrastruktur haben.
Wenn Sie hingegen ein kleines Team mit einfachen Anforderungen haben, ist eine cloudbasierte Lösung wie Travis CI möglicherweise die bessere Wahl, da sie einfach einzurichten und zu verwalten ist.
Statefulness bestimmt, ob die Agenten ihre Daten und Konfigurationen zwischen Builds beibehalten.
Unter CI-Befürwortern gibt es eine lebhafte Debatte über den besten Ansatz. Zustandslose Agenten bieten eine saubere und einfach zu reproduzierende Umgebung. Ich wähle sie in den meisten Fällen und denke, dass sie der bessere Ansatz sind.
Zustandslose Agenten können auch teurer sein, da ihre Einrichtung langsamer ist. Da wir für Cloud-Ressourcen bezahlen, können sich diese Kosten summieren. Der Hauptgrund, warum einige Entwickler die Stateful Agents bevorzugen, ist jedoch die Möglichkeit zur Untersuchung.
Wenn bei einem zustandslosen Agenten ein CI-Prozess fehlschlägt, stehen Ihnen in der Regel außer den Protokollen keine weiteren Untersuchungsmöglichkeiten zur Verfügung.
Mit einem zustandsbehafteten Agenten können wir uns bei der Maschine anmelden und versuchen, den Prozess manuell auf der angegebenen Maschine auszuführen. Wir könnten ein fehlgeschlagenes Problem reproduzieren und dadurch Erkenntnisse gewinnen.
Ein Unternehmen, mit dem ich zusammengearbeitet habe, hat sich für Azure gegenüber GitHub Actions entschieden, weil Azure Stateful Agents zulässt. Dies war ihnen beim Debuggen eines fehlgeschlagenen CI-Prozesses wichtig.
Ich bin damit nicht einverstanden, aber das ist eine persönliche Meinung. Ich habe das Gefühl, dass ich mehr Zeit mit der Fehlerbehebung bei fehlerhaften Agenten verbracht habe, als dass ich von der Untersuchung eines Fehlers profitiert habe. Aber das ist eine persönliche Erfahrung und einige kluge Freunde von mir sind anderer Meinung.
Wiederholbare Builds beziehen sich auf die Fähigkeit, jedes Mal, wenn ein Build ausgeführt wird, genau dieselben Softwareartefakte zu erzeugen, unabhängig von der Umgebung oder dem Zeitpunkt, zu dem der Build ausgeführt wird.
Aus DevOps-Sicht sind wiederholbare Builds von entscheidender Bedeutung, um sicherzustellen, dass Softwarebereitstellungen konsistent und zuverlässig sind.
Zeitweilige Ausfälle sind überall der Fluch von DevOps und es ist schmerzhaft, sie zu verfolgen.
Leider gibt es keine einfache Lösung. So sehr wir es uns auch wünschen würden, in Projekten mit angemessener Komplexität findet ein gewisses Maß an Flockigkeit Einzug. Es ist unsere Aufgabe, dies so weit wie möglich zu minimieren. Es gibt zwei Blocker für wiederholbare Builds:
Bei der Definition von Abhängigkeiten müssen wir uns auf bestimmte Versionen konzentrieren. Es gibt viele Versionierungsschemata, aber im letzten Jahrzehnt hat sich die standardmäßige semantische Versionierung mit drei Zahlen in der Branche durchgesetzt.
Dieses Schema ist für CI immens wichtig, da seine Verwendung die Wiederholbarkeit eines Builds erheblich beeinflussen kann. Mit Maven können wir beispielsweise Folgendes tun:
<dependency> <groupId>group</groupId> <artifactId>artifact</artifactId> <version>2.3.1</version> </dependency>
Dies ist sehr spezifisch und großartig für die Wiederholbarkeit. Dies könnte jedoch schnell veraltet sein. Wir können die Versionsnummer durch LATEST
oder RELEASE
ersetzen, wodurch automatisch die aktuelle Version abgerufen wird. Das ist schlecht, da die Builds nicht mehr wiederholbar sind.
Allerdings ist auch der hartcodierte Drei-Zahlen-Ansatz problematisch. Es kommt häufig vor, dass eine Patch-Version eine Sicherheitsbehebung für einen Fehler darstellt. In diesem Fall möchten wir vollständig auf das neueste kleinere Update aktualisieren, jedoch nicht auf neuere Versionen.
Für den vorherigen Fall würde ich beispielsweise implizit Version 2.3.2
und nicht 2.4.1
verwenden wollen. Dadurch wird eine gewisse Wiederholbarkeit gegen kleinere Sicherheitsupdates und Fehler eingebüßt.
Eine bessere Möglichkeit wäre jedoch, das Maven-Versions-Plugin zu verwenden und regelmäßig den Befehl mvn versions:use-latest-releases
aufzurufen. Dadurch werden die Versionen auf den neuesten Stand gebracht, um unser Projekt auf dem neuesten Stand zu halten.
Dies ist der unkomplizierte Teil wiederholbarer Builds. Die Schwierigkeit liegt in den flockigen Tests. Dies ist ein so häufiges Problem, dass einige Projekte eine „angemessene Anzahl“ fehlgeschlagener Tests definieren und einige Projekte den Build mehrmals erneut ausführen, bevor sie den Fehler bestätigen.
Eine Hauptursache für Testflocken sind Zustandslecks. Tests können aufgrund geringfügiger Nebenwirkungen, die von einem früheren Test herrühren, fehlschlagen. Im Idealfall sollte ein Test nacheinander bereinigt werden, sodass jeder Test isoliert ausgeführt wird.
In einer perfekten Welt würden wir jeden Test in einer völlig isolierten, frischen Umgebung durchführen, aber das ist nicht praktikabel. Das würde bedeuten, dass die Ausführung der Tests zu lange dauern würde und wir viel Zeit auf den CI-Prozess warten müssten.
Wir können Tests mit verschiedenen Isolationsstufen schreiben; Manchmal benötigen wir eine vollständige Isolation und müssen möglicherweise einen Container für einen Test hochfahren. Aber meistens ist das nicht der Fall und der Geschwindigkeitsunterschied ist erheblich.
Das Aufräumen nach den Tests ist eine große Herausforderung. Manchmal können Statuslecks von externen Tools wie der Datenbank zu einem unregelmäßigen Testfehler führen. Um die Wiederholbarkeit von Fehlern sicherzustellen, ist es üblich, die Testfälle konsistent zu sortieren. Dadurch wird sichergestellt, dass zukünftige Ausführungen des Builds in derselben Reihenfolge ausgeführt werden.
Dies ist ein heiß diskutiertes Thema. Einige Ingenieure glauben, dass dies fehlerhafte Tests fördert und Probleme verbirgt, die wir nur durch eine zufällige Reihenfolge der Tests entdecken können. Meiner Erfahrung nach wurden zwar Fehler in den Tests gefunden, aber nicht im Code.
Mein Ziel ist es nicht, perfekte Tests zu erstellen, daher führe ich die Tests lieber in einer konsistenten Reihenfolge durch, beispielsweise in alphabetischer Reihenfolge.
Es ist wichtig, Statistiken über Testfehler zu führen und niemals einfach auf „Wiederholen“ zu klicken. Indem wir die problematischen Tests und die Reihenfolge der Ausführung bei einem Fehler verfolgen, können wir oft die Ursache des Problems finden.
In den meisten Fällen liegt die Ursache des Fehlers in der fehlerhaften Bereinigung in einem vorherigen Test, weshalb die Reihenfolge und ihre Konsistenz ebenfalls wichtig sind.
Wir sind hier, um ein Softwareprodukt zu entwickeln, nicht ein CI-Tool. Das CI-Tool soll den Prozess verbessern. Leider ist die Erfahrung mit dem CI-Tool oft so frustrierend, dass wir am Ende mehr Zeit mit der Logistik verbringen als mit dem eigentlichen Schreiben von Code.
Oft habe ich tagelang versucht, eine CI-Prüfung zu bestehen, damit ich meine Änderungen zusammenführen konnte. Jedes Mal, wenn ich näher kam, führte ein anderer Entwickler zuerst seine Änderung zusammen und zerstörte meinen Build.
Dies trägt dazu bei, dass die Entwicklererfahrung nicht gerade herausragend ist, insbesondere wenn ein Team wächst und wir mehr Zeit in der CI-Warteschlange verbringen als mit dem Zusammenführen unserer Änderungen. Es gibt viele Dinge, die wir tun können, um diese Probleme zu lindern:
Letztlich hängt dies direkt mit der Produktivität der Entwickler zusammen. Aber wir haben keine Profiler für diese Art von Optimierungen. Wir müssen jedes Mal messen; das kann mühsam sein.
GitHub Actions ist eine in GitHub integrierte Plattform für kontinuierliche Integration/kontinuierliche Bereitstellung (CI/CD). Es ist zustandslos, ermöglicht jedoch bis zu einem gewissen Grad das Selbst-Hosting von Agenten. Ich konzentriere mich darauf, da es für Open-Source-Projekte kostenlos ist und eine anständige kostenlose Quote für Closed-Source-Projekte hat.
Dieses Produkt ist ein relativ neuer Konkurrent auf diesem Gebiet und nicht so flexibel wie die meisten anderen zuvor genannten CI-Tools. Dank der umfassenden Integration mit GitHub und zustandslosen Agenten ist es jedoch für Entwickler sehr praktisch.
Um GitHub Actions zu testen, benötigen wir ein neues Projekt, das ich in diesem Fall mit JHipster mit der hier gezeigten Konfiguration generiert habe:
Ich habe hier ein separates Projekt erstellt, das die Verwendung von GitHub Actions demonstriert. Beachten Sie, dass Sie dies bei jedem Projekt befolgen können. Obwohl wir in diesem Fall Maven-Anweisungen einschließen, ist das Konzept sehr einfach.
Sobald das Projekt erstellt ist, können wir die Projektseite auf GitHub öffnen und zur Registerkarte „Aktionen“ wechseln.
Wir werden so etwas sehen:
In der unteren rechten Ecke sehen wir den Projekttyp Java mit Maven. Sobald wir diesen Typ ausgewählt haben, beginnen wir mit der Erstellung einer maven.yml
Datei, wie hier gezeigt:
Leider enthält die von GitHub vorgeschlagene Standard-maven.yml ein Problem. Dies ist der Code, den wir in diesem Bild sehen:
name: Java CI with Maven on: push: branches: [ "master" ] pull_request: branches: [ "master" ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' cache: maven - name: Build with Maven run: mvn -B package --file pom.xml # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive - name: Update dependency graph uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6
Die letzten drei Zeilen aktualisieren das Abhängigkeitsdiagramm. Aber diese Funktion schlägt fehl, oder zumindest ist sie bei mir fehlgeschlagen. Das Entfernen löste das Problem. Der Rest des Codes ist eine Standard-YAML-Konfiguration.
Die pull_request
und push
Zeilen oben im Code geben an, dass Builds sowohl auf einer Pull-Anfrage als auch auf einem Push an den Master ausgeführt werden. Das bedeutet, dass wir unsere Tests vor dem Commit auf einer Pull-Anfrage ausführen können. Wenn der Test fehlschlägt, verpflichten wir uns nicht.
Wir können das Commit mit fehlgeschlagenen Tests in den Projekteinstellungen verbieten. Sobald wir die YAML-Datei festgeschrieben haben, können wir eine Pull-Anfrage erstellen und das System führt den Build-Prozess für uns aus. Dazu gehört auch das Ausführen der Tests, da das „Paket“-Ziel in Maven standardmäßig Tests ausführt.
Der Code, der die Tests aufruft, befindet sich in der Zeile, die am Ende mit „run“ beginnt. Dies ist praktisch eine Standard-Unix-Befehlszeile. Manchmal ist es sinnvoll, ein Shell-Skript zu erstellen und es einfach über den CI-Prozess auszuführen.
Manchmal ist es einfacher, ein gutes Shell-Skript zu schreiben, als sich mit allen YAML-Dateien und Konfigurationseinstellungen verschiedener CI-Stacks herumzuschlagen.
Es ist auch tragbarer, wenn wir das CI-Tool in Zukunft wechseln. Hier brauchen wir es jedoch nicht, da Maven für unsere aktuellen Bedürfnisse ausreicht.
Den erfolgreichen Pull-Request können wir hier sehen:
Um dies zu testen, können wir dem Code einen Fehler hinzufügen, indem wir den Endpunkt “/api”
in “/myapi”
ändern. Dies führt zu dem unten gezeigten Fehler. Außerdem wird eine Fehler-E-Mail an den Autor des Commits gesendet.
Wenn ein solcher Fehler auftritt, können wir auf der rechten Seite auf den Link „Details“ klicken. Dies führt uns direkt zu der Fehlermeldung, die Sie hier sehen:
Leider handelt es sich hierbei in der Regel um eine nutzlose Nachricht, die keine Hilfe bei der Problemlösung bietet. Wenn Sie jedoch nach oben scrollen, wird der tatsächliche Fehler angezeigt, der für uns normalerweise praktischerweise hervorgehoben wird, wie hier zu sehen ist:
Beachten Sie, dass es häufig zu mehreren Fehlern kommt, sodass es ratsam ist, weiter nach oben zu scrollen. In diesem Fehler sehen wir, dass der Fehler eine Behauptung in Zeile 394
von AccountResourceIT war, die Sie hier sehen können. Beachten Sie, dass die Zeilennummern nicht übereinstimmen. In diesem Fall ist Zeile 394
die letzte Zeile der Methode:
@Test @Transactional void testActivateAccount() throws Exception { final String activationKey = "some activation key"; User user = new User(); user.setLogin("activate-account"); user.setEmail("[email protected]"); user.setPassword(RandomStringUtils.randomAlphanumeric(60)); user.setActivated(false); user.setActivationKey(activationKey); userRepository.saveAndFlush(user); restAccountMockMvc.perform(get("/api/activate?key={activationKey}", activationKey)).andExpect(status().isOk()); user = userRepository.findOneByLogin(user.getLogin()).orElse(null); assertThat(user.isActivated()).isTrue(); }
Dies bedeutet, dass der Assert-Aufruf fehlgeschlagen ist. isActivated()
hat false
zurückgegeben und den Test nicht bestanden. Dies sollte einem Entwickler helfen, das Problem einzugrenzen und die Grundursache zu verstehen.
Wie bereits erwähnt, geht es bei CI um die Produktivität der Entwickler. Wir können weit über das bloße Kompilieren und Testen hinausgehen. Wir können Codierungsstandards durchsetzen, den Code linten, Sicherheitslücken erkennen und vieles mehr.
In diesem Beispiel integrieren wir Sonar Cloud, ein leistungsstarkes Code-Analysetool (Linter). Es findet potenzielle Fehler in Ihrem Projekt und hilft Ihnen, die Codequalität zu verbessern.
SonarCloud ist eine cloudbasierte Version von SonarQube, die es Entwicklern ermöglicht, ihren Code kontinuierlich zu prüfen und zu analysieren, um Probleme im Zusammenhang mit Codequalität, Sicherheit und Wartbarkeit zu finden und zu beheben. Es unterstützt verschiedene Programmiersprachen wie Java, C#, JavaScript, Python und mehr.
SonarCloud lässt sich in beliebte Entwicklungstools wie GitHub, GitLab, Bitbucket, Azure DevOps und mehr integrieren. Entwickler können SonarCloud verwenden, um Echtzeit-Feedback zur Qualität ihres Codes zu erhalten und die Codequalität insgesamt zu verbessern.
Andererseits ist SonarQube eine Open-Source-Plattform, die statische Code-Analysetools für Softwareentwickler bereitstellt. Es bietet ein Dashboard, das eine Zusammenfassung der Codequalität anzeigt und Entwicklern hilft, Probleme im Zusammenhang mit Codequalität, Sicherheit und Wartbarkeit zu identifizieren und zu beheben.
Sowohl SonarCloud als auch SonarQube bieten ähnliche Funktionalitäten, aber SonarCloud ist ein cloudbasierter Dienst und erfordert ein Abonnement, während SonarQube eine Open-Source-Plattform ist, die vor Ort oder auf einem Cloud-Server installiert werden kann.
Der Einfachheit halber verwenden wir SonarCloud, aber SonarQube sollte einwandfrei funktionieren. Um zu beginnen, gehen wir zu sonarcloud.io und melden uns an. Idealerweise mit unserem GitHub-Konto. Anschließend wird uns die Option angezeigt, ein Repository für die Überwachung durch Sonar Cloud hinzuzufügen, wie hier gezeigt:
Wenn wir die Option „Neue Seite analysieren“ auswählen, müssen wir den Zugriff auf unser GitHub-Repository autorisieren. Im nächsten Schritt wählen wir die Projekte aus, die wir zur Sonar Cloud hinzufügen möchten, wie hier gezeigt:
Sobald wir den Einrichtungsprozess ausgewählt haben und mit dem Einrichtungsprozess fortfahren, müssen wir die Analysemethode auswählen. Da wir GitHub-Aktionen verwenden, müssen wir diese Option in der folgenden Phase auswählen, wie hier gezeigt:
Sobald dies festgelegt ist, betreten wir die letzte Phase des Sonar Cloud-Assistenten, wie im folgenden Bild dargestellt. Wir erhalten einen Token, den wir kopieren können (Eintrag 2 ist im Bild unscharf) und den wir in Kürze verwenden werden.
Beachten Sie, dass es auch Standardanweisungen zur Verwendung mit Maven gibt, die angezeigt werden, sobald Sie auf die Schaltfläche mit der Bezeichnung „Maven“ klicken.
Wenn wir zum Projekt in GitHub zurückkehren, können wir zur Registerkarte „Projekteinstellungen“ wechseln (nicht zu verwechseln mit den Kontoeinstellungen im oberen Menü). Hier wählen wir „Geheimnisse und Variablen“ aus, wie hier gezeigt:
In diesem Abschnitt können wir ein neues Repository-Geheimnis hinzufügen, insbesondere den SONAR_TOKEN-Schlüssel und -Wert, den wir aus der SonarCloud kopiert haben, wie Sie hier sehen können:
GitHub Repository Secrets ist eine Funktion, die es Entwicklern ermöglicht, vertrauliche Informationen im Zusammenhang mit einem GitHub-Repository sicher zu speichern, wie z. B. API-Schlüssel, Token und Passwörter, die zur Authentifizierung und Autorisierung des Zugriffs auf verschiedene vom Repository verwendete Dienste oder Plattformen von Drittanbietern erforderlich sind .
Das Konzept hinter GitHub Repository Secrets besteht darin, eine sichere und bequeme Möglichkeit zur Verwaltung und Weitergabe vertraulicher Informationen bereitzustellen, ohne die Informationen öffentlich in Code- oder Konfigurationsdateien offenlegen zu müssen.
Durch die Verwendung von Geheimnissen können Entwickler vertrauliche Informationen von der Codebasis trennen und sie vor Offenlegung oder Gefährdung im Falle einer Sicherheitsverletzung oder eines unbefugten Zugriffs schützen.
GitHub-Repository-Geheimnisse werden sicher gespeichert und können nur von autorisierten Benutzern aufgerufen werden, denen Zugriff auf das Repository gewährt wurde. Geheimnisse können in Workflows, Aktionen und anderen Skripts verwendet werden, die mit dem Repository verknüpft sind.
Sie können als Umgebungsvariablen an den Code übergeben werden, damit dieser sicher und zuverlässig auf die Geheimnisse zugreifen und diese nutzen kann.
Insgesamt bieten GitHub Repository Secrets Entwicklern eine einfache und effektive Möglichkeit, vertrauliche Informationen im Zusammenhang mit einem Repository zu verwalten und zu schützen und so die Sicherheit und Integrität des Projekts und der von ihm verarbeiteten Daten zu gewährleisten.
Das müssen wir nun in das Projekt integrieren. Zuerst müssen wir diese beiden Zeilen zur Datei pom.xml hinzufügen. Beachten Sie, dass Sie den Namen der Organisation aktualisieren müssen, damit er mit Ihrem eigenen übereinstimmt. Diese sollten in den Abschnitt im XML aufgenommen werden:
<sonar.organization>shai-almog</sonar.organization> <sonar.host.url>https://sonarcloud.io</sonar.host.url>
Beachten Sie, dass das von uns erstellte JHipster-Projekt bereits über SonarQube-Unterstützung verfügt, die aus der POM-Datei entfernt werden sollte , bevor dieser Code funktioniert.
Danach können wir den „Build with Maven“-Teil der maven.yml
Datei durch die folgende Version ersetzen:
- name: Build with Maven env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=shai-almog_HelloJHipster package
Sobald wir dies getan haben, stellt SonarCloud Berichte für jede im System zusammengeführte Pull-Anfrage bereit, wie hier gezeigt:
Wir können einen Bericht sehen, der eine Liste von Fehlern, Schwachstellen, Gerüchen und Sicherheitsproblemen enthält. Wenn wir auf jedes dieser Probleme klicken, gelangen wir zu etwa Folgendem:
Beachten Sie, dass wir über Registerkarten verfügen, die genau erklären, warum das Problem ein Problem darstellt, wie es behoben werden kann und vieles mehr. Dies ist ein bemerkenswert leistungsstarkes Tool, das als einer der wertvollsten Codeprüfer im Team dient.
Zwei weitere interessante Elemente, die wir zuvor gesehen haben, sind die Berichterstattungs- und Duplikationsberichte. SonarCloud geht davon aus, dass Tests eine Codeabdeckung von 80 % aufweisen (80 % des Codes in einem Pull-Request auslösen), dieser Wert ist hoch und kann in den Einstellungen konfiguriert werden.
Außerdem wird auf doppelten Code hingewiesen, der auf einen Verstoß gegen das Don't Repeat Yourself (DRY)-Prinzip hinweisen könnte.
CI ist ein umfangreiches Thema mit vielen Möglichkeiten, den Ablauf Ihres Projekts zu verbessern. Wir können die Erkennung von Fehlern automatisieren. Optimieren Sie die Artefaktgenerierung, die automatisierte Bereitstellung und vieles mehr. Aber meiner bescheidenen Meinung nach ist das Kernprinzip von CI die Entwicklererfahrung.
Es ist hier, um unser Leben einfacher zu machen.
Wenn es schlecht gemacht wird, kann der CI-Prozess dieses erstaunliche Tool in einen Albtraum verwandeln. Das Bestehen der Tests wird zu einer vergeblichen Übung. Wir versuchen es immer wieder, bis wir schließlich zusammenführen können. Aufgrund der langsamen und überfüllten Warteschlangen warten wir stundenlang auf den Zusammenschluss.
Dieses Tool, das helfen sollte, wird zu unserem Erzfeind. Das sollte nicht der Fall sein. CI soll unser Leben einfacher machen, nicht umgekehrt.