Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Changelog Laravel Package

genealabs/laravel-changelog

GeneaLabs Laravel Changelog helps Laravel projects generate structured changelogs from Git commit history. Turn commit messages into release notes, keep users informed of changes, and reduce manual changelog maintenance with a simple Artisan-driven workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm what you installed before you plan around it. The package metadata calls this "A Laravel Nova tool," the description calls it a markdown changelog renderer, and at least one internal note describes an Eloquent audit-trail trait. Those are three different products with three different data postures. Spend ten minutes in a scratch app resolving this; everything below assumes the changelog-renderer reading, which is what the description and release notes support.

Install and pin deliberately.

composer require genealabs/laravel-changelog
php artisan list | grep -i changelog        # what commands actually ship
php artisan vendor:publish --help          # list tags before guessing

Do not assume the version number tracks maturity. 13.0.0 means "aligned to Laravel 13," and the only listed changes are PHP 8.5 and Laravel 13 support. Read composer.json in vendor/genealabs/laravel-changelog for the real php and illuminate/* constraints — a permissive constraint on an untested framework pair is worse than a hard failure, because you find out in production.

Publish config and views, then read them.

php artisan vendor:publish --provider="GeneaLabs\LaravelChangelog\ChangelogServiceProvider"

Open config/changelog.php first: that is where the markdown file path, the route, and any middleware live. Then check php artisan route:list | grep changelog to see whether a route was auto-registered and what middleware it carries.

First use case: ship a "What's New" page in an afternoon. Put a CHANGELOG.md at the repo root in Keep a Changelog format (## [1.4.0] - 2026-03-01, then ### Added / ### Fixed), point the config at it, and hit the route. If the package registers its own route, you are done; if it only provides a controller/view, define one route in routes/web.php and be explicit about middleware.

Implementation Patterns

Content-as-code, enforced in CI. The changelog belongs in the repo, edited in the same PR as the change. The pattern that actually holds up:

# CI step — fails the PR if user-facing code changed without a changelog entry
- run: git diff --quiet origin/main -- CHANGELOG.md || echo "note: no changelog entry"

Assert on the file's format, not just its existence. A single misplaced heading level silently produces an empty or half-rendered page.

Gate the route before you deploy it anywhere shared. Release notes leak unreleased fixes, internal ticket IDs, and customer names. Two viable patterns:

// config/changelog.php — internal-only
'middleware' => ['web', 'auth', 'can:viewChangelog'],

// or don't use the package route at all
Route::get('/changelog', ChangelogController::class)
    ->middleware(['web', 'auth'])
    ->name('changelog');

Public audience? Split the source, not the view. If you need both an internal and a customer-facing history, keep two markdown files (CHANGELOG.md, CHANGELOG-public.md) and two routes rather than filtering sections at render time. Filtering logic drifts; separate files get reviewed properly.

Cache the parse, not just the response. Verify whether the markdown is read per request. If it is, and the page is public, either wrap the render in Cache::remember('changelog', now()->addMinutes(10), ...) or put cache.headers:public;max_age=300 on the route. The output is static; there is no reason to hit disk per visitor.

Reuse the parsed output for a "latest release" widget. The same data feeding the full page can feed a footer badge or a modal partial — "v1.4.0 shipped 3 days ago." That is usually the highest-value use of the package, because the full page gets visited once and the badge gets seen constantly.

Generate drafts, don't auto-publish commits. A step that drafts a changelog section from merged PR titles is useful; committing raw commit messages to a customer-facing page is not. Draft in CI, hand-edit in the PR, merge alongside the tag.

Test the surface, cheaply.

public function test_changelog_page_renders(): void
{
    $this->get('/changelog')->assertOk()->assertSee('Unreleased');
}

This catches the three failures you will actually hit: file missing, malformed markdown, route or middleware misconfigured.

Gotchas and Tips

The scope ambiguity is the top risk, not a footnote. Resolve it in a scratch install before you commit engineering time. If it turns out to be the audit-trail variant, stop and treat it as a data-governance decision (retention, PII in old/new payloads, erasure handling) rather than a static page — a completely different conversation.

Major versions mirror Laravel majors. 11.0 → 13.0.0 is a compatibility jump, not thirteen iterations of hardening. Practically: you cannot take 13.x fixes while on Laravel 12, and every framework upgrade now carries a mandatory package-major review. Put it on the upgrade checklist as a standing line item.

"Added PHP 8.5 support" tells you nothing about the floor. It may have moved. Check the constraint, then run the test suite on your PHP version in a canary app before fleet rollout.

Assume the route ships open until you've checked. Read the published config and route:list output before deploying to a shared environment. Retrofitting auth after the page has been crawled is unpleasant.

Silent staleness is the failure you'll actually experience. The page keeps rendering perfectly while showing last quarter's news, because nobody wired it into the release pipeline. This is a process failure, and the only fix is a CI assertion or a release-checklist item. A changelog page is only as good as the pipeline that feeds it.

Keep CHANGELOG.md in your repo root, never in vendor/. It must survive package removal — that is your entire fallback plan.

Bus factor is one. Single maintainer, both 13.0.0 PRs authored by the same person with no second reviewer. Acceptable at this blast radius because the replacement is genuinely small: a markdown parser, a route, and a Blade view is a day of work. Keep the content in plain Keep-a-Changelog markdown so a swap is mechanical.

Debugging order when the page misbehaves:

php artisan route:list | grep -i changelog   # is it registered?
php artisan config:clear                     # stale config is the #1 cause
php artisan view:clear                       # stale published Blade override

Then check the file path — relative paths resolve from the app base, not the config file — and file permissions. An empty page almost always means a malformed heading hierarchy or a path that resolves somewhere unexpected.

Extension points are the published views and the config. Override the Blade template rather than editing vendor files. If the parser is container-bound in the service provider, you can swap your own implementation without forking — worth checking if you need custom formatting, but don't build on that assumption without confirming it in the provider source.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console