1.11.10 — Deploy failures report themselves, and a release can no longer move every fleet at once
Editorial identity incomplete
2026-08-14
django-mojo 1.11.10 closes the two halves of the 2026-08-14 deploy outage: an update script that cannot run now reports exactly why and releases the deploy plane instead of wedging it silently, and a new operator-controlled framework version hold means a PyPI release no longer changes what fleets install until someone says so. Hosted login now completes administrator-issued temporary passwords.
Added
EDGE_FRAMEWORK_VERSION— a protected system setting that pins the django-mojo version every fleet deploy installs. Set from the Admin portal (superuser with fresh authentication);holdstays on the last converged fleet version; unset keeps installing the newest published release. Read live: a change applies from the next deploy.- The Admin platform page reports the hold (
framework_pin: configured, value, mode, and whatholdcurrently resolves to). - Node update scripts declare a deploy contract (a header marker, plus a
--contractflag that answers even on an unprovisioned box). A provably stale fork is refused by name before it runs, instead of dying as an unexplainedexit 2. - Deploy failure evidence carries a redacted tail of the update script's stderr, so a node-side root cause is readable from the platform record without shell access.
- The node auditor flags an
aws/update.shthat has lost its execute bit. - A push recorded against a dead deploy is automatically resumed by the reconciler's next sweep, instead of waiting for another push.
Changed
- A deploy that fails no longer blocks the plane: a terminal failed lease is immediately re-armable, so the next push starts a deploy (
queued: true) instead of being recorded against the dead attempt until the coordination window expires. - An orchestrator whose deploy is superseded by a newer push stands down cleanly, rather than spinning to its timeout and filing a false canary incident.
- Deploy-time nginx activation failures name the missing runtime include, and health-probe timeouts name the port-80 catch-all as the likely cause on edge-converged nodes.
Fixed
- An update script that could not be executed (lost execute bit, missing file), timed out, or was unconfigured bypassed all failure reporting — no incident, no evidence, and a single-runner fleet's deploys silently stopped, stranding every subsequent push. All outcomes now report and close the deployment.
- The hosted login page completes administrator-issued temporary passwords: the forced-password response switches to the new-password form and finishes login, instead of stranding the user without a session. Custom login pages branch on
requires_password_changeand callMojoAuth.completeForcedPassword().
Upgrade notes
- Edge-converged nodes must export a vhost-true
PROBE_URL/SANITY_URLfrom their shim: the packaged localhost default hits the port-80 catch-all, fails the health gate on a healthy app, and makes a rollback report failure on a healthy node. - The documented edge nginx bootstrap needs the runtime include line (now in the docs); without it every deploy's render convergence fails.
- Project-side update scripts should ship committed as executable, or better, as the packaged shim — the deploy plane now audits and refuses what it can prove stale.
- Contract rule, both directions: anything the deploy plane reads across an upgrade boundary stays readable one generation back.