
In großen Projekten, die aus Dutzenden und Hunderten von interagierenden Diensten bestehen, wird ein Ansatz zur Dokumentation als Code - Dokumente als Code - immer zwingender.
Ich werde zeigen, wie Sie diese Philosophie in der Realität des klassifizierten Dienstes anwenden können, oder besser gesagt, ich beginne mit der ersten Phase ihrer Implementierung: der Automatisierung der Aktualisierung von Daten in der Dokumentation.
Werkzeugsatz
Das Prinzip „Dokumentation als Code“ impliziert die Verwendung derselben Tools beim Schreiben von Dokumentation wie beim Erstellen von Code: Textauszeichnungssprachen, Versionskontrollsysteme, Codeüberprüfung und automatische Tests. Das Hauptziel: Schaffung von Bedingungen für die Zusammenarbeit des gesamten Teams am Endergebnis - eine vollständige Wissensbasis und Anweisungen zur Verwendung einzelner Produktdienstleistungen. Als nächstes werde ich über spezifische Tools sprechen, die wir ausgewählt haben, um dieses Problem zu lösen.
Als Text-Markup-Sprache haben wir uns für den universellsten entschieden - reStructuredText . Neben einer Vielzahl von Anweisungen, die alle grundlegenden Funktionen zum Strukturieren von Text bereitstellen, unterstützt diese Sprache wichtige endgültige Formate, einschließlich des für unser Projekt erforderlichen HTML-Codes.
Dateien werden mit dem Sphinx- Dokumentationsgenerator von .rst nach .html konvertiert. Sie können statische Websites erstellen, für die Sie eigene Themen erstellen oder vorgefertigte Themen verwenden können . Unser Projekt verwendet zwei vorgefertigte Themen - Stanford-Thema und Bootstrap-Thema . Das zweite enthält Unterthemen, mit denen Sie verschiedene Farbschemata für wichtige Elemente der Benutzeroberfläche festlegen können.
Für einen bequemen und schnellen Zugriff auf die aktuelle Version der Dokumentation verwenden wir eine statische Site, die von einer virtuellen Maschine gehostet wird, auf die über das lokale Netzwerk des Entwicklungsteams zugegriffen werden kann.
Die Quelldateien des Projekts werden im Bitbucket-Repository gespeichert, und die Site wird nur aus den im Hauptzweig enthaltenen Dateien generiert. Das Aktualisieren der darin enthaltenen Daten ist nur über eine Pull-Anfrage möglich, mit der Sie alle neuen Abschnitte der Dokumentation überprüfen können, bevor sie öffentlich veröffentlicht werden.
Da zwischen dem Abschluss eines neuen Abschnitts der Dokumentation und dem Senden an die Site der Inhalt überprüft werden muss, besteht der Schlüsselprozess in der gesamten Kette darin, die Site zu erstellen und die Daten auf dem Host zu aktualisieren. Dieser Vorgang sollte jedes Mal wiederholt werden, nachdem die Pull-Anforderung mit dem Update mit dem Hauptzweig des Projekts zusammengeführt wurde.

Die Implementierung dieser Logik ermöglicht Jenkins - in unserem Fall ein System zur kontinuierlichen Integration der Entwicklung - Dokumentation. Ich werde Ihnen mehr über die Einstellungen in den Abschnitten erzählen:
- Hinzufügen eines neuen Knotens zu Jenkins
- Beschreibung von Jenkinsfile
- Jenkins und Bitbucket Integration
Hinzufügen eines neuen Knotens zu Jenkins
Um die Dokumentation auf der Site zu erstellen und zu aktualisieren, müssen Sie einen Computer vorbereiten, der zuvor als Jenkins- Agent dafür vorbereitet wurde.
Maschinenvorbereitung
Gemäß den Jenkins-Anforderungen muss auf allen im System enthaltenen Komponenten, einschließlich der Master-Maschine und aller registrierten Agentenknoten, JDK oder JRE installiert sein. In unserem Fall wird JDK 8 verwendet, für dessen Installation der Befehl ausgeführt werden kann:
sudo apt-get -y install java-1.8.0-openjdk git
Der Master-Computer stellt eine Verbindung zum Agenten her, um ihm zugewiesene Aufgaben auszuführen. Dazu müssen Sie auf dem Agenten einen Benutzer erstellen, unter dem alle Vorgänge ausgeführt werden und in dem alle von Jenkins generierten Dateien im Home-Ordner gespeichert werden. Führen Sie auf Linux-Systemen einfach den folgenden Befehl aus:
sudo adduser jenkins \--shell /bin/bash su jenkins
Um eine Verbindung zwischen dem Master-Computer und dem Agenten herzustellen, müssen Sie SSH konfigurieren und die erforderlichen Autorisierungsschlüssel hinzufügen. Wir werden die Schlüssel auf dem Agenten generieren und danach den öffentlichen Schlüssel zur Datei " authorized_keys
" für den Benutzer " jenkins" hinzufügen.
Wir werden die Site mit der Dokumentation in einem Docker-Container unter Verwendung eines vorgefertigten Python- Images erstellen : 3.7 . Befolgen Sie die Anweisungen in der offiziellen Dokumentation , um Docker auf dem Agenten zu installieren. Um den Installationsvorgang abzuschließen, müssen Sie erneut eine Verbindung zum Agenten herstellen. Überprüfen Sie die Installation, indem Sie den Befehl ausführen, mit dem das Testabbild geladen wird:
docker run hello-world
Um Docker-Befehle nicht im Namen des Superusers (sudo) ausführen zu müssen, reicht es aus, die in der Installationsphase erstellte Benutzer-Docker-Gruppe hinzuzufügen, für die die Befehle ausgeführt werden.
sudo usermod -aG docker $USER
Jenkins neue Knotenkonfiguration
Da für die Verbindung zum Agenten eine Autorisierung erforderlich ist, müssen Sie die entsprechenden Anmeldeinformationen in den Jenkins-Einstellungen hinzufügen. Detaillierte Anweisungen dazu auf Windows-Computern finden Sie in der offiziellen Jenkins-Dokumentation .
WICHTIG: Die im Abschnitt Jenkins konfigurieren -> Build-Umgebungen verwalten -> Knotenname -> Im Parameter Tags konfigurieren angegebene Kennung wird in Jenkinsfile verwendet , um den Agenten anzugeben, auf dem alle Vorgänge ausgeführt werden.
Beschreibung von Jenkinsfile
Das Stammverzeichnis des Projekt-Repositorys enthält die Jenkins-Datei , die Anweisungen enthält für:
- Vorbereiten der Build-Umgebung und Installieren von Abhängigkeiten
- Erstellen Sie eine Site mit Sphinx
- Aktualisieren der Hostinformationen.
Anweisungen werden mithilfe spezieller Anweisungen festgelegt, deren Anwendung wir am Beispiel der im Projekt verwendeten Datei weiter betrachten werden.
Agentenanzeige
Geben Sie zu Beginn der Jenkins- Datei die Bezeichnung des Agenten in Jenkins an , für den alle Vorgänge ausgeführt werden sollen. Verwenden Sie dazu die Agentenanweisung :
agent { label '-' }
Umweltvorbereitung
Um den Befehl sphinx-build site build auszuführen, müssen Sie Umgebungsvariablen festlegen, in denen die tatsächlichen Datenpfade gespeichert werden. Um die Informationen auf dem Host zu aktualisieren, müssen Sie im Voraus die Pfade angeben, in denen die Standortdaten mit der Dokumentation gespeichert sind. Mit der Umgebungsrichtlinie können Sie diese Werte Variablen zuweisen:
environment { SPHINX_DIR = '.' //, Sphinx BUILD_DIR = 'project_home_built' // SOURCE_DIR = 'project_home_source' // .rst .md DEPLOY_HOST = 'username@127.1.1.0:/var/www/html/' //@IP__:__ }
Hauptaktionen
Die Hauptanweisungen, die in Jenkinsfile ausgeführt werden, sind in der Stufenanweisung enthalten, die aus den verschiedenen Schritten besteht, die durch die Stufenanweisungen beschrieben werden . Ein einfaches Beispiel für eine dreistufige CI-Pipeline:
pipeline { agent any stages { stage('Build') { steps { echo 'Building..' } } stage('Test') { steps { echo 'Testing..' } } stage('Deploy') { steps { echo 'Deploying....' } } } }
Starten Sie den Docker-Container und installieren Sie Abhängigkeiten
Führen Sie zunächst den Docker-Container mit dem fertigen Python- Image aus : 3.7 . Verwenden Sie dazu den Befehl docker run mit den Flags --rm und -i . Führen Sie dann nacheinander folgende Schritte aus:
- Installieren Sie Python Virtualenv .
- Erstellen und Aktivieren einer neuen virtuellen Umgebung;
- Installieren Sie darin alle erforderlichen Abhängigkeiten, die in der Datei aufgeführt sind
require.txt, die im Stammverzeichnis des Projekt-Repositorys gespeichert ist.
stage('Install Dependencies') { steps { sh ''' docker run --rm -i python:3.7 python3 -m pip install --user --upgrade pip python3 -m pip install --user virtualenv python3 -m virtualenv pyenv . pyenv/bin/activate pip install -r \${SPHINX\_DIR}/requirements.txt ''' } }
Erstellen Sie eine Site mit Dokumentation
Jetzt erstellen wir eine Site. Führen Sie dazu den Befehl sphinx-build mit den folgenden Flags aus:
-q
: nur Protokollwarnungen und Fehler;
-w
: schreibe ein Protokoll in die nach dem Flag angegebene Datei;
-b
: Name des Site Builders;
-d
: Geben Sie das Verzeichnis zum Speichern zwischengespeicherter Dateien an - doctree pickles.
Löschen Sie vor dem Starten der Assembly mit dem rm -rf
die vorherige Site-Assembly und die Protokolle. Im Falle eines Fehlers in einer der Phasen wird das Ausführungsprotokoll für die Sphinx-Erstellung in der Jenkins- Konsole angezeigt.
stage('Build') { steps { // clear out old files sh 'rm -rf ${BUILD_DIR}' sh 'rm -f ${SPHINX_DIR}/sphinx-build.log' sh ''' ${WORKSPACE}/pyenv/bin/sphinx-build -q -w ${SPHINX_DIR}/sphinx-build.log \ -b html \ -d ${BUILD_DIR}/doctrees ${SOURCE\_DIR} ${BUILD\_DIR} ''' } post { failure { sh 'cat ${SPHINX_DIR}sphinx-build.log' } } }
Host-Site-Update
Und schließlich werden wir die Informationen auf dem Host, der die Site bedient, mit der in der lokalen Umgebung verfügbaren Produktdokumentation aktualisieren. In der aktuellen Implementierung ist der Host dieselbe virtuelle Maschine, die als Jenkins-Agent für die Zusammenstellung und Aktualisierung der Dokumentation registriert ist.
Als Synchronisationstool verwenden wir das Dienstprogramm rsync . Damit es ordnungsgemäß funktioniert, muss eine SSH-Verbindung zwischen dem Docker-Container, in dem sich die Site mit der Dokumentation befand, und dem Host konfiguriert werden.
Um die SSH-Verbindung mit Jenkinsfile zu konfigurieren, müssen die folgenden Plugins in Jenkins installiert sein :
- SSH Agent Plugin - Mit dieser
sshagent
können Sie den Schritt sshagent
in Skripten verwenden, um Anmeldeinformationen für den Benutzernamen / Schlüssel des Formulars bereitzustellen. - SSH Credentials Plugin - Ermöglicht das Speichern von Anmeldeinformationen des Formularbenutzernamens / -schlüssels in den Jenkins- Einstellungen.
Nach der Installation der Plugins müssen Sie die aktuellen Anmeldeinformationen für die Verbindung zum Host angeben, indem Sie das Formular im Abschnitt Anmeldeinformationen ausfüllen:
- ID : Kennung, die in Jenkinsfile in Schritt
sshagent
, um bestimmte Anmeldeinformationen anzugeben ( docs-deployer
); - Benutzername : Der Benutzername, unter dem die Aktualisierungsvorgänge für die Site-Daten ausgeführt werden (der Benutzer muss Schreibzugriff auf den Ordner
/var/html
des Hosts haben). - Privater Schlüssel : Ein privater Schlüssel für den Zugriff auf den Host.
- Passphrase : Passwort für den Schlüssel, falls dieser in der Generierungsphase festgelegt wurde.
Unten finden Sie den Skriptcode, der über SSH eine Verbindung herstellt und die Informationen auf dem Host mithilfe der Systemvariablen aktualisiert, die in der Phase der Vorbereitung der Umgebung mit den Pfaden zu den erforderlichen Daten angegeben wurden. Das Ergebnis des Befehls rsync wird in das Protokoll geschrieben, das bei Synchronisationsfehlern in der Jenkins- Konsole angezeigt wird.
stage('Deploy') { steps { sshagent(credentials: ['docs-deployer']) { sh ''' #!/bin/bash rm -f ${SPHINX_DIR}/rsync.log RSYNCOPT=(-aze 'ssh -o StrictHostKeyChecking=no') rsync "${RSYNCOPT[@]}" \ --delete \ ${BUILD_DIR_CI} ${DEPLOY_HOST}/ ''' } } post { failure { sh 'cat ${SPHINX_DIR}/rsync.log' } } }
Jenkins und Bitbucket Integration
Es gibt viele Möglichkeiten, die Interaktion von Jenkins und Bitbucket zu organisieren. In unserem Projekt haben wir uns jedoch für das Plugin " Parametrisierte Builds für Jenkins" entschieden . Die offizielle Dokumentation enthält detaillierte Anweisungen zur Installation des Plugins sowie die Einstellungen, die für beide Systeme angegeben werden müssen. Um mit diesem Plugin arbeiten zu können, müssen Sie einen Jenkins- Benutzer erstellen und ein spezielles Token für ihn generieren, mit dem sich dieser Benutzer beim System anmelden kann.
Erstellen eines Benutzer- und API-Tokens
Um einen neuen Benutzer in Jenkins zu erstellen, gehen Sie zu Jenkins-Einstellungen -> Benutzerverwaltung -> Benutzer erstellen und füllen Sie alle erforderlichen Anmeldeinformationen im Formular aus.
Der Authentifizierungsmechanismus, mit dem Skripts oder Anwendungen von Drittanbietern die Jenkins-API verwenden können, ohne das Benutzerkennwort tatsächlich zu übertragen, ist ein spezielles API-Token, das für jeden Jenkins- Benutzer generiert werden kann. Dafür:
- Melden Sie sich bei der Verwaltungskonsole mit den Details des zuvor erstellten Benutzers an.
- Gehen Sie zu Jenkins konfigurieren -> Benutzerverwaltung .
- Klicken Sie auf das Zahnradsymbol rechts neben dem Benutzernamen, unter dem sie im System autorisiert sind.
- Suchen Sie die Token-API in der Liste der Parameter und klicken Sie auf die Schaltfläche Neues Token hinzufügen.
- Geben Sie im angezeigten Feld die Kennung des API-Tokens an und klicken Sie auf die Schaltfläche Generieren .
- Kopieren Sie das generierte API-Token und speichern Sie es, indem Sie der Eingabeaufforderung auf dem Bildschirm folgen.
Jetzt können Sie in den Einstellungen des Bitbucket- Servers den Standardbenutzer angeben, der eine Verbindung zu Jenkins herstellen soll .
Fazit
Wenn früher, bestand der Prozess aus mehreren Schritten:
- Laden Sie das Update in das Repository herunter
- Warten Sie auf die Bestätigung der Richtigkeit.
- eine Website mit Dokumentation zusammenstellen;
- Informationen auf dem Host aktualisieren;
Klicken Sie jetzt einfach auf eine Schaltfläche In Bitbucket zusammenführen. Wenn nach der Überprüfung keine Änderungen an den Quelldateien erforderlich sind, wird die aktuelle Version der Dokumentation sofort nach Bestätigung der Richtigkeit der Daten aktualisiert.
Dies vereinfacht die Aufgabe des technischen Redakteurs erheblich und erspart ihm eine Vielzahl manueller Aktionen. Projektmanager erhalten ein praktisches Tool zum Verfolgen von Dokumentationsergänzungen und Feedback.
Die Automatisierung dieses Prozesses ist der erste Schritt beim Aufbau einer Dokumentationsverwaltungsinfrastruktur. In Zukunft planen wir, automatische Tests hinzuzufügen, die die Richtigkeit der in der Dokumentation verwendeten externen Links überprüfen, und interaktive Schnittstellenobjekte zu erstellen, die in vorgefertigte Themen für Sphinx integriert sind .
Dank derer, die dies zur Kenntnis genommen haben, werden wir bald weiterhin die Details der Dokumentationserstellung in unserem Projekt teilen!