Eine Continuous Integration (CI) für deinen Track einzurichten ist sehr wichtig, denn sie hilft, Fehler aufzuspüren.
Exercism-Repos (einschließlich Track-Repos) verwenden GitHub Actions, um ihre CI auszuführen. GitHub Actions basieren auf Workflows, die Skripte definieren, die automatisch ausgeführt werden, sobald ein bestimmtes Ereignis eintritt (z. B. wenn ein Commit gepusht wird). Weitere Informationen zu GitHub-Actions-Workflows findest du in der Workflow-Dokumentation.
Tracks werden mit einer Reihe vorinstallierter Workflows ausgeliefert, von denen du die meisten nicht ändern solltest (sie heißen gemeinsame Workflows).
Einen Workflow solltest du aber ändern, nämlich den Workflow test.yml.
Ziel des Workflows test.yml ist es, zu überprüfen, dass die Übungen des Tracks in ordentlichem Zustand sind.
Der Workflow ist so eingerichtet, dass er automatisch läuft (in der GitHub-Actions-Terminologie: ausgelöst wird), wenn ein Push in den Branch main oder in den Branch eines Pull Requests erfolgt.
Der Workflow selbst sollte nicht viel tun, außer:
verify-exercises ausführen (bereits implementiert)Wie erwähnt werden die Übungen über ein Skript verifiziert, nämlich das Skript bin/verify-exercises (Bash).
Dieses Skript ist fast fertig und macht Folgendes:
unskip_tests auf, in der du Tests in deinen Testdateien wieder aktivieren kannst (optional)run_tests auf, in der du die Tests ausführen solltest (erforderlich)Die Funktionen run_tests und unskip_tests sind die einzigen Dinge, die du implementieren musst.
Wenn dein Track das Überspringen von Tests unterstützt, müssen wir sicherstellen, dass beim Verifizieren der Beispiel-/Exemplarlösung einer Übung keine Tests übersprungen werden. Im Allgemeinen gibt es zwei Arten, wie Tracks das „Wiederaktivieren“ von Tests unterstützen:
test.skip in test ändern.SKIP_TESTS=false setzen.Wenn das Überspringen von Tests dateibasiert ist (die erste Option oben), passe die Funktion unskip_tests an, um die Testdateien zu ändern (der vorhandene Code kümmert sich bereits um die Schleife über die Testdateien).
Die Funktion unskip_test läuft auf einer Kopie eines Übungsverzeichnisses, du kannst die Dateien also nach Belieben ändern.
Die bin/verify-exercises file des Arturo-Tracks verwendet sed, um die Tests in den Testdateien wieder zu aktivieren:
unskip_tests() {
jq -r '.files.test[]' .meta/config.json | while read -r test_file; do
sed -i 's/test.skip/test/g' "${test_file}"
done
}
Wenn das Wiederaktivieren von Tests das Setzen einer Umgebungsvariablen erfordert, stelle sicher, dass sie in der Funktion run_tests gesetzt wird.
Die Funktion run_tests ist dafür zuständig, die Tests einer Übung auszuführen.
Wenn die Funktion aufgerufen wird, wurden die Beispiel-/Exemplardateien bereits in die (Stub-)Lösungsdateien kopiert, du musst also nur den richtigen Befehl aufrufen, um die Tests auszuführen.
Die Funktion muss als Exit-Code Null zurückgeben, wenn alle Tests bestehen, andernfalls einen Exit-Code ungleich Null.
Die Funktion run_tests läuft auf einer Kopie eines Übungsverzeichnisses, du kannst die Dateien also nach Belieben ändern.
Die Standardoption für das Skript verify-exercises ist, das Tooling der Sprache (SDK/Binary/usw.) zu verwenden, was die meisten Tracks auch tun.
Jeder Track hat seine eigene Art, die Tests auszuführen, aber meistens ist es einfach ein einzelner Befehl.
Die bin/verify-exercises file des Arturo-Tracks ändert die Funktion run_tests, um einfach den Befehl arturo mit der Testdatei aufzurufen:
run_tests() {
arturo tester.art
}
Die zweite Option ist, die Übungen zu verifizieren, indem du den Test-Runner des Tracks ausführst. Das setzt natürlich voraus, dass der Track einen funktionierenden Test-Runner hat.
Wenn dein Track noch keinen Test-Runner hat, kannst du entweder:
Am Standard-Skript bin/verify-exercises müssen folgende Änderungen vorgenommen werden:
docker verfügbar istdocker run das Test-Runner-Docker-Image für jede Übung ausführenjq überprüfen, dass die vom Docker-Container zurückgegebene Datei results.json anzeigt, dass alle Tests bestanden wurdenunskip_test und den Aufruf dieser Funktion entfernenDer Hauptvorteil dieses Ansatzes ist, dass er am besten nachbildet, wie die Tests in Produktion (auf der Website) ausgeführt werden. Damit ist es weniger wahrscheinlich, dass in Produktion Dinge fehlschlagen, die in der CI bestanden haben. Der Nachteil dieses Ansatzes ist, dass er meist langsamer ist, weil das Docker-Image gepullt werden muss und Docker Overhead mit sich bringt.
Die bin/verify-exercises file des Unison-Tracks fügt die Prüfung hinzu, dass der Befehl docker installiert ist:
required_tool docker
Dann pullt er das Test-Runner-Image des Tracks:
docker pull exercism/unison-test-runner
Anschließend ändert er die Funktion run_tests, um mit docker run den Test-Runner für die aktuelle Übung (die sich im Arbeitsverzeichnis befindet) auszuführen, gefolgt von einem jq-Befehl, um den richtigen Status zu prüfen:
run_tests() {
local slug
slug="${1}"
docker run \
--rm \
--network none \
--mount type=bind,src="${PWD}",dst=/solution \
--mount type=bind,src="${PWD}",dst=/output \
--tmpfs /tmp:rw \
exercism/unison-test-runner "${slug}" "/solution" "/output"
jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
}
Schließlich müssen wir den Aufruf des Befehls run_tests anpassen, da er jetzt den Slug benötigt:
run_tests "${slug}"
Jetzt, wo das Skript verify-exercises fertig ist, ist es Zeit, den Workflow test.yml abzuschließen.
Wie das geht, hängt davon ab, welche Option für die Implementierung des Skripts verify-exercises gewählt wurde.
Wenn das Skript verify-exercises direkt das Tooling der Sprache verwendet, muss der Test-Workflow Folgendes installieren:
Sobald das erledigt ist, sollte das Skript verify-exercises wie erwartet funktionieren, und du hast die CI erfolgreich eingerichtet!
Ein Beispiel findest du im Test-Workflow test.yml des Arturo-Tracks:
name: Test
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libgtk-3-dev libwebkit2gtk-4.0-dev libmpfr-dev
- name: Install Arturo
run: bin/install-arturo
env:
GH_TOKEN: ${{ github.token }}
- name: Verify all exercises
run: bin/verify-exercises
Die zweite Option ist, die Übungen zu verifizieren, indem du den Test-Runner des Tracks ausführst. Diese Option erfordert zwei Dinge:
verify-exercises verwendet das Test-Runner-Docker-Image, um die Tests einer Übung auszuführenWenn dein Track noch keinen Test-Runner hat, kannst du entweder:
Dieser Ansatz hat ein paar Vorteile:
Der größte Nachteil ist, dass er wahrscheinlich langsamer ist, weil das Docker-Image gepullt werden muss und Docker Overhead mit sich bringt.
Es gibt ein paar Möglichkeiten, das Test-Runner-Docker-Image zu pullen:
verify-exercises herunterladen.
Diesen Ansatz wählt der Unison-Track.Welchen Ansatz solltest du also wählen?
Wir empfehlen, mindestens Option 1 zu implementieren, damit das Skript verify-exercises eigenständig ist.
Wenn dein Image besonders groß ist, kann es sinnvoll sein, auch Option 3 zu implementieren, die das gebaute Docker-Image im Cache von GitHub Actions ablegt.
Nachfolgende Läufe können das Docker-Image dann einfach aus dem Cache lesen, statt es herunterzuladen, was besser für die Performance sein kann (bitte messen, um sicherzugehen).
Eine dritte, alternative Option ist eine Mischung aus den beiden vorherigen Optionen.
Hier verwenden wir ebenfalls das Test-Runner-Docker-Image, nur führen wir diesmal das Skript verify-exercises innerhalb dieses Docker-Images aus.
Um diese Option zu ermöglichen, müssen wir den Container des Workflows auf den Test-Runner setzen:
container:
image: exercism/vimscript-test-runner
Dann können wir die Schritte zur Installation von Abhängigkeiten und Tooling überspringen (die wurden bereits im Test-Runner-Docker-Image installiert) und mit dem Ausführen des Skripts bin/verify-exercises fortfahren.
Der Test-Workflow test.yml des vimscript-Tracks verwendet diese Option:
name: Verify Exercises
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-24.04
container:
image: exercism/vimscript-test-runner
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Verify all exercises
run: bin/verify-exercises