Upgrading
Stewart is one version for everything: the packages in composer.json, the runtime image, and the Home Assistant
integration. Upgrade them together.
How to upgrade
Section titled “How to upgrade”- Read the notes for every version between yours and the new one, below and in the changelog.
- On your machine, run
make updatefor the newest release of your version, ormake upgrade VERSION=x.yto move to another version.make upgradealso changes the image tags inDockerfileand the compose files. - Run
make generate,make stanandmake test, and follow the notes. - Commit
composer.lockand the changed files, and deploy as usual. - If you use the Stewart integration in Home Assistant, update it to the same version.
Within a major version, such as 1.x, a new release does not break your apps. Notes appear here only when a release asks you to do something.
Upgrade notes
Section titled “Upgrade notes”-
Run
make upgrade VERSION=1.8, then restart Stewart (make up,make deployor a new image). The control and worker protocols are unchanged, and so is the Home Assistant integration’s. -
Run
make generate. The generated classes of 1.7 and earlier callcallService(), so until they are regenerated every generated call prints a deprecation line in the log, andmake statussays the classes are of an older format. -
Move your apps and tests to the action names. This rewrites the calls whose names are written out;
make stanthen points at the rest, such as names held in a variable:Terminal window grep -rlE 'callService|stubService|getServiceName' apps tests | xargs sed -i -E \-e "s/->callService(ForResponse)?\('([a-z0-9_]+)', *'([a-z0-9_]+)'/->callAction\1('\2.\3'/g" \-e "s/->stubService(Answer|Failure)\('([a-z0-9_]+)', *'([a-z0-9_]+)'/->stubAction\1('\2.\3'/g" \-e 's/->callService(ForResponse)?\(/->callAction\1(/g' \-e 's/->getServiceName\(\)/->getActionName()/g' -
To have
make stancheck entity IDs and action names, add the PHPStan extension frommake sh; new projects from the skeleton have it:Terminal window composer config allow-plugins.phpstan/extension-installer truecomposer require --dev stewart-php/phpstan:^1.8 phpstan/extension-installer -
On Kubernetes with
adminApi.podMonitor.enabled, switch tometrics.enabled: trueandmetrics.podMonitor.enabled: true, and turnadminApi.podMonitoroff. If Prometheus was the only reason foradminApi.host: 0.0.0.0, set it back to127.0.0.1. -
The
TEMPLATEvariable ofmake appreaches only new projects. To use it, copy theapptarget from the skeleton’s Makefile.
- Run
make upgrade VERSION=1.7, then restart Stewart (make up,make deployor a new image). The control protocol is now 33: until the daemon runs 1.7,make statusand the other control targets refuse to talk to it. The Home Assistant integration’s protocol is unchanged. - Stewart 1.7 needs PHP 8.5.12. The runtime image already runs it, so
make pullis enough; a project that runs Stewart outside the image updates PHP first. - Log lines name their source after the level, such as
INFO [porch-light] …. Anything that parses line logs needs to allow for the tag; JSON logs only gainextra.source. - The new Makefile variables reach only new projects. To use them, copy
TRACEonrun,watchanddebug, andAPPandWATCHonstatus, from the skeleton’s Makefile.
- Run
make upgrade VERSION=1.6, then restart Stewart (make up,make deployor a new image). The control protocol is now 30: until the daemon runs 1.6,make statusand the other control targets refuse to talk to it. The Home Assistant integration’s protocol is unchanged. - The new targets reach only new projects. To use them, copy
reloadandwatchfrom the skeleton’s Makefile. docker compose kill -s HUP stewartnow reloads Stewart instead of stopping it, also in Git mode.
- Apps without
worker:can move to another worker once, so theworkerlabel of their metrics changes. If dashboards or alerts rely on it, runmake checkbefore upgrading, note each app’s worker, and pin it withapps.<id>.worker. - Run
make upgrade VERSION=1.5. Protocols are unchanged, so a 1.4 daemon,stewartCLI and Home Assistant integration work with 1.5. - Run
make check. It now builds every app, so it can name a problem that used to show only when the app started, and a Git deploy rejects a commit until it passes. - Delete the empty
dispose()from your apps;make checknames each app that still has one. Wheredispose()does something, addimplements Disposable(use Stewart\Contracts\Disposable;). An app that marksdispose()with#[\Override]does not load until you do one or the other. - The new deploy and CI steps reach only new projects. To use them, copy the
deploytarget from the skeleton’s Makefile, andci.ymlandimage.ymlfrom its workflows. CI checks the settings in.env.example, so keep it listing every setting your apps need.
- Run
make upgrade VERSION=1.4. Protocols are unchanged, so a 1.3 daemon,stewartCLI and Home Assistant integration work with 1.4. - The new Makefile targets reach only new projects. To use them, copy
check,app,app-pause,app-resume,app-reset,worker-restartand therequiredline from the skeleton’s Makefile; there,doctorruns with$(RUN_APP)andsetuprunsstewart doctor --offline. - To make Valkey optional, first add
COMPOSE_PROFILES=storeto.envnext toSTEWART_PERSISTENCE__URL. Then addprofiles: [store]to thevalkeyservice andrequired: falseunderdepends_on: valkey:incompose.yamland in any deploy compose file you copied. With the profile but without the.envline, Valkey no longer starts. - An existing
HelloAppkeeps working; nothing changes for it.
- Run
make upgrade VERSION=1.3. Protocols are unchanged, so a 1.2 daemon,stewartCLI and Home Assistant integration work with 1.3. - For
host.docker.internalwithmake up, addextra_hosts: ["host.docker.internal:host-gateway"]to thestewartservice incompose.yaml, and in any deploy compose file you copied. - Memory now reads higher, since it counts the whole process; raise alerts on
stewart_broker_memory_bytesandstewart_worker_memory_bytesto match.
- Run
make upgrade VERSION=1.0. Protocols are unchanged, so a 0.11 daemon,stewartCLI and Home Assistant integration work with 1.0. - Change the image tag in
Dockerfileand the compose files fromruntime:1.0toruntime:1(1-devincompose.dev.yaml), so the image keeps getting PHP and Alpine fixes after 1.1. Copybin/upgrade-stewart.shfrom the skeleton so later upgrades do the same.
Before 1.0
Section titled “Before 1.0”Each 0.x version could break apps; these notes are kept for old projects.
- Run
make upgrade VERSION=0.11, thenmake generate. Upgrade the daemon, thestewartCLI and the Home Assistant integration together; older versions refuse to talk to 0.11. - Replace
->whenChangedTo('on')->from('off')with->whenChangedTo('on', from: 'off'), and->fromAnyState()withfromAnyState: true. - Replace
runAtSunrise()andrunAtSunset()withrunAtSunEvent(SunEvent::Sunrise, …)orSunEvent::Sunset. - Replace an injected
StewartIdentitywith$ha->wasCausedByStewart($change). - Replace removed exception factories with
createForReason(),fromWire()withrestoreFromWire(), and removed collection factories such asfromIds()withfromList(). - Import classes that moved out of
stewart-php/contractsfromStewart\Support\…. - Custom implementations of
Timers,EventStream,HaContextorEntityExposureadd the new methods. - An app option variable ending in
_FILEis now read as a file; set the option instewart.yamlto keep passing the path itself.
- Run
make upgrade VERSION=0.10. Control and IPC protocols are unchanged, but broker, workers andstewartcommands should all run 0.10. - Update the
stewartintegration to 0.10.0 in Home Assistant. - Optionally take over the skeleton’s
.github/workflows/*.ymlandDockerfilechanges.
- Run
make upgrade VERSION=0.9. Broker, workers andstewartcommands must all run 0.9;stewart statusagainst a 0.8 daemon is refused (control protocol 28). - Install the
stewartintegration 0.9.0 in Home Assistant 2026.4 or newer before an app callsexpose*(); without it,expose*()throwsExposureException. Apps that expose nothing need no integration. - Daemons sharing one Home Assistant set a different
expose.instanceeach.
- Run
make upgrade VERSION=0.8. Broker, workers andstewartcommands must all run 0.8;stewart statusagainst a 0.7 daemon is refused (control protocol 24). - A git deployment whose
composer.lockstill holds runtime 0.7 setscode.git.poll: off(or dropsSTEWART_DEPLOY__GIT__POLLfromcompose.git.yaml) until it upgrades; 0.7 stops on the unknown variable. - A compose git volume from 0.7 is converted on the first start: the old checkout is removed and the release layout created, with one full dependency install.
- Code calling
BrokerLifecycle::run()directly gets aBrokerStopOutcomeback instead of nothing.
- Run
make upgrade VERSION=0.7. Broker, workers andstewartcommands must all run 0.7. - Code that constructs
StateChangesorStateTransitionsdirectly now passes aCurrentStateReader. - Custom
ClockandSchedulerimplementations addisWithin()andrunAtEntityTime(). - Tests comparing whole
EntityStateobjects fromRecordingHaContextwithassertEqualsnow see the stampedlastChangedAtandlastUpdatedAt.
- Run
make upgrade VERSION=0.6. Broker, workers andstewartcommands must all run 0.6. - Rename any app whose id is longer than 100 characters.
- On Kubernetes, the chart now probes port 8080 (
probes.port); setprobes.mode: execto keep exec probes.
- Run
make upgrade VERSION=0.5. Broker and workers must both run 0.5 (IPC protocol 21). - Run
make generate.
- Add
->fromAnyState()after anywhenChangedTo()that must also fire when an entity comes back fromunavailableorunknown. - Run
make generate.
- Remove
codegen.renamefromstewart.yamland anySTEWART_CODEGEN__RENAMEfrom.env; both are now refused. - Run
make generate. - Replace
$entities-><domain>-><entity>with$entities-><domain>->getEntity('<entity id>').
To make life easier in long term, I added an upgrade script, that script needs to be added manually, later on upgrades can be made by executing only one make target.
-
Fetch the upgrade script and keep it out of the production image:
Terminal window mkdir -p bincurl -fsSLo bin/upgrade-stewart.sh \https://raw.githubusercontent.com/stewart-php/skeleton/v0.2.0/bin/upgrade-stewart.shecho bin >> .dockerignore -
Add the target to your
Makefile, next toupdate; the recipe lines start with a tab:.PHONY: upgradeupgrade: ## Move to another Stewart release line, then pull its images and install it [VERSION=0.2]$(RUN) sh bin/upgrade-stewart.sh $(VERSION)$(DEV) pull$(RUN) composer update 'stewart-php/*' --with-all-dependencies --no-interaction -
To use MQTT, add
"stewart-php/mqtt": "^0.2"torequireincomposer.json. -
Upgrade. This points every
stewart-php/*requirement and runtime image tag at 0.2, pulls the images and installs:Terminal window make upgrade VERSION=0.2 -
If you added MQTT, set
STEWART_MQTT__URLin.env, such asmqtt://user:password@homeassistant.local:1883, and check themqttsection withmake config. Without the URL nothing changes. -
Check it with
make doctorandmake run. On the server, commit and push, then runmake deploy.