Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8c88877
Add automatic student repo creation (/join), replacing GitHub Classroom
claude Aug 19, 2026
c85028a
Address code review feedback on PR #49
claude Sep 4, 2026
d92887e
Перенести UI страницы /join из PR #48 в кодовую базу PR #49
claude Sep 4, 2026
9e829c4
frontend: use recursive glob for node --test, sync lockfile
claude Sep 4, 2026
1c0e795
frontend: перевести кнопку «Назад» на странице /join
markpolyak Sep 4, 2026
5475167
Support fork-based student repo creation as alternative to template (…
claude Sep 4, 2026
7cd610a
fork-режим: чинить форк и когда репозиторий уже существует
markpolyak Sep 4, 2026
2af6a19
Propagate template updates to student repos via fork PRs (#52)
claude Sep 4, 2026
fbb4742
Default the propagate-template-update body so a bodyless POST works
claude Sep 4, 2026
e14888f
propagate: не оставлять работу висеть в running и не считать шаблон н…
markpolyak Sep 4, 2026
4178a4b
propagate: открывать PR из служебной ветки в самом форке
markpolyak Sep 4, 2026
75517f8
Update operating-systems-2026.yaml
markpolyak Sep 4, 2026
4e9e8ce
Rename ml-2025_logo.png to itmo_ml_logo.png
markpolyak Sep 4, 2026
3e2cad6
Update index.yaml
markpolyak Sep 4, 2026
020f826
Add files via upload
markpolyak Sep 5, 2026
a059fd2
Резолвить лабу по идентификатору, а не по первому числу в строке
markpolyak Sep 5, 2026
bfcff70
Удалить неиспользуемый normalize_lab_id
markpolyak Sep 5, 2026
6b9007d
Выбор репозиториев в предпросмотре рассылки обновления
markpolyak Sep 5, 2026
02383d0
Закрепить шапку таблицы в предпросмотре рассылки
markpolyak Sep 5, 2026
bf20655
Запрещать форк репозитория студента при провижининге
markpolyak Sep 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,24 @@ SECRET_KEY=your_random_secret_key_here
# Google Sheets credentials file path (inside container)
CREDENTIALS_FILE=/app/google-credentials/credentials.json

# --- Автоматическое создание репозитория студента (/join/...) ---
# См. docs/REPO_GENERATION_PLAN.md. Не обязательны, если фича не используется -
# без них /join/* эндпоинты отвечают понятной ошибкой 503 вместо падения приложения.

# OAuth App регистрируется ПРЕПОДАВАТЕЛЕМ на github.com:
# Settings -> Developer settings -> OAuth Apps -> New OAuth App
# Authorization callback URL должен быть <ваш-хост>/join/callback
GITHUB_OAUTH_CLIENT_ID=
GITHUB_OAUTH_CLIENT_SECRET=

# Публичный URL frontend'а - куда перенаправляется браузер студента
# после прохождения OAuth (страница /join/:courseId/:labId)
FRONTEND_URL=http://localhost:8080

# Необязательно: явно задать Authorization callback URL, если backend работает
# за reverse-proxy и request.base_url не совпадает с адресом, зарегистрированным
# в OAuth App. По умолчанию вычисляется как "<адрес запроса>/join/callback"
# GITHUB_OAUTH_CALLBACK_URL=https://your-host/join/callback

# Optional: Branch to deploy (if using variable-based docker-compose.yaml)
# BRANCH=main
22 changes: 22 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ ADMIN_PASSWORD=... # Admin panel password
SECRET_KEY=... # Cookie signing key
LOG_DIR=/app/logs # Log directory (optional)
LOG_LEVEL=INFO # Logging level (optional)

# Optional: only needed for /join/... (student repo auto-creation, see docs/REPO_GENERATION_PLAN.md)
GITHUB_OAUTH_CLIENT_ID=...
GITHUB_OAUTH_CLIENT_SECRET=...
FRONTEND_URL=http://localhost:8080
```

## Key Conventions
Expand Down Expand Up @@ -96,6 +101,23 @@ labs:
- If score patterns configured but not found in logs → error
- If score patterns not configured → no score extraction (backward compatible)

## Student Repo Auto-Creation (`/join/...`)

Replaces GitHub Classroom's "assignment link" flow (see `docs/REPO_GENERATION_PLAN.md` for full design):
`GET /join/{course_id}/{lab_id}` lands the student on a page with a "Sign in with GitHub" button;
`/join/{course_id}/{lab_id}/start` and `/join/callback` drive a GitHub OAuth Web Application Flow
(username is only ever taken from the verified `GET /user` response, never from the frontend) and then
create the student's repo from the lab's `template-repo` and fix up collaborator access, using the
server's `GITHUB_TOKEN` - not the student's OAuth token. Orchestration lives in
`grading/repo_provisioning.py` (`RepoProvisioner`), mirroring `grading/grader.py`'s `LabGrader`.
Requires a GitHub OAuth App registered by the teacher (not the student) - see `.env.example`.

Labs with `repo-provisioning: fork` (see `docs/COURSE_CONFIG.md`) can later have template updates propagated
to every student fork as pull requests, from the admin lab list page (`/admin/courses/{course_id}/labs`).
Orchestration lives in `grading/propagate.py` (in-memory job state, single-worker backend required - see
`docs/PROJECT_DESCRIPTION.md`). All `/admin/...` and course-management routes require the `require_admin`
FastAPI dependency in `main.py`, not just the frontend's `ProtectedRoute`.

## CI/CD

- **Tests**: Run on every push via `.github/workflows/tests.yml`
Expand Down
17 changes: 12 additions & 5 deletions courses/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@
version: "1.0"

courses:
- id: "os-2026-spring"
- id: "ml-2026-autumn"
file: "machine-learning-2026.yaml"
status: "active"
priority: 100
featured: true
logo: "/courses/logos/itmo_ml_logo.png"

- id: "os-2026"
file: "operating-systems-2026.yaml"
status: "active"
priority: 100
Expand All @@ -29,19 +36,19 @@ courses:

- id: "mlb-2026-spring"
file: "machine-learning-basics-2026.yaml"
status: "active"
status: "archived"
priority: 90
logo: "/courses/logos/mlb-2026_logo.png"

- id: "rts-2026-spring"
file: "random-processes-and-time-series-2026.yaml"
status: "active"
status: "archived"
priority: 90
logo: "/courses/logos/itmo_random_processes_time_series.png"

- id: "nn-2026-spring"
file: "neural-networks-2026.yaml"
status: "active"
status: "archived"
priority: 80
logo: "/courses/logos/nn-2026_logo.png"

Expand All @@ -62,7 +69,7 @@ courses:
file: "machine-learning-2025.yaml"
status: "archived"
priority: 90
logo: "/courses/logos/ml-2025_logo.png"
logo: "/courses/logos/itmo_ml_logo.png"

- id: "fs-2025-autumn"
file: "fundamental-statistics-2025.yaml"
Expand Down
File renamed without changes
175 changes: 175 additions & 0 deletions courses/machine-learning-2026.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
# Configuration file for lab-grader

course:
name: Машинное обучение
alt-names:
- Машинное обучение
- МО
- Machine learning
- ML
semester: Осень 2026
university: ИТМО
email: mdpoliak@itmo.ru
timezone: UTC+3
github:
organization: itmo-ml-2026
teachers:
- "Mark Polyak"
- markpolyak
google:
spreadsheet: 1zIZOW35vWIV0DkoJtpxy_R0o3PudONXlkDxeRNyVzv0
info-sheet: График
task-id-column: 0
student-name-column: 1
lab-column-offset: 1
staff:
- name: Поляк Марк Дмитриевич
title: преп. практики
status: лектор
- name: Поляк Марк Дмитриевич
title: преп. практики
status: лабораторные работы
- name: Шаврин Андрей Андреевич
title: ассистент
status: лабораторные работы
- name: Сениченкова Яна Олеговна
title: инженер
status: лабораторные работы
labs:
"0":
github-prefix: ml-lab0
template-repo: itmo-ml-2026/github-starter-course
repo-provisioning: fork
short-name: ЛР0
penalty-max: 5
ignore-task-id: True
ci:
- workflows
files:
- goals.md
- info.md
- report.pdf
moss:
language: c
report:
- Задание
- Результат
validation:
commits:
-
filter: console
min-count: 1
"1":
github-prefix: ml-lab1
template-repo: itmo-ml-2026/lab1-eda
repo-provisioning: fork
short-name: ЛР1
taskid-max: 8
# ignore-task-id: True
penalty-max: 2
ci:
workflows:
- run-autograding-tests
- Test python scripts
files:
- exercises.ipynb
moss:
language: python
max-matches: 1000
local-path: lab1
report:
- Цель работы
- Индивидуальное задание
- Описание входных данных
- Результат выполнения работы
- Исходный код программы с комментариями
- Выводы
"2":
github-prefix: ml-lab2
template-repo: itmo-ml-2026/lab2-linreg-sgd
repo-provisioning: fork
short-name: ЛР2
taskid-max: 7
# ignore-task-id: True
penalty-max: 2
ci:
- workflows
files:
- exercises.ipynb
moss:
language: python
max-matches: 1000
local-path: lab2
report:
- Цель работы
- Задание на лабораторную работу
- Результат выполнения работы
- Выводы
"3":
github-prefix: ml-lab3
template-repo: itmo-ml-2026/lab3-binary-classification
repo-provisioning: fork
short-name: ЛР3
taskid-max: 5
# ignore-task-id: True
penalty-max: 2
ci:
- workflows
files:
- exercises.ipynb
moss:
language: python
max-matches: 1000
local-path: lab3
report:
- Цель работы
- Задание на лабораторную работу
- Результат выполнения работы
- Выводы
"4":
github-prefix: ml-lab4
template-repo:
repo-provisioning: fork
short-name: ЛР4
# taskid-max: 20
# ignore-task-id: True
penalty-max: 2
ci:
- workflows
files:
- exercises.ipynb
moss:
language: python
max-matches: 1000
local-path: lab4
report:
- Цель работы
- Задание на лабораторную работу
- Результат выполнения работы
- Выводы
"5":
github-prefix: ml-lab5
template-repo: itmo-ml-2026/lab5-backprop
repo-provisioning: fork
short-name: ЛР5
taskid-max: 5
# ignore-task-id: True
penalty-max: 2
ci:
- workflows
files:
- exercises.ipynb
moss:
language: python
max-matches: 1000
local-path: lab5
report:
- Цель работы
- Задание на лабораторную работу
- Результат выполнения работы
- Выводы
misc:
requests-timeout: 5


16 changes: 15 additions & 1 deletion courses/operating-systems-2026.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ course:
- OS
- Operating systems
- ОС
semester: Весна 2026
semester: Весна 2026, Осень 2026
university: ГУАП
email: k43guap@ya.ru
timezone: UTC+3
Expand All @@ -32,6 +32,8 @@ course:
labs:
"0":
github-prefix: os-task0
template-repo: suai-os-2026/github-starter-course
repo-provisioning: fork
short-name: ЛР0
penalty-max: 5
ignore-task-id: True
Expand All @@ -53,6 +55,8 @@ course:
min-count: 1
"01":
github-prefix: os-task-I-1
template-repo: suai-os-2026/os-course-task1-1
repo-provisioning: fork
short-name: ЛР0.1
taskid-max: 20
penalty-max: 6
Expand All @@ -72,6 +76,8 @@ course:
- Выводы
"1":
github-prefix: os-task1
template-repo: suai-os-2026/os-course-task1-new
repo-provisioning: fork
short-name: ЛР1
taskid-max: 25
penalty-max: 6
Expand Down Expand Up @@ -104,6 +110,8 @@ course:
- Выводы
"2":
github-prefix: os-task2
template-repo: suai-os-2026/os-course-task2
repo-provisioning: fork
short-name: ЛР2
taskid-max: 20
taskid-shift: 4
Expand Down Expand Up @@ -140,6 +148,8 @@ course:
- Выводы
"3":
github-prefix: os-task3
template-repo: suai-os-2026/os-course-task3
repo-provisioning: fork
short-name: ЛР3
taskid-max: 20
penalty-max: 7
Expand Down Expand Up @@ -175,6 +185,8 @@ course:
- Выводы
"4":
github-prefix: os-task4
template-repo: suai-os-2026/os-course-task4
repo-provisioning: fork
short-name: ЛР4
taskid-max: 30
penalty-max: 7
Expand Down Expand Up @@ -206,6 +218,8 @@ course:
- Выводы
"5":
github-prefix: os-task5
template-repo: suai-os-2026/os-course-task5
repo-provisioning: fork
short-name: ЛР5
taskid-max: 30
penalty-max: 8
Expand Down
Loading
Loading