Plans cascade version bumps through the dependency graph.
When a package is bumped, all packages that depend on it receive a patch bump automatically (like Rush in Node.js).
Cascading is idempotent
A cascade does not mean "add a patch to whatever mix.exs says". It means
"ensure this dependent has a bump pending for the current release cycle". The
difference matters as soon as you bump twice before publishing:
mix releaser.bump ex_pdf_components patch # ex_pdf 1.0.6 -> 1.0.7
mix releaser.bump ex_qr patch # ex_pdf must stay at 1.0.7The second cascade reaches ex_pdf again, but its pending 1.0.7 already
covers this cycle — bumping it to 1.0.8 would burn a version number that is
never published. So each dependent is compared against its Releaser.Baseline
(its last released version) and skipped when it is already ahead.
Recursion still walks through skipped apps: a pending dependent may itself have clean dependents that do need a bump.
The directly bumped app is never subject to this check — an explicit bump is user intent, not a cascade.
Summary
Functions
Plans version changes for an app and its publishable dependents.
Returns the list of changes to write, each a map of
%{app:, path:, old:, new:, version_form:, reason:} where :reason is
:direct or :cascade.
Options
:cascade— whenfalse, only the direct app is bumped. Defaults totrue.:baselines— a%{app_name => version | nil}map, bypassing baseline resolution. Mainly for tests; production callers let it resolve.
Like plan/4, but also reports dependents that were skipped.
Returns %{changes: [change], pending: [pending]}, where :pending lists the
dependents already ahead of their baseline as %{app:, version:, baseline:}.
They need no write, but they ARE part of this release cycle — callers render
them so a skipped app does not look like a forgotten one.