Runme turns your documentation into interactive runbooks

29.05.2024Ricky Elfner
DevOps Developer Experience DevOps Cloud Computing hands-on API https

Banner

Hat nicht jeder, der Readme-Dateien durchliest, den Wunsch, den entsprechenden Code direkt auszuführen und zu testen? Genau hier setzt Runme.dev an. Das Ziel ist es, die Ausführung und Verwaltung von Runbooks zu verbessern, indem es diese wirklich ausführbar macht. Dadurch können Nutzer schrittweise Anleitungen befolgen – eine ideale Lösung für Runbooks, Playbooks und Dokumentationen, die interaktive, ausführbare Schritte erfordern.

Mit der Kombination aus interaktiven Notebooks und Markdown können Nutzer Anweisungen ausführen, Zwischenergebnisse überprüfen und sicherstellen, dass die Ergebnisse den Erwartungen entsprechen. Dies bietet den Nutzern die nötige Sicherheit, die Schritte erfolgreich abzuschließen. Entwickler können dadurch auch zuverlässige Wege für Aufgaben wie das lokale Setup definieren und dies für andere Entwickler dokumentieren.

Runme ist dabei wie eine Terminal-Sitzung und unterstützt eine Vielzahl von Programmier- und Skriptsprachen und ist vollständig kompatibel mit CommonMark. Dies ermöglicht es, nicht nur Readmes, sondern sämtliche Markdown-Dokumente mit Runme zu verwenden. Runme funktioniert überall, unabhängig von der Umgebung – ob auf einem lokalen Laptop, in einer VM, einem Cloud-Entwicklungsumfeld oder angebunden an einen Remote-Host via SSH. Runme ist vergleichbar mit einem Jupyter Notebook nur mit viel mehr Möglichkeiten.

Die gesamten Funktionen lassen sich jedoch am besten in einer praktischen Demonstration zeigen. Deshalb: Los geht’s!

Hands-on

Um Runme zu nutzen, gibt es verschiedene Möglichkeiten, die ich nun zeigen werde.

VS Code

Eine Möglichkeit ist die Installation via Microsoft Marketplace. Dadurch lässt sich Runme direkt als Erweiterung innerhalb von VS Code nutzen. Die folgenden Beispiele werden ebenfalls mit VS Code durchgeführt, da man hier den größten Funktionsumfang hat.

Öffnet man nun eine README.md-Datei, erkennt man direkt, dass hier nun einige neue Funktionen mittels unterschiedlichen Buttons bereitgestellt werden. Die wichtigsten sind dabei +Code und +Markdown, um entsprechende Codeblöcke zu definieren.

Für unser erstes Beispiel nutzen wir zunächst einen Markdown-Block, der etwas beschreibt. Der zweite Block enthält dann unser erstes Command. Dies könnte dann wie folgt aussehen:

CLI

Wenn wir nun auf der linken Seite den Play-Button klicken, öffnet sich direkt darunter ein Terminal, in dem das entsprechende Command ausgeführt wird.

Um zu überprüfen, ob die Installation aus unserem Beispiel erfolgreich war, erstellen wir zunächst einen weiteren Markdown- und Code-Block. Dieser soll einfach einen Ping gegen Google ausführen.

Als Nächstes öffnen wir ein Terminal und führen den Befehl runme aus. Dadurch wird unsere README-Datei von Runme geöffnet und zeigt uns alle Code-Blöcke an, die wir definiert haben.

Zunächst möchten wir das Ping-Beispiel über das Terminal ausführen. Mit den Pfeiltasten kann man einfach den gewünschten Code-Block auswählen und mit der Enter-Taste ausführen. Anschließend sieht man das Ergebnis direkt im Terminal unterhalb des ausgeführten Befehls.

Webserver

Runme bietet zudem die Möglichkeit, sich selbst als lokalen Server zu starten. Voraussetzung dafür ist jedoch eine erfolgreiche Installation der CLI. Ist diese gegeben, kann man mit dem Befehl runme open starten. Sollte der code-server nicht installiert sein, erhält man folgende Meldung und muss die Installation durchführen:

1
No code-server installation found. Do you want to install coder's code-server? [Y/n]

Nach Abschluss dieser Installation wird Runme automatisch im Standard-Webbrowser gestartet.

Basics

Wenn man einen Code-Block in VS Code definiert, stehen verschiedene Einstellungsoptionen zur Verfügung, die wir uns näher betrachten sollten. Diese unterteilen sich in allgemeine und erweiterte Einstellungen.

General

name

Die erste Einstellungsmöglichkeit ist name, der dazu dient, den entsprechenden Code-Block zu identifizieren. In Runme werden diese Code-Blöcke als cells bezeichnet und sind standardmäßig unbenannt. Wie wir bereits gesehen haben, werden alle Code-Blöcke in der CLI angezeigt, wenn man runme im Terminal ausführt. Der Name, den wir in den Einstellungen unter name definieren, ist auch derjenige, der in der CLI für jeden Code-Block angezeigt wird.

cwd

Mit der Einstellung cwd wird das aktuelle Arbeitsverzeichnis angepasst. Wichtig ist dabei, dass, wenn das Arbeitsverzeichnis sowohl für das gesamte Dokument als auch für einzelne Zellen festgelegt wird, diese sich nicht gegenseitig überschreiben – die Werte kombinieren sich einfach. Setzt man also für das Dokument den cwd auf /tmp/dummy und für die Zelle auf .., ergibt sich der Pfad /tmp.

promptEnv

In jedem Code-Block können spezifische Umgebungsvariablen genutzt werden, die sogar während der Ausführung eingegeben werden können; dies geschieht über die Einstellung promptEnv. Nutzer haben die Möglichkeit, diese Einstellung auf “Yes” zu setzen, wodurch das System dann auf eine Benutzereingabe wartet. Bei einer Einstellung auf “No” verwendet das System automatisch die innerhalb des Code-Blocks festgelegten Werte. Die Option “Auto” passt das Verhalten automatisch an, abhängig davon, ob eine Variable bereits definiert wurde oder nicht.

interactive

Die Runme-Zellen können als interaktive oder nicht-interaktive Zellen konfiguriert werden. Interaktive Zellen (interactive=true) ermöglichen es dem Benutzer, während der Ausführung Eingaben zu machen. Dies ist besonders hilfreich, wenn der Benutzer auf die Ausgabe reagieren oder Einstellungen vor der Fortsetzung des Codes ändern muss. Nicht-interaktive Zellen (interactive=false) hingegen erwarten keine Benutzereingaben und geben ihre Ergebnisse direkt in das Notebook aus. Sie eignen sich besonders gut dafür, wenn die Ausgabe als Eingabe für nachfolgende Zellen verwendet werden soll.

Advanced

Nun werfen wir einen Blick auf den Advanced-Tab in den Einstellungen, um weitere Konfigurationsmöglichkeiten zu erkunden. Dieser Bereich bietet zusätzliche Optionen, die es ermöglichen, die Funktionalität und das Verhalten der Code-Blöcke in spezifischeren Szenarien anzupassen.

background

Je nach Command kann es ausreichen, diesen im Hintergrund auszuführen, etwa wenn man anfänglich verschiedene Umgebungsvariablen setzt oder sonstige Setup-Aufgaben erledigt. Dafür kann man einfach die Option background aktivieren.

mimeType

Eine weitere nützliche Funktion ist das Definieren des mimeType. Hier gibt es unterschiedliche Möglichkeiten, wie auf der offiziellen Dokumentationsseite ersichtlich. Der Standardwert ist text/plain. Ohne Anpassungen dieses Wertes würde beispielsweise bei einem Command der folgende Output angezeigt werden:

Ändert man jedoch den Parameter mimeType auf image/svg+xml, wird das entsprechende Bild angezeigt:

Ein weiteres Beispiel für die Nutzung von MIME-Typen ist der Einsatz von text/csv in Kombination mit der Extension Data Table Renderers aus dem VS Code Marketplace. Diese Extension ermöglicht die grafische Darstellung von Tabellen. Ich habe dazu zwei Beispiele erstellt: Das erste Beispiel verwendet den Standard-MIME-Typ text/plain und zeigt einfach den Inhalt der CSV-Datei an. Das zweite Beispiel verwendet hingegen text/csv als MIME-Typ, wodurch der Inhalt der Datei in Form einer übersichtlichen Tabelle dargestellt wird.

Interpreter & Shebang

Eine nützliche Einstellung ist der Shebang-Support. Die aktuelle Unterstützung, bei der der Interpreter automatisch erkannt wird, ist auf der offiziellen Dokumentationsseite dokumentiert. Dadurch ist es möglich, verschiedene Programmiersprachen innerhalb der Code-Blöcke zu verwenden. Die gewünschte Sprache kann oben rechts in der Ecke des Code-Blocks ausgewählt werden.

Sollte es sich um eine Sprache handeln, die nicht automatisch erkannt wird, muss der entsprechende Interpreter im Advanced-Einstellungstab definiert werden. Wenn man beispielsweise Java verwenden möchte, muss im Code-Block zunächst der gewünschte Code hinzugefügt und die Shebang-Einstellung auf Java gesetzt werden.

In meinem Fall lautete der Pfad für den Java-Interpreter:

1
/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/java --source 17

Anschließend kann der Code-Block ausgeführt werden, woraufhin der gewünschte Output im Terminal angezeigt wird.

terminalRows

In Runme werden die Ausgaben in Zeilen/Reihen angezeigt. Die Anzahl dieser Zeilen, in denen eine Ausgabe dargestellt werden soll, lässt sich durch eine Einstellung namens terminalRows festlegen. Diese Einstellung ermöglicht es Ihnen, die Anzahl der Zeilen zu bestimmen, in denen Ihre Ausgabe unterhalb einer Zelle sichtbar wird. Wenn keine spezifische Terminalzeile festgelegt ist, verwendet Runme standardmäßig 10 Zeilen zur Darstellung der Ausgaben.

excludeFromRunAll

Jedes VS Code-Notebook ermöglicht es den Benutzern, alle verfügbaren Zellen auf einmal auszuführen. Dies kann besonders nützlich sein, wenn ein vollständiges Runbook in der Markdown-Datei definiert ist, sodass Entwickler auf den Button “Alle ausführen” klicken können, um alles einzurichten und zu starten.

Mit dem excludeFromRunAll kann verhindert werden, dass dieses Block bei Run All ausgeführt wird.

category

Im “Advanced”-Tab der Einstellungen besteht die Möglichkeit, einzelne Code-Blöcke einer bestimmten Kategorie zuzuordnen. Ein praktischer Anwendungsfall hierfür wäre beispielsweise, wenn mehrere Code-Blöcke für das Setup eines Projekts benötigt werden. In diesem Fall könnte man eine passende Kategorie erstellen und diese allen relevanten Code-Blöcken zuweisen. Anschließend kann man in VS Code die Funktion “Execute by Category” nutzen, die gewünschte Kategorie auswählen und alle zugehörigen Code-Blöcke werden der Reihe nach ausgeführt.

Auch hierfür habe ich ein Beispiel angelegt. Dabei gibt es category01 und category02:

Nun möchten wir nur die category01 ausführen. Dies hätte dann folgenden Output:

Piping

Eine weitere nützliche Funktion ist das Piping zwischen den Codeblöcken. Hierbei ist es möglich, dass der Output eines Codeblocks als Input innerhalb eines anderen Codeblocks verwendet werden kann. Dies ermöglicht eine flexible und effiziente Datenverarbeitung, indem Ergebnisse eines Prozesses direkt in den nächsten Schritt überführt werden können.

In dem Beispiel gibt es zunächst einen Codeblock, der eine gewünschte URL abfragt. Anschließend kann der Input über die Variable $__ direkt im nächsten Codeblock verwendet werden. In diesem Fall wird ein ping-Command ausgeführt.

GitHub Action

Eine weitere bemerkenswerte Möglichkeit, die Runme bietet, ist das Ausführen von GitHub Actions direkt aus dem Tool heraus.

Zuerst muss eine Action in unserem Repository angelegt werden. Mein Beispiel demonstriert eine Action, die durch das Ereignis workflow_dispatch ausgelöst wird und es dem Benutzer ermöglicht, spezifische Eingaben über die Benutzeroberfläche zu machen. Die verfügbaren Eingaben beinhalten techHubType, welcher den Typ des TechHub-Beitrags bestimmt, mit Optionen wie techup und decodify, sowie title für den Titel des Beitrags. Der Benutzer kann zudem metaType auswählen, der das Format des Beitrags festlegt, mit Optionen wie markdown und mp3. Eine zusätzliche Option publish erfragt, ob der Beitrag veröffentlicht werden soll, wobei die Wahlmöglichkeiten „yes“ oder „no“ bestehen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
name: b-nova Example
on:
  workflow_dispatch:
    inputs:
      techHubType:
        description: "TechHub Type"
        required: true
        type: choice
        default: "techup"
        options:
          - techup
          - decodify
      title:
        description: "Title"
        required: true
        type: string
      metaType:
        description: "MetaType"
        required: true
        type: choice
        default: markdown
        options:
          - markdown
          - mp3
      publish:
        description: "Publish it?"
        required: true
        type: choice
        default: "yes"
        options:
          - "yes"
          - "no"
jobs:
  createTechHubEntry:
    runs-on: ubuntu-latest
    env:
      REPOSITORY: b-nova-techhub
    steps:
      - name: Print inputs
        run: |
          echo "${{ toJSON(github.event.inputs) }}"          

Sobald die GitHub Action im Repository bereitgestellt wurde, kann der Link dazu kopiert und in einem Codeblock innerhalb von Runme eingefügt werden.

1
https://github.com/b-nova-techhub/runme-example/blob/main/.github/workflows/b-nova-runme.yml

Diese Integration ermöglicht es, die Action direkt auszuführen. Runme bietet dabei eine übersichtliche Darstellung, welche die Daten für die GitHub Action entgegennimmt. Zusätzlich wird angezeigt, dass die Action ausgeführt wird, und es wird ein Link zur laufenden Ausführung bereitgestellt. Dies erleichtert die Verwaltung und das Tracking der GitHub Actions erheblich.

Fazit

Runme bietet eine innovative Lösung, die herkömmliche Readme-Dateien in ausführbare Runbooks und Playbooks transformiert. Dadurch können Entwickler direkt mit dem Readme interagieren und beschriebene Setups interaktiv durchführen. Dies wird ermöglicht, indem Code direkt aus den Dokumenten ausgeführt werden kann, was eine sofortige Verifikation und praktische Anwendung bietet.

Durch die Integration in die Entwicklungsumgebung VS Code, die Kompatibilität mit der CLI und die Nutzungsmöglichkeit als Webserver zeigt Runme eine beachtliche Flexibilität über verschiedene Plattformen hinweg. Allerdings wäre eine erweiterte Integration in andere IDEs wünschenswert, um die Nutzbarkeit weiter zu verbessern.

Da Runme eine Vielzahl von Programmiersprachen unterstützt, kann es nahezu in jedem Projekt angewendet werden, ohne Einschränkungen zu erfahren.

Die Möglichkeit, ganze Code-Blöcke automatisiert auszuführen, interaktive Umgebungsvariablen zu nutzen und GitHub Actions direkt aus Runme zu steuern, vereinfacht die Entwicklungs-Workflows erheblich. Diese Funktionen machen Runme zu einem effektiven Werkzeug, das sowohl die Produktivität steigert als auch die Zusammenarbeit in technischen Teams fördert.

Aus diesen Gründen kann ich Runme auf jeden Fall empfehlen und bin der Meinung, dass es viel öfter eingesetzt werden sollte.

[!TIP]

Die gesamten Beispiele sind auch in unserem Techhub Repository verfügbar

Ricky Elfner

Ricky Elfner – Denker, Überlebenskünstler, Gadget-Sammler. Dabei ist er immer auf der Suche nach neuen Innovationen, sowie Tech News, um immer über aktuelle Themen schreiben zu können.