Clone conference durable workflow - #4822
marcoacierno wants to merge 7 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Adds a durable Resonate workflow (clone_conference) plus an admin action/form to spin up the next conference edition by copying configuration (deadlines, durations, schedule days, sponsor levels/benefits, email templates, CMS content, forms, voting included events) while leaving edition-specific content untouched. Bug: cloning collapses multiple custom deadlines into one. copy_deadlines in backend/conferences/workflows/clone_conference.py keys Deadline.objects.get_or_create on (conference, type) only. Deadline.TYPES.custom is explicitly allowed to repeat per conference: validate_deadlines_form in backend/conferences/admin/conference.py skips the "one deadline per type" check specifically when type is custom. So a source conference with several custom deadlines will only have the first one copied; the rest match the already-created (conference, custom) row and are silently dropped. The code already handles this correctly for EmailTemplate (copy_email_templates disambiguates custom templates by name) but the same treatment is missing for copy_deadlines. No test exercises more than one deadline per source conference, so this gap is not caught. Minor: create_conference and the copy steps annotate new_start/new_end as datetime, but callers (start_clone_conference, and the workflow own clone_conference entrypoint) always pass ISO-format strings. It happens to work because Django DateTimeField parses ISO strings on save, but the type hints are misleading for anyone extending these steps. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## resonate-ecs-setup #4822 +/- ##
=====================================================
Coverage ? 92.83%
=====================================================
Files ? 360
Lines ? 11508
Branches ? 945
=====================================================
Hits ? 10684
Misses ? 703
Partials ? 121 🚀 New features to boost your workflow:
|
9a35ba5 to
84ddcd4
Compare
Setting up the next edition means re-creating, by hand, everything that is configuration rather than content. `clone_conference` does it in one Resonate workflow: the conference itself (settings and taxonomies, never the pretix ids or the logo), then deadlines shifted by the gap between the two editions' start dates, durations, sponsor benefits/levels/special options, email templates, generic copy, FAQs, menus, forms and their questions, and voting included events. Each copy is a durable step wrapped in a transaction and keyed on the natural key of what it creates, so a failed run resumes from the step that failed and re-running never duplicates anything. i18n fields cannot be used in ORM lookups, so models keyed on one are de-duplicated in Python. Content produced during an edition -- proposals, schedule, keynotes, sponsors, grants, vouchers, answers -- is never copied. Triggered with `manage.py clone_conference <source> <new> ...`, whose workflow id defaults to `clone-conference-<new_code>`.
Creating the next edition is something organizers do from the admin, not from a shell: selecting the conference to use as base and running *Create new conference using this one as base* opens a form for the code, name, hostname and dates of the new edition, prefilled with the same values one year later, and starts the workflow. The form refuses a code or hostname already in use, and a start after the end. Each submission gets its own workflow id so a run that failed for good can be started again; a double submit is harmless anyway, since every step of the workflow only creates what is not there yet.
The bare `Resonate()` the tests build picks up RESONATE_URL from the
environment, so in a container that has one they ran against the real
server and replayed promises left by an earlier run instead of executing
the workflow. `env={}` pins them to the in-process connection.
The new edition gets one day per date it runs on, in its own timezone, and each takes the rooms and slots of the source day in the same position, so a conference that opens with a workshop day keeps that shape. Days the source edition did not have are left empty, and the streaming and Sli.do links stay with the edition that used them.
Every copy step opened with the same four lines: import the models, open a transaction, and look up the two conferences. A `copy_step` decorator now does that once and hands each step the source and the new conference, so what is left in each is only what it copies. `copy_cms_content` covered three unrelated kinds of content in one long body; it now calls one function per kind.
The action already refuses anything but a single conference, so passing the selection to the template as a list -- and the action's own name as a context variable -- only made the page look more general than it is.
Review follow-ups: the action name the page posts is taken from the function again, so renaming it cannot leave the form posting an action that no longer exists (nothing renders this template in tests, so a wrong name would go unnoticed); the steps keep their qualified name, so a traceback names the step it came from rather than the decorator; and the `copied` keys say why they are spelled out instead of derived.
84ddcd4 to
3bb145a
Compare
Setting up the next edition means re-creating, by hand, everything that
is configuration rather than content.
clone_conferencedoes it in oneResonate workflow: the conference itself (settings and taxonomies, never
the pretix ids or the logo), then deadlines shifted by the gap between
the two editions' start dates, durations, sponsor benefits/levels/special
options, email templates, generic copy, FAQs, menus, forms and their
questions, and voting included events.
Each copy is a durable step wrapped in a transaction and keyed on the
natural key of what it creates, so a failed run resumes from the step
that failed and re-running never duplicates anything. i18n fields cannot
be used in ORM lookups, so models keyed on one are de-duplicated in
Python.
Content produced during an edition -- proposals, schedule, keynotes,
sponsors, grants, vouchers, answers -- is never copied.
Triggered with
manage.py clone_conference <source> <new> ..., whoseworkflow id defaults to
clone-conference-<new_code>.What
ToDo