Testing Mail in Laravel with Mail Fakes
When Laravel code sends an email, a test should verify the intended message without contacting a mail provider or sending mail to…
Laravel package maintainers should release a new major version when a change breaks something they promised users would keep working. Those promises include the package’s documented interfaces and behavior, plus the PHP and Laravel versions it supports.
Semantic Versioning, or SemVer, labels releases as MAJOR.MINOR.PATCH. For a package at version 1.0.0 or later, increase the major number when a change breaks the public API: the interfaces and behavior users are told they can rely on. Add features that preserve compatibility in a minor release, and make bug fixes that preserve compatibility in a patch release, following the SemVer rules.
Check whether an existing, supported installation still works after you update it without changing its code, configuration, or environment. If it does not, identify which promise the change breaks and plan the release accordingly.
A Laravel package’s public contract can include more than PHP method signatures. Laravel packages can also provide service providers and configuration. They can provide commands and routes, as well as views and facades. If the package documents or promises how users interact with any of these parts, maintainers should check them for compatibility. Laravel’s package development documentation shows these package features.
For example, if the package documents config('acme.timeout'), removing that key or requiring users to change how they use it breaks a documented integration. The same applies to removing a documented facade or renaming a public method. Changing a public method’s parameters or the result it returns also requires a major release if existing calls stop working or return an incompatible result.
Maintainers do not need to preserve every internal detail. A private helper or an undocumented implementation choice is not automatically part of the public contract. Check the documentation, published support statements, and established behavior to decide what users could reasonably rely on. Clear promises make it easier to classify future changes consistently.
A package can keep every method name and still break users by changing what a method does. Defaults, output formats, promised ordering, and error handling all matter when the package promises them. Side effects, meaning changes a method makes beyond its returned result, matter too.
Suppose a package documents that a command only reports pending changes. Changing it to modify data as well breaks that expectation. Changing a documented array return value to a collection also breaks callers that rely on the original format. These changes point to a major release even though the method signature may be unchanged.
SemVer classifies compatible bug fixes as patch changes. User reliance on behavior the maintainer considers incorrect can also affect the release decision. If a fix changes a result users can see, check whether they reasonably relied on the old result and explain the change in the release notes. A correction that disrupts supported integrations may need a major release or a gradual transition.
An internal dependency update does not automatically require a major release. SemVer treats dependency updates as compatible when they leave the package’s public API unaffected. Classify the release by its purpose and effect on users.
Composer, PHP’s dependency manager, can create a separate compatibility problem through package metadata. Before installation, Composer checks the package’s require constraints, which set limits on dependency versions. Raising the minimum PHP or Laravel version can exclude environments that the previous release supported. The Composer schema documentation explains how requirements affect installation. If the package promised support for those environments, dropping them breaks that promise and is a strong reason for a major release.
A narrower dependency constraint can also prevent Composer from resolving combinations that worked before. Check the actual constraints and the package’s stated support policy rather than assuming every constraint edit has the same versioning impact. Composer’s version constraint documentation explains how constraints such as ^1.2.3 limit which dependency versions Composer can select. Adding support for another Laravel version while retaining existing supported versions is generally compatible, provided the package’s requirements and tests still cover the old versions.
Before removing a public feature, maintainers can introduce a replacement and mark the old feature as deprecated. This warns users that the feature still works but is planned for removal. SemVer recommends announcing deprecations in a minor release and removing the feature in a later major release. At least one minor release should include the warning.
For example, a package can add a replacement configuration key while continuing to accept the old key, then deprecate the old key in a minor release. Maintainers can remove it in a later major release and include migration instructions. SemVer does not prescribe a fixed waiting period, so maintainers should set expectations in their documentation and release notes.
SemVer treats 0.y.z versions as initial development, a stage when the public API is not considered stable. The standard major-version compatibility promise applies most clearly from 1.0.0 onward. A package at 0.x can still publish and follow its own policy for breaking changes, but users should not assume that moving to the next 0.x minor version guarantees compatibility.
State the package’s 0.x policy in its documentation. If users depend on it in production, clear release notes and migration guidance give them information to assess changes even when the package has not reached 1.0.0.
Before publishing, ask:
Plan a major release if a change breaks a documented interface, promised behavior, or previously supported environment. Use a minor release to add a feature while keeping those promises. Use a patch release to fix a bug without breaking the public contract.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com