.. _release_policy: ========================== 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: 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. .. list-table:: Release workflow comparison :header-rows: 1 :widths: 24 24 28 44 * - Workflow - Release branch base - Route to release - Purpose * - Feature (minor-release) workflow - ``upstream/dev`` - release branch → ``upstream/dev`` → ``upstream/main`` - Includes the compatible features, improvements, and fixes accumulated for the next minor version. * - Patch workflow - ``upstream/main`` - patch branch → ``upstream/main`` - Releases selected fixes from the current stable line without including unreleased features already present on ``upstream/dev``. 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: 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 :ref:`release_branch_routes` and create ``release_branch`` from ``upstream/dev`` for a minor release or the current stable commit on ``upstream/main`` for a patch release. For a patch, include only the selected fixes and necessary supporting changes. #. Review the ``Unreleased`` section of ``CHANGELOG.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, place ``Fixed`` first and confirm that it is non-empty and clearly states the defect that justifies the release. #. Finalize the release version and date in ``CHANGELOG.md`` and ``CITATION.cff``. #. Update ``docs/source/_static/switcher.json``: - Change the stable entry's display name to the full ``X.Y.Z (stable)`` version while retaining ``stable`` as 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, and ``CHANGELOG.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.toml`` and ``CHANGELOG.md`` as needed. Integrate the Release ^^^^^^^^^^^^^^^^^^^^^ For a minor release using the feature workflow: #. Merge the completed ``release_branch`` into ``upstream/dev`` through a reviewed pull request. #. Merge ``upstream/dev`` into ``upstream/main`` through a reviewed pull request. #. Use the resulting ``upstream/main`` commit as the release base. For a patch release using the dev-bypass workflow: #. Merge the completed ``release_branch`` directly into ``upstream/main`` through a reviewed pull request, without routing it through ``upstream/dev``. #. Use the resulting ``upstream/main`` commit 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 ``v`` prefix. * **Previous tag:** select the previous published version, then click **Generate release notes**. * **Release notes:** place a brief release summary first, followed by a ``## Changelog`` section containing the associated entry from ``CHANGELOG.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/main`` back into ``upstream/dev`` after 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/dev`` for the next development cycle and confirm its required checks pass. #. Remove the merged ``release_branch`` when it is no longer needed.