====== Classroom 50: Ein Klassenzimmer einrichten ====== Von einem laufenden Classroom 50 bis zu Noten in Moodle — für ein **beliebiges** Klassenzimmer. Reihenfolge einhalten; jeder Schritt ist einzeln prüfbar. ^ Platzhalter ^ Bedeutung ^ Beispiel ^ | '''' | GitHub-Organisation der Klasse | ''m320-ix25'' | | '''' | Kurzname des Klassenzimmers = Ordner im Config-Repo | ''m320-ix25'' | | '''' | Slug einer Aufgabe | ''m320-lu04-a4-objektkommunikation'' | | '''' | gepinnte pygrader50-Version | ''v2.0.0'' | '''' und '''' sind oft gleich, müssen es aber nicht sein — der Kurzname steht in ''/classroom.json''. ===== 0. Voraussetzungen ===== Ein ''classroom50''-Config-Repo unter '''' mit laufenden Workflows (''publish-pages'', ''collect-scores''), erzeugt von ''gh teacher classroom add''. gh extension install foundation50/gh-teacher gh auth refresh -h github.com -s admin:org,read:org,repo,workflow gh teacher classroom list Ohne ''admin:org'' bricht **jeder** ''gh teacher''-Aufruf mit einer Scope-Meldung ab. Der Refresh öffnet den Browser und braucht ein interaktives Terminal. ===== 1. Engine veröffentlichen ===== Nur nötig, wenn pygrader50 selbst weiterentwickelt wird — für ein neues Klassenzimmer pinnt man einen bestehenden Tag und überspringt diesen Schritt. git tag v2.0.0 && git push origin main --tags Der Tag ist das, was die Klassenzimmer pinnen. Ohne Tag kein reproduzierbares Semester: ''main'' würde sich unter laufenden Bewertungen verändern. **Prüfen**, dass der Pin installierbar ist — sonst scheitert er erst im ersten Studi-Lauf: python3 -m venv /tmp/pin && /tmp/pin/bin/pip install \ "pygrader50 @ git+https://github.com/BZZ-Commons/pygrader50@" ===== 2. Default-Autograder setzen ===== Pro Klassenzimmer einmal: gh teacher autograder set-default --from bootstrap/autograder.py Das legt ''/autograder.py'' im Config-Repo ab; ''publish-pages'' stellt die Datei auf die Pages-Site, wo ''runner.py'' sie bei jeder Abgabe holt. Die gepinnte Version steht in ''bootstrap/autograder.py'': VERSION = 'v2.0.0' Ein Upgrade heisst später: Tag hochziehen, Zeile ändern, ''set-default'' erneut ausführen — pro Klassenzimmer, das mitziehen soll. Klassen können bewusst auf unterschiedlichen Versionen bleiben. **Vorher prüfen**, was überschrieben wird: gh teacher autograder show gh teacher autograder list **Nachher prüfen**, dass Pages die Datei ausliefert: curl -sS -o /dev/null -w '%{http_code}\n' \ https://.github.io/classroom50//autograder.py Das Klassen-Segment im Pfad ist Pflicht. ''…/classroom50/autograder.py'' **ohne** ''/'' liefert 404 — eine beliebte Fehlspur beim Prüfen. Der Deploy braucht nach dem Push rund 30 Sekunden. Dann in einem Test-Repo etwas pushen: Das Release muss eine echte Punktzahl zeigen (z.B. ''0/7'') statt ''0/0''. Im Job-Log steht, welche Konfigurationsdateien gefunden wurden. ===== 3. Aufgaben-Konfiguration ablegen ===== Die drei Dateien können bleiben, wo sie sind (''.github/autograding/'' im Studi-Repo) — dann ist nichts zu tun. Manipulationssicher wird es erst im Config-Repo, weil Lernende ihr eigenes ''.github/'' bearbeiten können. Aufbau, Vorrangregeln und Beispiele: [[.:bewertung|Wie bewertet wird]]. classroom50/ └── / └── autograders/ └── / ├── unittests.json ├── lint.json └── pylintrc **Prüfen:** Punkte in der Bundle-''unittests.json'' ändern, pushen, neu bewerten lassen — die neue Maximalpunktzahl muss im Release stehen. ===== 4. Template-Repos migrieren ===== Nur bei Klassen, die von GitHub Classroom kommen — vollständig beschrieben unter [[.:migration|Migration von GitHub Classroom]]. Kurzfassung: scripts/remove-legacy-classroom-yml.sh # Trockenlauf scripts/remove-legacy-classroom-yml.sh --apply # löschen Danach den alten Moodle-Token **löschen und rotieren**. ===== 5. Moodle-Übertrag einrichten ===== ==== 5.1 Workflow einbauen ==== cp classroom50/moodle-sync.yaml /.github/workflows/moodle-sync.yaml Eigener Dateiname, keine bestehende Datei anfassen: ''gh teacher'' überschreibt die mitgelieferten Skeleton-Workflows bei einem Refresh. Die Datei ist klassenzimmer-neutral. Bleibt die Eingabe ''classroom'' leer, wird jeder Ordner mit einer ''scores.json'' übertragen — ein Config-Repo mit mehreren Klassen braucht keine zweite Kopie. Anzupassen ist nur der gepinnte Tag, falls er von ''bootstrap/autograder.py'' abweicht. ==== 5.2 Zugangsdaten, Moodle-Seite, erster Lauf ==== Siehe [[.:moodle|Noten nach Moodle übertragen]]. Kurz: - Secret ''MOODLE_TOKEN'' und Variable ''MOODLE_URL'' im **classroom50-Repo** setzen. - In Moodle je Aufgabe eine Aktivität //External Assignment// mit dem Slug als Namen. - **Actions → Moodle Sync → Run workflow** mit ''dry_run'', Ausgabe prüfen. - Dasselbe ohne ''dry_run''. Danach liegt ''/moodle-state.json'' im Repo. ===== 6. Betriebsfallen ===== Vier Verhaltensweisen der Classroom-50-Seite, die man einmal wissen muss — ''scores.json'' wird nie aufgeräumt, eingesammelt wird nach Teams statt nach Roster, das Roster heisst ''roster.csv'', und der Service-Token braucht Administration-Rechte. Ausgeführt unter [[.:lehrpersonen|Klassenzimmer und Aufgaben verwalten]]. ===== Verantwortlichkeiten ===== ^ Was ^ Wo ^ Warum dort ^ | Bewertungs-Engine, Moodle-Übertrag | ''BZZ-Commons/pygrader50'' | eine Quelle, versioniert, für alle Klassenzimmer | | Default-Autograder, Aufgaben-Bundles, Moodle-Token | ''/classroom50'' | von der Lehrperson kontrolliert, für Lernende nicht schreibbar | | Startcode, Tests, Musterlösung | Template-Repo | gehört zur Aufgabe | | Abgabe | Studi-Repo | gehört den Lernenden |