PrepareRelease
What it does
PrepareRelease is the core release execution step.
It discovers packages, loads authored changesets, computes the release plan, updates manifests and changelogs, and prepares the structured release result that later steps can consume.
In other words: most release-oriented commands are really PrepareRelease plus something else.
Why use it
Use PrepareRelease whenever the command needs real release state.
It is the step that unlocks:
- release file updates
- changelog rendering
- release target calculation
- structured
release.*template context - the cached
.monochange/release-manifest.jsonartifact exposed asmanifest.path - later steps such as
CommitRelease,PublishRelease,OpenReleaseRequest, andCommentReleasedIssues
If your command eventually needs release metadata, start with PrepareRelease rather than trying to reconstruct that state in shell.
Inputs
format—markdown,text, orjson
Step-level when condition
All CLI steps support an optional when = "..." condition.
If the expression resolves to false at runtime, monochange skips the step and continues with the next step.
when = "{{ inputs.enabled }}"
Step-level always_run flag
All CLI steps support an optional always_run = true flag.
When set, the step executes even if a previous step in the same command has failed. This is useful for cleanup, notification, or dry-run preview steps that must run regardless of earlier outcomes.
always_run = true
Prerequisites
None. PrepareRelease is the producer step for the rest of the release workflow.
Side effects and outputs
PrepareRelease is stateful.
It can produce:
- updated manifests
- updated changelogs
- deleted or consumed changeset files
- release target information
- a cached release manifest at
.monochange/release-manifest.json - final command output in markdown, text, or JSON form
- structured
release.*template values for laterCommandsteps manifest.pathfor laterCommandsteps that need the on-disk JSON artifact
Built-in release-oriented commands now default their human-readable format input to markdown. Use text when you explicitly want the older plain-text style, or json for automation.
When you only need the resolved package and group versions, use the dedicated DisplayVersions step or the built-in mc versions command instead of overloading PrepareRelease.
It also fills the shorthand template values commonly used by Command steps:
{{ version }}{{ group_version }}{{ released_packages }}{{ changed_files }}{{ changesets }}
Example
[cli.release]
help_text = "Prepare a release from discovered change files"
[[cli.release.inputs]]
name = "format"
type = "choice"
choices = ["text", "json"]
default = "text"
[[cli.release.steps]]
type = "PrepareRelease"
inputs = ["format"]
Composition ideas
Prepare and run a custom follow-up command
[cli.release-with-notes]
help_text = "Prepare a release and print a custom summary"
[[cli.release-with-notes.inputs]]
name = "format"
type = "choice"
choices = ["text", "json"]
default = "text"
[[cli.release-with-notes.steps]]
type = "PrepareRelease"
inputs = ["format"]
[[cli.release-with-notes.steps]]
type = "Command"
command = "echo Releasing {{ release.version }} for {{ released_packages }}"
shell = true
Prepare and then branch into provider automation
Typical production commands look like:
PrepareRelease→PublishReleasePrepareRelease→OpenReleaseRequestPrepareRelease→CommitReleasePrepareRelease→Command
Prepare once, consume several outputs
Because the later steps all depend on the same prepared state, you should generally do one PrepareRelease and then fan out from it with several typed steps rather than trying to run several independent release commands.
Reuse prepared state across separate commands
When you do need to split the workflow across separate commands, monochange can now reuse a prepared release artifact instead of recomputing the release plan from scratch.
The default path is automatic:
mc release
mc release-pr --dry-run
mc release stores the prepared state in .monochange/prepared-release-cache.json, and later commands with a PrepareRelease step reuse it when the git HEAD, workspace status, tracked release inputs, and relevant configuration still match.
That .monochange/ directory is meant for local monochange artifacts. Keep it gitignored so reusable prepared state, the cached release manifest, and other local release metadata do not pollute reviewable commits.
If you need to pass the artifact between explicit jobs or custom commands, use --prepared-release:
mc release --prepared-release /tmp/release-plan.json
mc release-pr --prepared-release /tmp/release-plan.json --format json
If the artifact is stale, monochange falls back to a fresh PrepareRelease run instead of trusting outdated release data.
Good fit / bad fit
Good fit:
- any release workflow
- commands that need release metadata
- commands that need changelog or version updates
Bad fit:
- simple validation-only CI gates
- discovery-only inspection commands
- post-release repair flows (
RetargetReleaseis separate)
Common mistakes
- putting
PublishReleaseorOpenReleaseRequestbeforePrepareRelease - assuming
PrepareReleaseis just a read-only planner in non-dry-run mode - forgetting that later
Commandsteps can consume its structured output directly - forgetting that
--quietsuppresses stdout/stderr and forces dry-run behavior when the command supports dry-run semantics