Skip to content

Upgrading

Stewart is one version for everything: the packages in composer.json, the runtime image, and the Home Assistant integration. Upgrade them together.

  1. Read the notes for every version between yours and the new one, below and in the changelog.
  2. On your machine, run make update for the newest release of your version, or make upgrade VERSION=x.y to move to another version. make upgrade also changes the image tags in Dockerfile and the compose files.
  3. Run make generate, make stan and make test, and follow the notes.
  4. Commit composer.lock and the changed files, and deploy as usual.
  5. 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.

  1. Run make upgrade VERSION=1.0. Protocols are unchanged, so a 0.11 daemon, stewart CLI and Home Assistant integration work with 1.0.
  2. Change the image tag in Dockerfile and the compose files from runtime:1.0 to runtime:1 (1-dev in compose.dev.yaml), so the image keeps getting PHP and Alpine fixes after 1.1. Copy bin/upgrade-stewart.sh from the skeleton so later upgrades do the same.

Each 0.x version could break apps; these notes are kept for old projects.

  1. Run make upgrade VERSION=0.11, then make generate. Upgrade the daemon, the stewart CLI and the Home Assistant integration together; older versions refuse to talk to 0.11.
  2. Replace ->whenChangedTo('on')->from('off') with ->whenChangedTo('on', from: 'off'), and ->fromAnyState() with fromAnyState: true.
  3. Replace runAtSunrise() and runAtSunset() with runAtSunEvent(SunEvent::Sunrise, …) or SunEvent::Sunset.
  4. Replace an injected StewartIdentity with $ha->wasCausedByStewart($change).
  5. Replace removed exception factories with createForReason(), fromWire() with restoreFromWire(), and removed collection factories such as fromIds() with fromList().
  6. Import classes that moved out of stewart-php/contracts from Stewart\Support\….
  7. Custom implementations of Timers, EventStream, HaContext or EntityExposure add the new methods.
  8. An app option variable ending in _FILE is now read as a file; set the option in stewart.yaml to keep passing the path itself.
  1. Run make upgrade VERSION=0.10. Control and IPC protocols are unchanged, but broker, workers and stewart commands should all run 0.10.
  2. Update the stewart integration to 0.10.0 in Home Assistant.
  3. Optionally take over the skeleton’s .github/workflows/*.yml and Dockerfile changes.
  1. Run make upgrade VERSION=0.9. Broker, workers and stewart commands must all run 0.9; stewart status against a 0.8 daemon is refused (control protocol 28).
  2. Install the stewart integration 0.9.0 in Home Assistant 2026.4 or newer before an app calls expose*(); without it, expose*() throws ExposureException. Apps that expose nothing need no integration.
  3. Daemons sharing one Home Assistant set a different expose.instance each.
  1. Run make upgrade VERSION=0.8. Broker, workers and stewart commands must all run 0.8; stewart status against a 0.7 daemon is refused (control protocol 24).
  2. A git deployment whose composer.lock still holds runtime 0.7 sets code.git.poll: off (or drops STEWART_DEPLOY__GIT__POLL from compose.git.yaml) until it upgrades; 0.7 stops on the unknown variable.
  3. 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.
  4. Code calling BrokerLifecycle::run() directly gets a BrokerStopOutcome back instead of nothing.
  1. Run make upgrade VERSION=0.7. Broker, workers and stewart commands must all run 0.7.
  2. Code that constructs StateChanges or StateTransitions directly now passes a CurrentStateReader.
  3. Custom Clock and Scheduler implementations add isWithin() and runAtEntityTime().
  4. Tests comparing whole EntityState objects from RecordingHaContext with assertEquals now see the stamped lastChangedAt and lastUpdatedAt.
  1. Run make upgrade VERSION=0.6. Broker, workers and stewart commands must all run 0.6.
  2. Rename any app whose id is longer than 100 characters.
  3. On Kubernetes, the chart now probes port 8080 (probes.port); set probes.mode: exec to keep exec probes.
  1. Run make upgrade VERSION=0.5. Broker and workers must both run 0.5 (IPC protocol 21).
  2. Run make generate.
  • Add ->fromAnyState() after any whenChangedTo() that must also fire when an entity comes back from unavailable or unknown.
  • Run make generate.
  1. Remove codegen.rename from stewart.yaml and any STEWART_CODEGEN__RENAME from .env; both are now refused.
  2. Run make generate.
  3. 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.

  1. Fetch the upgrade script and keep it out of the production image:

    Terminal window
    mkdir -p bin
    curl -fsSLo bin/upgrade-stewart.sh \
    https://raw.githubusercontent.com/stewart-php/skeleton/v0.2.0/bin/upgrade-stewart.sh
    echo bin >> .dockerignore
  2. Add the target to your Makefile, next to update; the recipe lines start with a tab:

    .PHONY: upgrade
    upgrade: ## 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
  3. To use MQTT, add "stewart-php/mqtt": "^0.2" to require in composer.json.

  4. 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
  5. If you added MQTT, set STEWART_MQTT__URL in .env, such as mqtt://user:password@homeassistant.local:1883, and check the mqtt section with make config. Without the URL nothing changes.

  6. Check it with make doctor and make run. On the server, commit and push, then run make deploy.