Engineering-Leitfaden

DocC-Dokumentation als CI-Prüfung auf dem Cloud-Mac

DocC-Dokumentation als CI-Prüfung auf dem Cloud-Mac

Nachdem ein Team eine öffentliche API umbenannt hat, lässt sich das lokale Projekt häufig weiterhin kompilieren, obwohl alte Symbolverweise in der Dokumentation bereits ungültig sind. Das Problem fällt meist erst bei einer manuellen Prüfung der Dokumentation kurz vor der Veröffentlichung auf. Zuverlässiger ist es, bei jeder Merge-Prüfung auf dem Cloud-Mac einen DocC-Build auszuführen. Nicht auflösbare Verweise, doppelte Themen und Compilerwarnungen führen dann direkt zu einem fehlgeschlagenen Prüflauf, während die statische Website und die Diagnoseprotokolle als Artefakte erhalten bleiben.

Grenzen der Prüfung zuerst festlegen

Eine DocC-Prüfung sollte nicht sämtliche Dokumentationskontrollen übernehmen. DocC eignet sich besonders zur Validierung von Swift-Symbolen, Artikelverzeichnissen, Themenhierarchien und internen Verweisen. Die Erreichbarkeit externer URLs und die Einheitlichkeit des Schreibstils sollten dagegen in separaten Jobs geprüft werden. Andernfalls kann bereits ein vorübergehender Netzwerk-Timeout das Zusammenführen von Code blockieren.

Zunächst sollten drei Ergebniskategorien definiert werden:

Ergebnis Behandlung Typischer Fall
Fehler Sofort blockieren Nicht auflösbares Symbol, ungültige Verzeichnisstruktur
Warnung Auf dem Hauptbranch blockieren Ungültiger Themenverweis, doppelte Kennung
Hinweis Protokollieren, aber zulassen Zu kurze Zusammenfassung, unvollständiges Beispiel

Das Ziel einer Dokumentationsprüfung besteht nicht darin, keinerlei Hinweise mehr zu erzeugen. Entscheidend ist, dass dieselbe Eingabe in einer festgelegten Umgebung stets zum gleichen Ergebnis führt. Die Regeln müssen sich auf Entwicklungsrechnern und CI-Knoten mit demselben Befehl reproduzieren lassen.

Auch für die Verzeichnisstruktur sollte es nur eine maßgebliche Quelle geben. Die Dokumentation eines Moduls gehört in das .docc-Verzeichnis des jeweiligen Targets, modulübergreifende Anleitungen in das Dokumentations-Target, das die Inhalte zusammenführt. Derselbe Artikel sollte nicht in mehrere Catalogs kopiert werden, da nach einer Überarbeitung sonst leicht nur eine der Kopien aktualisiert wird.

Xcode und Build-Eingaben fest vorgeben

Auf Remote-Knoten entsteht Drift am häufigsten durch den standardmäßig ausgewählten Xcode-Pfad. Zu Beginn des Jobs sollte deshalb die Version ausgegeben und das Entwicklerverzeichnis ausdrücklich geprüft werden. Verwaltet das Team mehrere Versionen, kann der vollständige Pfad über eine CI-Variable übergeben werden, statt sich auf die Auswahl einer vorherigen interaktiven Sitzung zu verlassen.

set -euo pipefail

: "${DEVELOPER_DIR:?set DEVELOPER_DIR}"
: "${SCHEME:?set SCHEME}"

test -x "$DEVELOPER_DIR/usr/bin/xcodebuild"
xcodebuild -version
swift --version
git status --short

Vor dem Build muss außerdem der Zustand des Repositorys geprüft werden. Die CI sollte mit einem sauberen Checkout beginnen. Dateien zur Auflösung von Abhängigkeiten müssen versioniert sein, und die für die Dokumentation benötigten Ressourcen dürfen nicht von lokalen Kopien im Entwicklerverzeichnis abhängen. Erzeugt ein Skript Markdown, sollte die Ausgabe zunächst in einem temporären Verzeichnis erstellt und anschließend mit dem erwarteten Ergebnis verglichen werden. Bei nicht committeten Abweichungen muss der Job fehlschlagen.

Impliziten Workspace-Zustand vermeiden

Langfristig bestehende DerivedData-Verzeichnisse sollten nicht wiederverwendet werden. Alte Symbolgraphen können dazu führen, dass gelöschte Typen weiterhin in der Dokumentation erscheinen, und fehlende Ressourcen verdecken. Jeder Job sollte ein eigenes Verzeichnis verwenden und nach Abschluss nur die benötigten Diagnosen und DocC-Artefakte archivieren.

Einen reproduzierbaren docbuild ausführen

Das folgende Skript erstellt für jeden Job ein isoliertes Verzeichnis, behandelt DocC-Warnungen als Fehler und bewahrt das vollständige Protokoll auf. generic/platform=iOS ist nicht von einem bestimmten gestarteten Simulator abhängig und eignet sich daher für Prüfungen, bei denen lediglich Symbolgraphen und Dokumentation kompiliert werden müssen.

set -euo pipefail

ROOT="$PWD/.build/docs"
DERIVED="$ROOT/DerivedData"
LOG="$ROOT/docc-build.log"

rm -rf "$ROOT"
mkdir -p "$ROOT"

set -o pipefail
xcodebuild docbuild \
  -scheme "$SCHEME" \
  -destination "generic/platform=iOS" \
  -derivedDataPath "$DERIVED" \
  OTHER_DOCC_FLAGS="--warnings-as-errors" \
  2>&1 | tee "$LOG"

ARCHIVE="$(find "$DERIVED/Build/Products" -name '*.doccarchive' -print -quit)"
test -n "$ARCHIVE"
printf '%s
' "$ARCHIVE" > "$ROOT/archive-path.txt"

Enthält das Scheme zugleich Targets, für die keine Dokumentation erzeugt werden muss, sollte der Umfang der Dokumentationskompilierung ausdrücklich in den Projekteinstellungen festgelegt werden. Warnungen lediglich aus dem Protokoll herauszufiltern, würde auch echte Regressionen verschlucken. Bei der erstmaligen Aktivierung von --warnings-as-errors empfiehlt es sich, den Build zunächst als nicht blockierenden Job auszuführen. Nachdem die bestehenden Probleme behoben wurden, kann er zur verpflichtenden Merge-Prüfung werden.

Statische Website exportieren und Artefakte prüfen

Ein .doccarchive eignet sich für die weitere Verarbeitung. Prüfer benötigen jedoch meist statische Dateien, die sich direkt öffnen lassen. Nachdem das Archive gefunden wurde, wird die Website mit dem in DocC enthaltenen Konvertierungsbefehl erzeugt:

set -euo pipefail

ARCHIVE="$(cat .build/docs/archive-path.txt)"
OUTPUT="$PWD/.build/docs/site"

xcrun docc process-archive transform-for-static-hosting \
  "$ARCHIVE" \
  --output-path "$OUTPUT" \
  --hosting-base-path docs

test -s "$OUTPUT/index.html"
find "$OUTPUT" -type f | sort > .build/docs/site-files.txt

--hosting-base-path muss mit dem endgültigen Unterpfad der Bereitstellung übereinstimmen. Wird die Website tatsächlich im Root-Pfad veröffentlicht, darf docs nicht unverändert übernommen werden. Bei einem abweichenden Pfad lässt sich die Startseite lokal möglicherweise problemlos öffnen, während Skripte und Stylesheets nach der Bereitstellung mit Fehlern antworten.

Archiviert werden sollten mindestens das Build-Protokoll, der Archive-Pfad, die statische Website und die Dateiliste. Das Protokoll dient zur Analyse konkreter Diagnosen, während die Dateiliste unerwartete Löschungen in großem Umfang sichtbar macht. Für die statische Website kann eine kürzere Aufbewahrungsfrist gelten; Protokolle fehlgeschlagener Jobs sollten dagegen erhalten bleiben, bis das Problem geschlossen ist.

Die Prüfung externer Links sollte das erzeugte HTML einlesen, ausschließlich zulässige https-Adressen prüfen und die Parallelität begrenzen. Bei Timeouts und serverseitiger Ratenbegrenzung sind wenige Wiederholungsversuche sinnvoll; erst dauerhaft fehlschlagende Abrufe sollten blockieren. Links mit temporären Token, Abfrageparametern oder internen Adressen gehören weder in öffentliche Dokumentation noch in die Prüfprotokolle.

Häufige Fehler beheben und eine Abnahmecheckliste erstellen

Wenn ein Symbol vorhanden ist, von DocC aber nicht gefunden wird, gibt es dafür meist drei Ursachen: Das Symbol gehört nicht zum aktuellen Scheme, seine Zugriffsebene liegt außerhalb des Dokumentationsumfangs oder der Link verwendet eine veraltete vollständige Signatur. Zuerst sollte das Target geprüft und anschließend im erzeugten Protokoll nach vorgeschlagenen Symbolen gesucht werden, statt Schreibweisen wiederholt auf Verdacht zu ändern.

Bei ungültigen Artikelverweisen müssen Dateiname, aus dem Titel erzeugte Kennung und relative Hierarchie im Verzeichnis geprüft werden. Können Ressourcen nicht geladen werden, sind Groß- und Kleinschreibung sowie die Target-Mitgliedschaft zu kontrollieren. Das Dateisystem in der Cloud folgt exakt den tatsächlichen Pfaden. Schreibweisen, die aufgrund abweichender Groß- und Kleinschreibung nur in einigen lokalen Umgebungen zufällig funktionieren, dürfen nicht beibehalten werden.

Die endgültige Prüfung sollte folgende Fragen beantworten können:

  • Wurden die Xcode- und Swift-Versionen protokolliert?
  • Wurde mit einem sauberen Workspace begonnen?
  • Werden DocC-Warnungen wie vereinbart behandelt?
  • Wurde das erwartete Archive gefunden und ausschließlich dieses verarbeitet?
  • Ist der Einstiegspunkt der statischen Website vorhanden?
  • Wurden Build-Protokoll und Dateiliste archiviert?
  • Werden Fehler bei externen Links getrennt von DocC-Kompilierungsfehlern gemeldet?

Werden alle diese Prüfungen durch dasselbe Skript ausgeführt, bieten Dokumentationsänderungen einen ebenso reproduzierbaren Fehlerzustand wie Codeänderungen. Verantwortliche können Verweise anhand des Protokolls untersuchen, die Struktur mithilfe der statischen Artefakte prüfen und Verhaltensunterschiede nach einem Xcode-Upgrade eindeutig vergleichen.

Häufig gestellte Fragen

Prüft ein erfolgreicher DocC-Build auch externe Weblinks?

Nein. DocC prüft vor allem Symbol- und Themenverweise innerhalb des Dokumentationsbestands. Externe Links benötigen einen getrennten Job mit Zeitlimit, Wiederholungen und einer kontrollierten Ausnahmeliste.

Warum sollte der Xcode-Pfad im CI-Job festgelegt werden?

Xcode-Versionen enthalten unterschiedliche Compiler- und DocC-Versionen. Eine explizite DEVELOPER_DIR-Prüfung verhindert, dass ein geändertes Standard-Xcode unbemerkte Unterschiede erzeugt.

Dedizierter physischer Knoten

Cloud-Mac-Workflows mit OpsVM bereitstellen

Wählen Sie aus drei Apple-Silicon-Konfigurationen und sechs verfügbaren Knoten. Maßgeblich ist der in der Konsole in Echtzeit angezeigte Status.

Konfiguration auswählen und bestellen