Versioning and releases¶
The version number tells you whether an upgrade can break your application, and the changelog tells you what to do about it. This page states both promises, and how a release is actually cut.
What a version number promises¶
Griglia follows semantic versioning. It is still on 0.x, where the rules shift by one
position:
Part of 0.MINOR.PATCH |
Changes when | Can it break you? |
|---|---|---|
MINOR |
features, and anything that changes the public surface | yes — read the changelog before bumping |
PATCH |
fixes, documentation, internals | no |
So pin the minor you have tested ("alle80/griglia": "^0.89.0") and treat a minor bump as a small upgrade
project: the upgrade runbook is the procedure.
There is no 1.0 date. It arrives when the public surface below stops moving, not on a schedule.
What counts as public¶
A change to any of these is breaking, and lands in a minor:
- Configuration keys in
config/griglia.phpand the settings of theagent,appandoptimizationgroups — see Configuration file and Settings. - Artisan commands: their names, arguments and options — see Artisan commands.
- Published files: views, language files, scripts and precompiled assets, and the tags that publish them.
- Extension hooks: the access gate, the user model,
Mode, the registered routes and their names. - The
TodoChangedevent and its payload — see Events and broadcasting. - Database tables and columns the host application can read.
Everything else — classes with no documentation page, internal helpers, CSS internals, the shape of a Blade partial — is internal and may change in a patch. If you depend on an internal, say so in an issue: an extension point is cheaper for both of us than a private fork.
Deprecations are announced under Deprecated in the changelog and, whenever the change allows it, keep working for one more minor before they go.
Supported versions¶
Only the newest minor is supported: fixes go on top of it, there are no backports to older 0.x lines. The
reasoning is on Governance.
The changelog is the release¶
Every release is described once, in CHANGELOG.md,
in Keep a Changelog format. Nothing restates it: the GitHub Release is
generated from that section by .github/workflows/release.yml, so a release cannot end up described in two
different ways.
The link definitions that close the file are generated too:
php .github/scripts/changelog-notes.php --links # print the whole [x.y.z]: …/compare/… block
php .github/scripts/changelog-notes.php --links --write # write it back at the end of the changelog
php .github/scripts/changelog-notes.php 0.89.12 # the notes for one version, as published
ReleaseProcessTest fails when the block no longer matches, so it cannot silently rot.
Cutting a release¶
Four manual steps, then GitHub takes over.
# 1. Move the Unreleased entries under a heading of their own, dated today.
# ## [0.90.0] - 2026-08-23
php .github/scripts/changelog-notes.php --links --write # 2. refresh the link block at the end of the file
npm run build # 3. only when CSS, JS or views changed
composer qa # 4. lint, suite, generated reference pages
git tag v0.90.0 && git push origin master v0.90.0
Pushing the tag triggers everything else:
| Then | Who |
|---|---|
| the version appears on Packagist | the Packagist hook on the repository |
| a GitHub Release appears with the changelog notes and a compare link | release.yml |
| the documentation site is rebuilt | docs.yml |
A tag whose version has no changelog section fails the release workflow instead of publishing an empty release. To republish notes for a tag already out there, run the release workflow by hand with that tag.
Where the source lives¶
alle80/griglia is a publishing mirror. The package is developed inside the application monorepo that
uses it, under src/packages/griglia, and a release script mirrors that directory onto master, tags it and
pushes. The script refuses to run when master carries versions or files the source does not have, so a
release cannot quietly delete work that arrived from somewhere else.
For a contributor this changes nothing: branch from master, open the pull request there, and it is reviewed
and merged there. What it adds is a maintainer step — carrying the merge back into the monorepo before the
next release — and it is the reason master shows tags and merges rather than a long day-to-day history.
Repository metadata¶
Description, homepage, topics, the feature switches and private vulnerability reporting are not in the code,
so they drift without anybody noticing. They live in
.github/repository.json, and a
script writes them:
php .github/scripts/repo-metadata.php # what differs from the live repository
php .github/scripts/repo-metadata.php --apply # write the file to GitHub, needs `gh auth login`
The description there and the one in composer.json are the same sentence, because GitHub and Packagist are
the two places a stranger reads first; a test fails when they drift apart.
The social preview is the exception: GitHub has no API for it. After changing
docs/images/social-preview.png (1280×640 PNG) upload it once from Settings → General → Social preview.
The same image is the og:image of every page of this site, through overrides/main.html.
See also¶
- Contributing — the change itself: tests, changelog entry, pull request.
- Quality standards — the bar every release has already cleared.
- Upgrade Griglia safely — the other side of a minor bump.