Skip to content

feat: per-assignment submission triggers — modes and milestone tags (#477) - #531

Open
joshkaplan-dev wants to merge 5 commits into
mainfrom
feat/submission-mode
Open

feat: per-assignment submission triggers — modes and milestone tags (#477)#531
joshkaplan-dev wants to merge 5 commits into
mainfrom
feat/submission-mode

Conversation

@joshkaplan-dev

Copy link
Copy Markdown
Contributor

Summary

Adds per-assignment control over when the autograder runs, completing #477 in
two parts delivered together: a submission mode (every push vs. submit-only)
and teacher-named milestone tags that trigger grading.

By default every push grades, spending Actions minutes on every work-in-progress
commit. This PR adds two levers:

  • submission_modeevery-push (default, unchanged) or tag (only
    submit/* tag pushes grade; a plain git push costs no Actions minutes).
  • submission_tags — optional tag patterns (e.g. phase1, phase2) that
    also trigger grading. A student pushing a matching tag gets that commit graded
    with plain git — no CLI required.

Milestone tags trigger; submit/* records. A milestone tag can move between
commits, so a milestone-tag push triggers grading and the runner mints the
canonical immutable submit/<UTC-timestamp>-<short-sha> tag at that commit and
publishes the release there. The collector, regrade, web views, and download are
unchanged — all still key on submit/*. (This is why the issue's migration step
is unnecessary: submit/* stays infrastructure, not config.)

Also in this PR — the retrofit tooling (gh teacher assignment submission-mode + web bulk/per-row actions) that rewrites existing repos'
shims; the runner-side stale-shim and foreign-tag suppression; and a few fixes
found during live testing:

  1. set-latest was dead code (self-compared, never acted) → explicit best-effort
    claim; latest = most recent submission.
  2. Retrofit misreported after a cached pre-write read → reports from the actual
    commit outcome.
  3. Regrade failed on immutable-release orgs (refused delete) → tolerates the
    refusal, keeps the old release, warns.
  4. Milestone-tags field validated only on save → live validation + a
    comma-vs-newline hint.

Design deviations from the issue: no config migration
(obsoleted by the triggers-vs-records design) and no default submission tag
(absent = no milestone tags).

Deferred (per the issue): tags-ignore /
exclude patterns, custom branch triggers, drift-detection UI.

Closes #477

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor / maintenance

Checklist

  • I built, tested, and linted the module(s) I touched:
    • CLI (Go): go build ./... && go test ./... && golangci-lint run in the module dir (cli/gh-teacher, cli/gh-student, or cli/shared)
    • Web: cd web && npm run check
    • Skeleton scripts (Python): python3 -m pytest cli/gh-teacher/skeleton_tests -q
  • If I changed a cross-binary contract, I updated schemas/*.schema.json and every mirror (Go / Python / TypeScript), and the parity tests pass.
  • If I added or changed a CLI command or flag, I documented it in the wiki (not in a README).
  • My commits follow Conventional Commits (e.g., feat(web): ..., fix(gh-teacher): ...).

# Conflicts:
#	cli/gh-teacher/init_skeleton_test.go
#	cli/gh-teacher/skeleton/dotgithub/workflows/autograde-runner.yaml
- web: pass submission_tags to the per-row trigger retrofit (SubmissionsPage
  -> SubmissionsTable) so a row-level update no longer erases milestone
  patterns from the shim
- web: pin the shim retrofit's read-rewrite-commit cycle to one resolved tip
  SHA (read-after-write lag misreport; mirrors the Go retrofitShim fix)
- web: run the bulk trigger retrofit serially (REPO_WRITE_CONCURRENCY=1) —
  3-step git-data writes, matching the CLI's serial rate-limit stance
- python: add the charset fail-closed gate to both matcher copies
  (regrade_repos.py, autograde-runner.yaml) matching Go/TS
  IsSafeSubmissionTagPattern, and pin it with new charset-unsafe +
  unclosed-bracket golden fixture cases (all four sides re-verified)
- web: add the submission_tags schema-parity vitest the Go comment already
  claimed existed (cap + charset vs assignments-v1.schema.json)
- go: point shimTriggerBlock at its web SHIM_TRIGGER_BLOCK mirror; extend the
  --empty-repo mutual-exclusion text to the new submission flags (help + wiki)
- fixture: correct the _comment (four implementations, submissiontags.go)
@joshkaplan-dev
joshkaplan-dev marked this pull request as ready for review August 7, 2026 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: configurable submission trigger (custom tag vs. every push)

1 participant