Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
howto:git:classroom50:moodle_simple [2026/08/25 09:44] – angelegt adminhowto:git:classroom50:moodle_simple [2026/10/01 11:56] (aktuell) – [4. Testen] aprobst
Zeile 1: Zeile 1:
-====== Classroom 50: Noten nach Moodle übertragen ======+====== Classroom50: Moodle sync einrichten ======
  
-Der Übertrag läuft **zentral** aus dem ''classroom50''-Config-Repo und +<WRAP center round tip 60%> 
-**nachts**, nicht bei jedem Push.+Diese Seite erklärt, wie die Noten aus Classroom 50 automatisch ins 
 +Moodle-Notenbuch kommen. Der Übertrag läuft **nachts**, du musst nichts 
 +von Hand starten. 
 +</WRAP>
  
-===== Warum zentral und nachts =====+===== Voraussetzungen =====
  
-Der Moodle-Webservice-Token kann Noten für **beliebige Personen** setzen. In +  * Die Organisation ist in GitHub und Classroom50 erstellt [[.:setup]]. 
-einem Studi-Repo liest ihn ein selbst hinzugefügter Workflow in drei Zeilen aus. +  * Die Klasse ist erstellt [[.:classes]]. 
-Genau so lief es unter GitHub Classroom (''secrets: inherit'' in +  * Die Assignments sind erstellt — inklusive //external assignment// in Moodle [[.:assignments]].
-''classroom.yml'') — diese Exposition endet mit der Migration.+
  
-Technisch geht es unter Classroom 50 auch gar nicht anders: Der zentrale +===== 1. Workflow ins Repo kopieren =====
-Reusable Workflow ''autograde-runner.yaml'' deklariert nur ''outputs:'' und +
-reicht **keine Secrets** an den Bewertungs-Job durch.+
  
-Nachts statt bei jedem Push, weil der direkte Weg einen Token in jedem +''moodle-sync.yaml'' ist **BZZ-eigen** und wird //nicht// von Classroom50 
-Studi-Repo, eine eigene Workflow-Datei je Repo, eine nachgebaute Skip-Logik und +mitgeliefert. Du kopierst sie einmal pro Config-Repo von Hand hinein — die 
-rund 33 % mehr Actions-Minuten gekostet hätte — und ein Nacht-Fallback wäre +Vorlage liegt im Repository [[https://github.com/BZZ-Commons/pygrader50|BZZ-Commons/pygrader50]] 
-trotzdem nötig gewesen.+im Ordner ''classroom50/''.
  
-===== Voraussetzungen auf der Moodle-Seite =====+  - Öffne das Repository ''classroom50'' in deiner GitHub-Organisation, z.B. ''https://github.com/m320-ix25/classroom50''. 
 +  - Kopiere ''moodle-sync.yaml'' nach ''.github/workflows/moodle-sync.yaml''. 
 +  - Committen. Der Workflow erscheint danach unter **Actions → Moodle Sync**.
  
-  - Eine Aktivität vom Typ **External Assignment** (''mod_externalassignment''). +<WRAP center round important 60%> 
-  - Ihr Name ist **exakt der Slug** der Aufgabe, z.B. ''m323-lu01-a02-imperativer-ggt''. +Den Dateinamen so lassen und **keine bestehende Workflow-Datei** dafür 
-  - Der **GitHub-Login steht im Moodle-Profil** der lernenden Person, im Feld //GitHub Classroom// — siehe [[howto:git:github_moodle|]]. +verwenden: Classroom50 überschreibt seine eigenen Workflows bei einem Update. 
-  - Die Person ist im Kurs eingeschrieben.+</WRAP>
  
-Welches Profilfeld gelesen wird, steht in der Plugin-Einstellung +Die Datei gilt für **alle** Klassen im Repo — eine Kopie genügt, auch bei 
-''mod_externalassignment/external_username'' (Vorgabe: Kurzname ''github_user''). +mehreren Klassenordnern.
-Das Plugin sucht ausschliesslich in diesem Feld — der Moodle-Benutzername ist +
-für die Zuordnung **irrelevant**.+
  
-<WRAP center round important 90%> +===== 2. Zugangsdaten hinterlegen =====
-Zwei Fehlermeldungen, die man auseinanderhalten muss:+
  
-^ Meldung ^ Bedeutung ^ +Ebenfalls im Repo ''classroom50'', unter **Settings → Secrets and variables → 
-| ''No Moodle user found with username "X": Update your Moodle profile.'' | Profilfeld leer oder falsch geschrieben | +Actions**:
-| ''No matching assignment found. Contact your teacher.'' | Aktivität fehlt **oder** die Person ist nicht im Kurs — das Plugin löst ''(assignmentname, userid)'' gemeinsam auf |+
  
-Zum Testen deshalb einen echten Studi-Login nehmen — der eigene Lehrer-Account +^ Art ^ Name ^ Wert ^ 
-ist im Kurs meist kein Teilnehmer. +| Secret | ''MOODLE_TOKEN'' | Webservice-Token aus Moodle | 
-</WRAP>+| Variable | ''MOODLE_URL'' | ''https://moodle.bzz.ch'' |
  
-===== Zugangsdaten ===== +Oder im Terminal:
- +
-Im **classroom50-Repo**, nicht in der Studi-Organisation: +
- +
-^ Art ^ Name ^ Wert ^ +
-| Secret | ''MOODLE_TOKEN'' | Webservice-Token | +
-| Variable | ''MOODLE_URL'' | z.B. ''https://moodle.bzz.ch'' | +
-| Variable | ''MOODLE_FUNCTION'' | optional, Vorgabe ''mod_externalassignment_update_grade'' |+
  
 <code bash> <code bash>
Zeile 57: Zeile 48:
 </code> </code>
  
-Für den Token einen **eigenen Webservice-Benutzer** anlegen, der nur diese eine +<WRAP center round important 60%> 
-Funktion darf. Je enger die Rechte, desto kleiner der Schaden bei einem Leck.+Der Token gehört **nur** ins ''classroom50''-Repo, nie in ein Repo der 
 +Lernenden — damit lassen sich Noten für beliebige Personen setzen. 
 +</WRAP>
  
-===== Was übertragen wird =====+===== 3. Zuordnung prüfen =====
  
-Je Kombination aus Aufgabe und Person geht die **neueste** Abgabe raus.+Damit eine Note ankommt, muss die Person in Moodle gefunden werden:
  
-^ Moodle-Feld ^ Quelle ^ +  - Die lernende Person hat ihren **GitHub-Login im Moodle-Profil** eingetragen, im Feld //GitHub Classroom// → [[howto:git:github_moodle|Anleitung]]. 
-| ''assignment_name'' | Slug der Aufgabe aus ''scores.json'' | +  - Die Person ist **im Moodle-Kurs eingeschrieben**. 
-| ''user_name'' | GitHub-Login der besitzenden Person | +  - Die Aktivität //external assignment// heisst **exakt wie der Slug** der Aufgabe, z.B. ''m323-lu01-a02-imperativer-ggt''.
-| ''points'' / ''max'' | Punkte der neuesten Abgabe | +
-| ''externallink'' | URL des GitHub-Releases | +
-| ''feedback'' | Release-Text; davor ein Hinweis bei verspäteter Abgabe, dahinter der Link zur Abgabe |+
  
-===== Zeitplan =====+Der Moodle-Benutzername spielt keine Rolle — gesucht wird nur im Profilfeld.
  
-^ Job ^ Zeit ^ Was er tut ^ +===== 4. Testen =====
-| ''collect-scores'' | nachts | sammelt alle Releases in ''<CLASSROOM>/scores.json'' | +
-| ''moodle-sync'' | ''57 4 * * *'' (04:57) | überträgt daraus nach Moodle |+
  
-40 Minuten Abstand, damit ''collect-scores'' sicher durch ist. +Im Repo ''classroom50'' unter **Actions → Moodle Sync → Run workflow**, 
- +Häkchen bei ''dry_run'' (zeigt nur an, schreibt nichts):
-Ein Zustandsfile ''<CLASSROOM>/moodle-state.json'' merkt sich, was schon +
-übertragen wurde. Übersprungen wird nur, wenn Abgabe **und** Punktzahl +
-identisch sind — eine Nachbewertung derselben Abgabe geht also erneut raus. +
- +
-===== Von Hand auslösen ===== +
- +
-Im classroom50-Repo unter **Actions → Moodle Sync → Run workflow**. +
-Eingaben: Classroom, optional Aufgabe und Login, dazu die Schalter +
-''dry_run'' und ''force''. Bleibt der Classroom leer, laufen **alle** Ordner +
-mit einer ''scores.json''. +
- +
-<code bash> +
-gh workflow run moodle-sync.yaml --repo <ORG>/classroom50 \ +
-  -f classroom=<CLASSROOM> -f dry_run=true +
-</code> +
- +
-Trockenlauf-Ausgabe:+
  
 <code> <code>
Zeile 104: Zeile 75:
 </code> </code>
  
-===== Lokal prüfen, ohne Zugangsdaten =====+Sieht das gut aus, dasselbe ohne ''dry_run'' laufen lassen. Danach ist die 
 +Einrichtung fertig.
  
-<code bash> +<WRAP center round important 60%> 
-gh api repos/<ORG>/classroom50/contents/<CLASSROOM>/scores.json \ +Zum Testen einen **echten Login einer lernenden Person** nehmen. Der eigene 
-   -H 'Accept: application/vnd.github.raw' > scores.json +Lehrer-Account ist im Kurs meist kein Teilnehmer — der Test scheitert dann, 
-GH_TOKEN=$(gh auth token) python -m pygrader50.moodle scores.json --dry-run +obwohl alles richtig eingerichtet ist. 
-</code>+</WRAP> 
 +{{:howto:git:classroom50:classroom50workflowdryrun.png?200|}} 
 + 
 +===== Ab jetzt automatisch ===== 
 + 
 +^ Wann ^ Was ^ 
 +| nachts | Classroom 50 sammelt alle Abgaben ein | 
 +| 04:57 | ''moodle-sync'' trägt sie ins Moodle-Notenbuch ein | 
 + 
 +Übertragen wird pro Person und Aufgabe die **neueste** Abgabe, zusammen mit 
 +Punktzahl, Feedback und Link zur Abgabe. Schon Übertragenes wird übersprungen — 
 +ausser die Punktzahl hat sich geändert. 
 + 
 +Zwischendurch von Hand: **Actions → Moodle Sync → Run workflow**. Der Schalter 
 +''force'' sendet auch schon Übertragenes nochmals. 
 + 
 +===== Wenn etwas nicht klappt =====
  
-Alle Optionen: [[.:cli|CLI-Referenz]].+^ Meldung / Symptom ^ Das hilft ^ 
 +| kein Eintrag **Moodle Sync** unter Actions | Schritt 1 nachholen | 
 +| ''No Moodle user found with username "X"'' | Person trägt ihren GitHub-Login im Moodle-Profil nach | 
 +| ''No matching assignment found'' | Aktivitätsname stimmt nicht **oder** Person ist nicht im Kurs — beides prüfen | 
 +| ''keine XML-Antwort erhalten'' | ''MOODLE_URL'' oder Token falsch | 
 +| Note kommt nicht an, Log sagt „unverändert" | nochmals auslösen, diesmal mit ''force'' | 
 +| Nachtlauf jede Nacht rot, immer dieselbe Person | alter Eintrag in ''scores.json'', siehe [[https://github.com/BZZ-Commons/pygrader50/blob/main/docs/betrieb.md|Betrieb]] |
  
-===== Probleme =====+===== Details =====
  
-^ Meldung / Symptom ^ Ursache ^ +  * [[https://github.com/BZZ-Commons/pygrader50/blob/main/docs/moodle.md|Moodle]] — Hintergründe, alle Felder, Zustandsfile 
-| ''No matching assignment found'' | Aktivitätsname **oder** Kursmitgliedschaft passt nicht | +  * [[https://github.com/BZZ-Commons/pygrader50/blob/main/docs/einrichtung.md|Einrichtung]] — vollständige Einrichtung inkl. Autograder 
-| ''keine XML-Antwort erhalten'' | falsche ''MOODLE_URL'' oder ungültiger Token — Moodle liefert eine Login-Seite | +  * [[https://github.com/BZZ-Commons/pygrader50/blob/main/docs/cli.md|CLI-Referenz]] — Übertrag lokal prüfen, alle Optionen 
-| Note kommt nicht an, Log sagt „unverändert" | Zustandsfile hält sie für erledigt — mit ''force'' erneut auslösen | +  * [[.:hilfe|Hilfe und Dokumentation]] — Übersicht über die ganze Dokumentation
-| Nachtlauf jede Nacht rot, immer dieselbe Person | Karteileichen-Eintrag in ''scores.json'', siehe [[.:lehrpersonen|Betriebsfallen]] |+
  
  • howto/git/classroom50/moodle_simple.1787643875.txt.gz
  • Zuletzt geändert: 2026/08/25 09:44
  • von admin