Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Writing Clear Upgrade Notes for Laravel Package Releases

Laravel package maintainers need upgrade notes that help users decide whether a major release affects their code and what to change before upgrading. A major release signals that backward-incompatible changes may exist. Upgrade notes identify those changes and give affected users a path to update and verify their applications.

A package’s public API is the set of interfaces users are expected to rely on. For a Laravel package, that includes PHP classes and methods, plus commands users run through Artisan. It also covers configuration keys and database migration files users publish in their applications, along with routes, middleware aliases, and events. Under Semantic Versioning, a backward-incompatible change to the declared public API requires a major version increment after version 1.0.0. That version number signals a compatibility break, but it does not tell each user whether the break applies to them.

Clear notes name the affected surface, explain who needs to act, and describe the action and a way to check the result. This structure gives users steps to follow and helps prevent avoidable support requests. No note format guarantees fewer support requests.

State who needs to act

Open the upgrade guide with a short impact summary. Tell readers whether the release affects users who call a particular method, publish the package’s configuration, customize a model, implement a package contract, or have already copied a migration into their application. Readers who do not use an affected surface should be able to tell that they can skip the corresponding instruction.

Be precise about what the package treats as public. A method rename matters to users who call that method. A migration change matters to users whose database setup includes the earlier migration. A new default configuration value can affect users who rely on package defaults, while a renamed key can require an edit from users with a published configuration file. These are different changes with different audiences, even when they ship in the same major release.

The Laravel upgrade guide offers a useful model: it identifies specific changes and says which applications they affect. Apply that principle to a package by naming which users need each step, using wording such as “If your application implements this contract…” or “If you published this configuration file…”. This keeps conditional steps from sounding mandatory for everyone.

Describe each breaking change on its own

A useful breaking-change entry answers four questions: what changed, who is affected, what action they should take, and what happens if they do nothing when that consequence is known. “The API changed” answers none of them. “The package removed a method used by custom model implementations; update those implementations to use the replacement method” gives readers a way to assess and address the change.

Keep the change under a consistent changelog category, such as Changed or Removed, and mark it clearly as breaking. Keep a Changelog recommends identifying the broken interface rather than relying on the word “breaking” by itself. A prominent summary near the top of the upgrade guide can help readers scan, while categorized entries keep the full record organized.

When the consequence is not established, do not guess. State what the release changes and which users encounter it, then tell them what to inspect in their own integration with the package. For example, if a package changes a migration stub, explain whether users who already ran the previous migration need an application migration. The package’s actual schema and data changes determine the answer; “run migrations” is not a safe universal instruction.

Show old and new names together

For a renamed class, method, event, command, or namespace, give users a direct mapping and say where to update references. A compact table works well:

Before After User action
Old class or symbol Replacement class or symbol Update the relevant import, listener, binding, or call site

The action column matters. A class rename may require a change in an event listener or service-provider binding, while a method rename affects call sites. If the command’s PHP class changes but its Artisan name and options stay the same, say so. Readers should not infer that one name change implies another.

The Spatie laravel-permission upgrade guide demonstrates this approach with package-specific event and command renames. Its instructions also distinguish renamed classes from unchanged command signatures. Those details describe that package’s releases, but the documentation technique applies broadly: name the old and new symbols, identify likely integration points, and specify what remains unchanged when that distinction affects the user’s work.

Explain configuration changes for both kinds of users

For each configuration change, name the file and key. Explain whether the change added or removed the key, renamed or moved it, or gave it a new default. State who must edit it. A mapping table makes spelling and structure changes easy to compare:

Existing configuration New configuration User action
Previous key or structure Replacement key or structure Edit the published file, if present

Some users rely on package defaults; others publish a configuration file and customize it. Laravel package documentation explains that Laravel combines package defaults with application configuration at the first level of the configuration array, but does not merge nested arrays at deeper levels. The Laravel package development documentation is for Laravel 10.x, so maintainers should check the behavior against the Laravel versions their package supports.

State whether users with an unpublished default configuration need to act, and whether users with a published file should edit it or publish a fresh copy. If the new default changes behavior, explain how a user can preserve the previous behavior when the package supports that choice. When instructions involve environment variables, identify where the user should set them and what deployment step follows. Laravel documents that configuration caching changes when .env values are loaded, so users should not be left to assume that editing an environment file immediately changes a cached deployment’s behavior. See the Laravel configuration documentation.

Put migration work in order

A migration guide should separate package installation from application-specific changes. Give actions in the order users should perform them, and mark conditional work explicitly. For example:

  1. Update the package constraint in composer.json and run the targeted Composer update.
  2. Compare the package's new migration templates (stubs) with migration files already in the application.
  3. Add or adjust an application migration if the release requires a database change.
  4. Update any published configuration file to account for the new package defaults.
  5. Update custom models, overridden methods, contract implementations, and renamed API references that apply to the application.
  6. Run relevant tests and verify the changed behavior.

The Spatie upgrade guide provides package-specific examples of these tasks, including comparing migration stubs and checking custom models and contract signatures. Do not present every step as mandatory for every user. Write “If your application has already run the previous migration…” or “If you implement this contract…” so readers can skip work that does not match their setup.

Describe database changes carefully. If a release changes the database structure (its schema), explain whether users need a new application migration and what that migration changes. Do not tell users to run a database command without confirming the package’s migration behavior and the deployment context. The user needs enough detail to plan the change, especially when existing data is involved.

Keep the upgrade guide and changelog aligned

Use the changelog as the durable, complete record of notable release changes. Use the major-version upgrade guide as the focused path through compatibility breaks and migration work. A release announcement can summarize the headline changes and link to that guide. Keep a Changelog distinguishes the ongoing changelog from release notes that curate information and include upgrade instructions.

A short action can sit beside its changelog entry. When a change requires several steps, keep the entry brief and link to the detailed upgrade instructions. This lets users scan the release record without losing the steps they need to complete the upgrade.

Review generated notes before publishing. Commit history and automated summaries can help identify changes, but they do not reliably explain user impact. Check that the notes cover every break users encounter. For each renamed symbol, confirm that the notes name a replacement. Make sure they distinguish default configuration from published files and match the package’s actual database migration path. Finally, verify that the notes describe the released code.

What I'm building

Delegate tasks. Get software.

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

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *