Docs-as-Code – Alles unter einem Dach
Schlechte Dokumentation kostet Geld
Im ersten Teil dieser Artikelreihe haben wir Ihnen den Docs-as-Code-Ansatz erläutert. Im zweiten Teil zeigten wir, wie Sie durch Automatisierung weitere Build-Schritte erzeugen, die Ihnen die Dokumentation erleichtern.
Dabei lag unser Fokus immer auf einem einzelnen Dokument. Die Dokumentation Ihres Teams wird hingegen aus einer Vielzahl unterschiedlicher Dokumente bestehen. Die offensichtlichen sind die Architekturdokumentation, ein Benutzerhandbuch und ein Entwicklerhandbuch. Betrachtet man andere Systeme, so spielt auch immer eine Landingpage als Einstieg in das System und ein Blog für aktuelle Informationen eine große Rolle. Ein Menü zur einfachen Navigation bildet schließlich die Klammer um all diese Dokumente (s. Abb. 1).
In diesem Artikel – dem dritten Teil der Serie – zeigen wir Ihnen, wie Sie mit Hilfe eines Static Site Generators alle benötigten Dokumente unter ein Dach bringen und eine Micro-Site für Ihr System bauen.
Anforderungen
Bevor wir uns der eigentlichen Lösung zuwenden, sollten wir zumindest grob die Anforderungen skizziert haben. Die meisten oben aufgeführten Dokumente können wir mit dem schon besprochenen Docs-as-Code-Ansatz prima erzeugen. Wir benötigen also ein System, welches den Docs-as-Code-Ansatz mit AsciiDoc unterstützt.
Beim Schreiben mit AsciiDoc steht der Content im Vordergrund, nicht das Layout und die Optik. Eine Landingpage muss jedoch optisch ansprechend aufgebaut sein. Das System muss also z. B. reines HTML für möglichst viel Freiheit bei der Gestaltung einer Landingpage erlauben. Und auch ein Blog hat spezielle Anforderungen. So benötigt ein Blog nicht nur die Darstellung der einzelnen Artikel (was in AsciiDoc sehr gut geht), sondern auch eine Auflistung aller Artikel nach Datum oder nach Kategorien/Tags.
Dokumentieren wir eine Bibliothek, die in mehreren Versionen produktiv im Einsatz ist, so muss auch unsere Dokumentation dem Rechnung tragen und in allen unterstützten Versionen vorliegen. Nicht zuletzt benötigen wir eine seitenübergreifende Suche. Strg+F reicht für eine einzelne Seite aus, für eine Dokumentations-Site benötigen wir etwas ausgefeilteres.
Static Site Generator (SSG)
Sie können alle oben genannten Anforderungen mit einem Static Site Generator lösen. Die statische Seite bietet dabei den Vorteil, dass sie selbst keine Anforderungen an ein spezielles Hosting mitbringt und durch die fehlende Dynamik sehr schnell ist. Sie besteht einfach nur aus statischen HTML-Seiten, die sogar aus einem lokalen Verzeichnis aufgerufen werden können.
Der Generator kümmert sich dabei um die "Dynamik". Jedes mal, wenn Sie eine Änderung an Ihrer Site vornehmen, kümmert er sich um das korrekte Einhängen Ihrer Dokumente in die Navigation, Verknüpfung von Seitenelementen (z. B. ein kleines Autorenprofil für jeden Blog-Artikel) und die Neugenerierung von Übersichtsseiten.
Durch diese Neugenerierung bei jeder Änderung, die Sie von Ihrem Code ja kennen, wird ein dynamisches Blog zu einer statischen Site. Dieser Ansatz macht Ihre Dokumentation auch extrem schnell, denn statische Seiten benötigen beim Ausliefern an den Browser keine Datenbankzugriffe oder andere Logik.
Die Wahl eines SSG
Auf staticgen.com sind ca. 250 Static Site Generators mit ein paar Attributen aufgeführt [1]. Genannt ist die Sprache der Implementierung und die Beliebtheit in Github-Sternchen. Die Unterstützung des Markup-Typs ist nicht genannt, weshalb wir für Sie ein wenig recherchiert haben und zu der in Abb. 1 gezeigten Auswahl gekommen sind. All diese SSGs unterstützen AsciiDoc und somit unseren Docs-as-Code-Ansatz.
HUGO
Hugo ist in Go geschrieben und dadurch extrem schnell. Das trägt zur Beliebtheit dieses SSGs bei. AsciiDoctor wird als externes Tool eingebunden und hebt diesen Vorteil zum Teil dadurch wieder auf. Für ein reines Java-Projekt ist Hugo mit seiner Implementierung in Go allerdings auch eher der Exot.
Antora
Antora ist nicht nur ein SSG, Antora bringt auch einen Git-Client mit und kann somit Dokumentation aus verschiedenen Git-Repositories automatisch einsammeln und entsprechend der Versionstags in verschiedenen Versionen generieren. Es ist das jüngste Projekt von Dan Allen, dem Kopf hinter Asciidoctor. Damit ist es nicht verwunderlich, dass die AsciiDoc-Unterstützung perfekt ist. Die Leistungsfähigkeit hat Antora schon durch den Einsatz bei größeren Open-Source-Projekten bewiesen. Eine Landing-Page oder ein Blog unterstützt es jedoch nicht, so dass man diese Elemente durch andere Werkzeuge bei Bedarf abdecken müsste. Antora ist mit Node.js realisiert.
Jekyll
Jekyll liegt in der Beliebtheit knapp vor Hugo (gemessen an den GitHub-Sternchen). Out of the Box wird MarkDown unterstützt. Das Asciidoctor-Projekt stellt ein Plugin zur Verfügung, mit dem Jekyll nach einer kleinen Konfiguration auch sehr gut AsciiDoc unterstützt [2]. Durch ein vielfältiges Angebot an Themes kommen Sie mit Jekyll schnell zu guten Ergebnissen. So ist z. B. die WebSite docs-as-co.de mit Jekyll und AsciiDoc aufgebaut [3]. Jekyll ist, wie Asciidoctor, in Ruby geschrieben.
jBake
jBake scheint eher der unbekannte Champion zu sein, weshalb wir im Folgenden unseren Ansatz mit jBake detaillierter vorstellen werden [4]. jBake unterstützt AsciiDoc direkt, ist als Command-Line-Tool, Maven- und Gradle-Plugin und als Library verfügbar. Durch die Unterstützung verschiedener Template-Engines (Freemarker, Groovy, Thymeleaf and Jade) ist jBake sehr flexibel. Für ein Java-Projekt ist der größte Vorteil wohl die Implementierung in Java und die perfekte Integration mit Maven und Gradle.
Umsetzung einer Site mit jBake
In den ersten Teilen haben wir als Build-Tool schon Gradle verwendet. Da jBake über eine entsprechende Gradle-Integration verfügt, ist die erste Umsetzung der Site trivial:
plugins {
id 'org.jbake.site' version '5.0.0'
}
jbake {
srcDirName = 'src/site'
destDirName = 'docs/html5/site'
configuration['asciidoctor.option.requires'] = "asciidoctor-diagram"
}
Auch hier verwenden wir wieder Asciidoctor mit dem Diagram-Plugin um PlantUML für Diagramme verwenden zu können.
Wenn Sie die ersten Teile der Folge aufmerksam verfolgt haben, wird Ihnen auffallen, dass wir in dieser Konfiguration src/site und nicht src/docs referenzieren. In der Praxis hat sich gezeigt, dass es durchaus Sinn macht, die Site von der eigentlichen Dokumentation zu trennen. So erstellen Sie z. B. Ihre arc42-Dokumentation klassisch mit einem Master-Template, welches alle Unterkapitel per include referenziert. Das Ergebnis ist ein großes Dokument.
In der Site funktioniert die Navigation jedoch besser, wenn Sie jedes Kapitel in der Top-Level-Navigation einzeln aufführen. Über die Trennung von Dokumentation (src/docs) und Site (src/site) ist das kein Problem. Sie legen einfach – ähnlich wie das arc42-Master-Template – für jede Seite ein Dokument an, welches auf beliebige Fragmente Ihrer Dokumentation per include verweist. Durch diesen Ansatz bauen Sie die Struktur Ihrer Site getrennt von der Dokumentation auf und bekommen mehr Flexibilität.
Navigation
jBake kann sich über ./gradlew bakeInit selbst initialisieren und so das benötigte site-Verzeichnis mit Templates etc. anlegen. jBake unterstützt dabei verschiedene Template-Engines. Wir verwenden in dem Beispiel Groovy als Engine, da wir ja schon in der Java-Welt sind und auch in Gradle Groovy verwenden. Das Original-Template baut die Site-Navigation in HTML mit Twitter-Bootstrap auf. Da dies schnell unübersichtlich wird, haben wir das Template dank Groovy so umgeschrieben, dass die Navigation über eine Map definiert wird:
Das Navigationsmenu
def nav = [
title: 'Docs-as-Code',
entries: [
'Artikel': [
'Die Grundlagen': 'artikel/folge1',
'Die Werkzeuge': 'artikel/folge2',
'Alles unter einem Dach': 'artikel/folge3'
],
'Tests': 'tests/',
'News': 'news/',
'About': 'about/',
]
]
Table of Contents (TOC)
Das CSS von AsciiDoc verträgt sich sehr gut mit den Styles von Twitter-Bootstrap. Allerdings sieht jBake keinen Table of Contents für die AsciiDoc-Seiten vor, so dass wir auch hier eine Anpassung vorgenommen haben. Schnell sind dem header.gsp-Template ein paar CSS-Styles hinzugefügt und ein neues page_toc.gsp-Template angelegt. Wir können nun pro Seite wählen, ob wir einen TOC darstellen wollen oder nicht.
Landing Page
AsciiDoc ist prima für technische Dokumentation. Für eine ansprechende Landingpage, die einen guten ersten Eindruck unseres Projekts vermitteln soll, gehen wir dann doch auf Plain-HTML zurück. Durch die Verwendung von Bootstrap fällt es leicht, eine ansprechende Seite aufzubauen, die auch responsive ist und sich somit mobil wie auch auf dem Desktop als Aushängeschild eignet. Twitter-Bootstrap hat an dieser Stelle den Vorteil des mittlerweile hohen Bekanntheitsgrads.
HTML-Sanity-Check
In der letzten Folge haben wir Ihnen gezeigt, wie Sie Ihre generierten HTML-Dokumente mit HTML-Sanity-Check auf Fehler überprüfen können. Da dieses Überprüfen nach dem Generieren der Site durch jBake erfolgt, kann jBake den erstellten Report nicht mehr in die Webseite selbst einbetten. Auch hierfür haben wir eine Lösung in der Trickkiste, denn für jede Seite haben wir die Wahl der Template-Engine in dem wir die Dateiendung wählen. Wenn wir für den Test-Report HTML als Template-Engine wählen, dann können wir den Report einfach per iFrame einbinden.
tests.html
title=Test Report
date=2013-07-24
type=page
status=published
~~~~~~
<iframe
src="report/htmlchecks/index.html"
style="width: 100%; height: 90vh; border: 0; z-index:-1000;"
wmode="transparent"
></iframe>
Das ist nicht ganz perfekt, erfüllt aber durchaus seinen Zweck.
Blog und Architecture Decision Records (ADRs)
Zu guter Letzt wollen wir auch den Leser mit einzelnen Nachrichtenbeiträgen im Stil eines Blog auf dem Laufenden halten. Hier bringt jBake die nötige Funktionalität gleich mit. Neue Artikel werden einfach als AsciiDoc mit einem Header für die Metadaten versehen und in das Verzeichnis site/news gelegt. Über das Attribut :jbake-tags: vergeben Sie für jeden Blog-Eintrag Tags und jBake erstellt automatisch entsprechende Übersichtsseiten.
Blog-Header
= Neuer Artikel "Die Werkzeuge"
:jbake-type: post
:jbake-date: 2019-05-02
:jbake-status: published
:jbake-tags: asciidoc, documentation
Wenn Sie nun im Verlauf Ihres Projekts Architekturentscheidungen treffen, schreiben Sie diese doch einfach als Blog-Beitrag und versehen sie mit einem entsprechenden Tag ADR. Damit findet jeder Projektbeteiligte schnell im Blog alle neuen Entscheidungen.
Wenn Sie den Dateinamen des Beitrags nun auch noch nach dem Schema ADR-0123… bilden, dann können Sie all diese Beiträge leicht mit dem collectIncludes-Task von docToolchain einsammeln und automatisch in Kapitel 9: "Entwurfsentscheidungen" Ihrer arc42-Dokumentation zufügen.
Suche
In größeren AsciiDoc-Dokumenten lassen sich über die Suche des Browsers (Strg+F) Begriffe gut finden. Wird das Dokument über mehrere Navigationselemente verteilt und gibt es mehrere solcher Dokumente, ist Strg+F nicht mehr ausreichend. Über Tools wie Lunr.js lässt sich auch auf einem statischen System eine Suche per JavaScript auf dem Client implementieren [5]. Allerdings erzeugen Sie damit eine Dokumentations-Insel. Gerade im Unternehmenskontext möchten Sie Ihre Dokumentation auch über die zentrale Suche finden können. Die meisten Suchmaschinen unterstützen zu diesem Zweck eine Einschränkung der Suche auf die Domain der Website.
Bei Google funktioniert das über den Parameter site im Suchfeld. So findet die Suchanfrage site:docs-as-co.deAsciiDoc alle entsprechenden Dokumente auf unserer Website [6]. Somit kann eine Suche mit einem einfachen Form-Tag in Ihre Microsite eingebunden werden. Das vollständige Beispiel zu diesem einfachen Form-Tag finden Sie wieder in unserem Github-Repository [7].
Fazit
Nachdem Sie im ersten Teil die Grundlagen und im zweiten die Werkzeuge des Docs-as-Code-Ansatzes kennengelernt haben, wissen Sie nun auch, wie Sie die verschiedenen Teile Ihrer Dokumentation mit jBake zusammenführen können. jBake hat dabei unter Beweis gestellt, dass er sich hinter anderen Static-Site-Generatoren nicht zu verstecken braucht und den Ansprüchen gewachsen ist. Im Gegenteil – in einem Java-Projekt bietet jBake eine perfekte Integration in Ihren Build.
Noch mehr Informationen finden Sie auch auf Docs-as-Co.de [3]. In unserem Beispiel-Repository finden Sie diesen Artikel (zusammen mit den beiden ersten) auch als Microsite umgesetzt [7].
In diesem Sinne wünschen wir viel Erfolg mit dem Docs-as-Code-Ansatz!