Dieses Dokument erklärt, wie du mit GitHub Actions (GHA) Continuous-Integration-(CI-)Workflows für einen Exercism-Sprach-Track einrichtest. Es bietet Best Practices und Beispiele, mit denen du deine eigenen schnellen, zuverlässigen und robusten CI-Workflows erstellen kannst. Die GHA-Workflows in diesem Ordner lassen sich an jede CI anpassen, weil die Grundstruktur gleich bleibt.
Es wird:
Eine Beispielumsetzung dieser Workflow-Dateien findest du in exercism/javascript.
Der Rest des Dokuments erklärt, wie die Workflows funktionieren. Wenn du es eilig hast und nur von Travis oder Circle zu GHA wechseln möchtest, ohne die PR-Skripte zu optimieren, schau dir unseren ~10-Minuten-Leitfaden zur Migration von Travis an.
Die empfohlenen Aktionen, mit denen du prüfst, ob der Inhalt deines Repositorys integer ist, sind folgende:
configlet-Linting, um config.json zu prüfenv3 erfordert neue Dateien; das könnte zu configlet wandern)Es kann auch trackspezifische Aktionen geben. Zum Beispiel:
Und vielleicht möchtest du weitere Quality-of-Life-Prüfungen, wie zum Beispiel:
Überlege bei jeder Aktion, wie oft sie laufen sollte.
configlet-Linting ist so wichtig (denn ein Track kann kaputtgehen, wenn config.json kaputtgeht), dass es wahrscheinlich immer laufen sollte, aber es muss nur einmal pro Commit laufen.Es kann sehr hilfreich sein, die Aktionen, die laufen sollen, auch lokal verfügbar zu machen. Das bedeutet, dass die Skripte, die die eigentliche Arbeit erledigen, auch manuell ausführbar sind. Um das zu erreichen, bette die Aktion nicht direkt in die Workflow-Dateien ein, sondern erstelle ein eigenständiges Skript. Zum Beispiel lässt sich die Prüfung auf Stubs komplett im Workflow-File mit Bash erledigen, aber die Empfehlung hier ist, stattdessen ein neues ausführbares Skript scripts/ci-check zu erstellen.
„Aber der Befehl ist doch sehr kurz, z. B.
eslint . --ext ts --ext tsx“.Wenn dieser Befehl aktualisiert werden muss, muss er jetzt an allen Stellen aktualisiert werden: in der Dokumentation, den Workflow-Dateien und in den Köpfen der Maintainer. Das alles löst du, wenn du ihn in ein Skript auslagerst. Eine Workflow-Datei zu lesen, kann außerdem sehr einschüchternd sein.
Die Skripte scripts/pr und scripts/pr-check (siehe Vorlagen) werden mit mehreren Argumenten aufgerufen, eines für jede Datei, die in diesem PR geändert oder hinzugefügt wurde. Wenn zum Beispiel two-fer aktualisiert wurde, sieht ein Aufruf etwa so aus:
scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext
Es wird empfohlen, alle Aktionen auf die geänderte Übung und nicht auf die geänderte Datei anzuwenden. Denn eine geänderte Datei löst wahrscheinlich Änderungen für die gesamte Übung aus (denk an: Konfiguration, Pakete).
Noch nicht bereit? / Zu komplex?
Bevor du diese Optimierung umsetzt, kannst du sie getrost ignorieren! Der Migrationsleitfaden deutet an, sie zu einem späteren Zeitpunkt hinzuzufügen. Wenn die Eingabeargumente ignoriert werden, laufen alle Prüfungen für alle Übungen. Das ist völlig in Ordnung. Es dauert nur länger.
Wenn der Track eine einzelne „Top-Level“-Abhängigkeitsdatei und/oder andere Konfigurationsdateien hat, füge einen Schritt zur Integritätsprüfung hinzu (der neben einem scripts/sync oder bin/sync existiert, das alle Konfigurationsdateien in alle Übungen kopiert), der sicherstellt, dass die Top-Level-/Basisdateien mit der in die Übungsverzeichnisse kopierten Datei identisch sind. Jetzt können Abhängigkeiten aktualisiert und im ganzen Repository synchronisiert werden, und wir können sicherstellen, dass alle Übungen dieselbe Konfiguration haben.
Ein üblicher Weg dafür ist eine Prüfsumme. Ubuntu (und diverse andere Linux-Distributionen) bringt ein Tool namens sha1sum mit, aber welche Methode auch immer du verwendest, um die Konfigurationsdatei zu hashen oder auf einen Prüfsummenwert zu reduzieren (md5, sha1, crc32), würde funktionieren:
$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md
Wenn der Track zusätzliche Workflows verwendet, die Zugriff auf das GitHub-Token oder andere Secrets benötigen, gehört es zu den Best Practices, alle im Workflow verwendeten Aktionen an einen bestimmten Commit zu binden. Einzelheiten findest du in GitHubs Leitfaden zur Sicherheitshärtung.
Zum Beispiel:
- uses: julia-actions/setup-julia@v1
+ uses: julia-actions/setup-julia@d26d1111976eae5f00db04f0515ab744ec9cd79e # 1.3.1
Wenn das Tooling Lockfiles für die Abhängigkeitsverwaltung hat, solltest du sie ins Repository einchecken und innerhalb der Workflow-Dateien ein „frozen lockfile“ verwenden. Zum Beispiel: npm ci, yarn install --frozen-lockfile und bundle install --frozen. Das stellt sicher, dass die Lockfile beim Ändern von Abhängigkeiten aktuell ist, und verhindert, dass bösartige Pakete eindringen.
In diesem Verzeichnis gibt es mindestens die folgenden Vorlagen:
configlet.yml: Dieser Workflow holt die neueste configlet-Binary und lintet dieses Repository. Läuft bei jedem Commit. Bei PRs läuft er auf dem tatsächlichen Commit und einem „After-Merge“-Tree.ci.yml: Dieser Workflow läuft nur auf dem Main-Branch, einmal bei jedem Commit.
pr.ci.yml: Dieser Workflow läuft nur bei PRs, einmal bei jedem Commit.
Die Nicht-PR-Workflows können auch über workflow_dispatch ausgelöst werden.
In jeder Datei steht oben, welche „Skripte“ verfügbar sein sollten. Wenn du sie als Binaries haben möchtest, ersetze scripts/xxx durch bin/xxx. Manches Tooling erfordert, dass Binaries in einem bin-Ordner liegen.
scripts/ci: ein Skript, das alle Übungen bauen und mit den Beispiellösungen gegen die Tests testen solltescripts/ci-check: ein Skript, das alle Übungen linten und optional auf Stubs, Konfigurationsintegrität und mehr prüfen solltescripts/pr: wie scripts/ci, aber es sollte nur Übungen ausführen, die aus den als Eingabe angegebenen Pfaden aufgelöst wurdenscripts/pr-check: wie scripts/ci-check, aber es sollte nur für Dateien oder Übungen ausgeführt werden, die aus den als Eingabe angegebenen Pfaden aufgelöst wurdenWenn du auf Probleme stößt oder möchtest, dass jemand deine Workflows prüft, tagge bitte das Team @exercism/github-actions.
Eine Top-Level-Datei geändert, die einen CI-Lauf für alle Übungen auslösen sollte
Zum Zeitpunkt des Schreibens erlaubt
pr.ci.ymlnur „Extension“-Tests. Idealerweise wird das so aktualisiert, dass es immer ausgelöst wird, wenn bestimmte Dateien geändert werden (zum Beispiel die Binary zum Ausführen der Tests). Diese Änderungen sind jedoch oft selten und werden von Maintainern vorgenommen, sodass die Tatsache, dassci.ymlauf main immer für alles läuft, wahrscheinlich sicher genug ist.
Eine scripts/xxx-Datei unter Windows erstellt und jetzt funktioniert sie unter {anderem OS} nicht
Standardmäßig haben unter Windows erstellte Dateien keine Metadaten im git-index eingebettet, die ihre Ausführbarkeit betreffen, weil das Berechtigungsmodell unter Windows anders ist. Git verwendet standardmäßig die git-index-Metadaten, um zu entscheiden, ob die Datei auf POSIX-basierten Systemen ausführbar sein sollte, und macht die Datei
scripts/xxxdadurch NICHT ausführbar.
git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"