Release Policy and Process#
MC/DC uses Semantic Versioning as a guide for distinguishing minor and patch releases and maintains a human-readable release history in CHANGELOG.md.
Minor Releases#
For MC/DC, a minor release primarily expands what the code can do. Examples include an additional transport or execution capability, a new public Python API, a new command-line option, a new opt-in behavior, or a deprecation that users need time to accommodate. A minor release may include compatible fixes and internal improvements alongside its features.
MC/DC plans one minor release in each three-month seasonal cycle. These releases collect compatible features, improvements, and fixes that have passed the project’s required review and validation. For planning convenience, these cycles follow the Northern Hemisphere meteorological seasons: winter (Dec-Feb), spring (Mar-May), summer (Jun-Aug), and autumn/fall (Sep-Nov).
The seasonal schedule is a target rather than a reason to release unverified work. A minor release may be delayed when additional testing, documentation, or integration work is needed; it may also be brought forward when the accumulated changes are substantial and users would benefit from earlier availability.
Patch Releases#
For MC/DC, a patch release primarily restores or strengthens behavior already expected from the current stable release. A change belongs in a patch when it corrects intended or documented behavior, prevents an installation or runtime failure, or fixes an implementation defect without asking users to adopt a new interface. Tests, documentation corrections, refactoring, build changes, and developer tooling may accompany a patch when they support or validate the fix and do not independently expand user-facing behavior. If a change introduces a new option, API, capability, or opt-in behavior, it should normally be held for a minor release even when developed alongside a bug fix and separated from the patch branch. When the classification is not obvious, use the purpose and user impact of the release: capability expansion points to a minor release, while correction of existing behavior points to a patch release.
Bug fixes are not held until the next seasonal minor release.
Once a fix has passed review and the relevant validation and release checks, MC/DC publishes a patch release as soon as practical.
Every patch release must include a non-empty Fixed section in CHANGELOG.md that describes the user-visible defect corrected by the release.
Place Fixed first in a patch release entry so the reason for the release is immediately visible.
Supporting changes may also appear under other headings, but the defect that justifies the patch release must be stated under Fixed.
For dependency-compatibility patches, identify the installation or runtime failure prevented and the affected dependency or version range when known.
Published versions and release notes are available from the MC/DC releases page.
Release Branch Routes#
MC/DC uses different integration routes for feature and patch releases because upstream/dev and upstream/main have different roles.
The development branch integrates work for the next minor release, while the main branch identifies the current stable release line.
Workflow |
Release branch base |
Route to release |
Purpose |
|---|---|---|---|
Feature (minor-release) workflow |
|
release branch → |
Includes the compatible features, improvements, and fixes accumulated for the next minor version. |
Patch workflow |
|
patch branch → |
Releases selected fixes from the current stable line without including unreleased features already present on |
If a patch fix was first developed on upstream/dev, transfer only the fix and its necessary tests, documentation, and supporting changes onto a branch based on upstream/main.
Do not merge upstream/dev into the patch branch.
After publishing the patch, merge upstream/main back into upstream/dev so subsequent minor releases retain the fix.
Release Checklist#
Use this checklist for every minor and patch release.
Here, upstream refers to the canonical mcdc-project/mcdc repository and release_branch refers to the release-preparation branch.
Prepare the Release#
Confirm the intended version and scope against the release policy above.
Select the appropriate Release Branch Routes and create
release_branchfromupstream/devfor a minor release or the current stable commit onupstream/mainfor a patch release. For a patch, include only the selected fixes and necessary supporting changes.Review the
Unreleasedsection ofCHANGELOG.md. Ensure every user-visible change is included under the correct heading, remove empty headings, and add contributor attribution where appropriate. For a patch release, placeFixedfirst and confirm that it is non-empty and clearly states the defect that justifies the release.Finalize the release version and date in
CHANGELOG.mdandCITATION.cff.Update
docs/source/_static/switcher.json: - Change the stable entry’s display name to the fullX.Y.Z (stable)version while retainingstableas its version identifier and URL. - Add the previous stable release as a historical entry, using its Read the Docs tag identifier and URL, and retain the existing historical entries in newest-to-oldest order. - Confirm that every listed historical version is active, built, and reachable on Read the Docs.Review the release diff for user-facing behavior. Confirm that each affected interface or workflow is reflected in the relevant documentation and examples. If existing users must change how they use MC/DC, include the necessary deprecation notice or migration guidance.
Confirm whether the release changes the supported Python versions. If it does, update
pyproject.toml, the compatibility workflows, installation documentation, andCHANGELOG.md.Confirm the required local checks, continuous-integration workflows, and distribution artifact tests pass on the release candidate; resolve any dependency incompatibilities they expose and update
pyproject.tomlandCHANGELOG.mdas needed.
Integrate the Release#
For a minor release using the feature workflow:
Merge the completed
release_branchintoupstream/devthrough a reviewed pull request.Merge
upstream/devintoupstream/mainthrough a reviewed pull request.Use the resulting
upstream/maincommit as the release base.
For a patch release using the dev-bypass workflow:
Merge the completed
release_branchdirectly intoupstream/mainthrough a reviewed pull request, without routing it throughupstream/dev.Use the resulting
upstream/maincommit as the release base.
Publish from Main#
Create the
v-prefixed tag and GitHub Release from the validated release commit using the following settings:Target: select
main.Release title: use the tag exactly, including the
vprefix.Previous tag: select the previous published version, then click Generate release notes.
Release notes: place a brief release summary first, followed by a
## Changelogsection containing the associated entry fromCHANGELOG.md, then the generated release notes.Release label: select Latest.
Finish: click Publish release when creating the release, or Update release when editing an existing release.
Confirm that the automatically triggered Publish Python Package to PyPI and Check citation metadata workflows complete successfully, and that the release is available from the stable Read the Docs site.
Smoke-test the published PyPI package in a clean environment with
python -m pip install "mcdc==X.Y.Z", then run a minimal MC/DC simulation.
Return to Development#
Merge
upstream/mainback intoupstream/devafter the release is published and verified.For a patch release, confirm that the back-merge retains the patch while preserving the unreleased feature work already on
upstream/dev.Prepare
upstream/devfor the next development cycle and confirm its required checks pass.Remove the merged
release_branchwhen it is no longer needed.