diff --git a/MAINTAINERS.md b/MAINTAINERS.md index dd2f0df..c1a839d 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -26,18 +26,13 @@ When a PR has been accepted: * Update PR title if necessary to clarify purpose. * Prefer using merge commits from Github to record PR name and number. -* For automated PR's (like pyup.io), prefer using rebase from Github UI. +* For automated PR's (like dependabot), prefer using rebase from Github UI. ## Releasing New Versions 1. Decide on the next version number, based on what has been added to the `main` - branch since the previous release: - - * Major breaking changes should increment the first number and reset the - other two, eg `1.10.0 -> 2.0.0`. - * New features should increment the second number and reset the third, - eg `1.10.0 -> 1.11.0`. - * Bug fixes should only increment the third number, eg `1.10.0 -> 1.10.1`. + branch since the previous release. See the + [Versioning Guide](https://usort.rtfd.io/en/latest/versioning.html). 2. Update `CHANGELOG.md` with the new version, following the same pattern as previous versions. Entries should reference both the PR number and any @@ -46,8 +41,12 @@ When a PR has been accepted: Contributers to this release should be acknowledged by including the output of `git shortlog -sn ...`. -4. Commit the updated version number and changelog with a message following - the pattern "(Feature | bugfix) release v". +3. If releasing a new major version, ensure the ``check_backcompat.py`` test + script has been updated to match the intended backward compatibility + version target for future releases. + +4. Commit the updated content with a message following the pattern + "(Feature | bugfix) release v". 5. Push this commit to upstream main branch and wait for CI to run/pass. diff --git a/docs/api.rst b/docs/api.rst index 0c7332c..7d81c18 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,3 +1,5 @@ +.. _api: + API Reference ============= diff --git a/docs/changelog.rst b/docs/changelog.rst index 83d7eb5..8ad71eb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,4 +1,7 @@ Changelog ========= +See the :ref:`Versioning Guide ` for details on µsort's version scheme +and recommendations on how to handle upgrades. + .. mdinclude:: ../CHANGELOG.md diff --git a/docs/index.rst b/docs/index.rst index 8c1d977..3644e91 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,6 +18,7 @@ :hidden: :maxdepth: 1 + versioning changelog contributing code-of-conduct diff --git a/docs/versioning.rst b/docs/versioning.rst new file mode 100644 index 0000000..3d40eee --- /dev/null +++ b/docs/versioning.rst @@ -0,0 +1,104 @@ + +.. _versioning: + +Versioning +========== + +µsort tries to maintain the *spirit* of `SemVer `_ while +focusing primarily on the sorting and formatting results than strictly on the +API contract. + +In general, µsort will attempt to maintain consistent formatting results within +a major version, with a best-effort attempt to remain "backwards compatible" +with previous versions of µsort within that major release. Except for obvious +or egregious formatting errors, any file sorted by a newer release of µsort +should produce no changes if formatted by previous minor/patch versions +in that family. + +Our goal is to enable a safe and predictable process for users to introduce +updates to their projects, especially in large monorepos. This policy allows +users to transparently and proactively format their codebase with new minor +or patch versions, and validate the resulting behavior, before upgrading CI +workflows or developer toolchains to the latest release. + +For example, a file already sorted by µsort ``1.1.3`` may produce changes when +sorted by a newer µsort ``1.2.1`` release, but a file already sorted by ``1.2.1`` +should remain unchanged if sorted again by ``1.1.3``. However, a file sorted by +a future µsort ``2.0.0`` release may not be stable if sorted again by version +``1.2.1``. + + +Details +------- + +It is our intent to: + +1. Bump the post version (and yank the original, depending on how severe) for: + + - documentation or packaging issues, such as missing files in the sdist + or unintended classifiers + +2. Bump the patch version for: + + - garden-variety bugs, such as those where the previous behavior was an exception + (such as `#194 `_) + - any bug that produces output so mangled it would not have been accepted + by human review (such as `#187 `_ + fixed in `#188 `_ + causing unnecessary reflow that disagreed with black) + - performance optimizations that expect to have no impact on sorting behavior + + Additionally, if the bug causes data loss, we will also yank affected + releases (best effort), but the timing of the yank is not defined here. + The spirit of this is to prevent people from installing known-bad versions, + but if people pin then yanking is a sign, not a cop. + +3. Bump the minor version for: + + - new features that may change the output (at the byte level) for greenfield + sorting, but produce output that can then be sorted with previous versions + (see above) without producing additional changes + (such as `#140 `_) + - anything that includes a new config option (although the defaults for + those config options must keep previous behavior); if a consumer project + relies on a certain config option, it is on them to constrain to `>=` + the version where that was added + - any new ``DeprecationWarning`` + - changing strings intended for humans (e.g. ``Result.warnings``) or exception + classes (e.g. ``Result.exception``, or its specific values or hierarchy) + which are not part of the :ref:`documented API `. + +4. Bump the major for: + + - any formatting change that breaks the ``backward-compatibility`` test + on CI, i.e. any change to sorting behavior that would result in previous + versions of µsort producing changes in code already sorted with the new + version + - any intentional change to picking ``pyproject.toml`` or inferring + first-party names + - any backwards-incompatible API change or removal + + Additionally, within reason we will yank releases that should have bumped + the major but didn't, once informed. + +5. Note that we assume our deps follow reasonable versioning practices + (and since several of them are us with another hat on, this is believable). + In particular: + + - We rely on ``trailrunner`` for discovery of ``pyproject.toml``, and will + constrain to a major version, with the expectation that any intentional + changes to discovery behavior will happen with a major version change. + There may still be subtle edge cases when faced with complicated systems, + like UNC paths on Windows or bind-mounted path loops on Linux. + - We rely on ``stdlibs`` to classify top-level names in the stdlib section + or not. This is date-versioned currently, and in general we *want* the + updates like `stdlibs#25 `_, + even though that *can* cause formatting changes in uncommon cases. + - If you are sensitive to behavior changes, we suggest pinning to specifc + versions of the following packages: + + - ``black`` + - ``libcst`` + - ``stdlibs`` + - ``trailrunner`` + - ``usort`` diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index e69de29..0000000