Releasing
This repository is the only place Stewart is developed. Everything else is published from it.
| Artifact | Where | Built by |
|---|---|---|
stewart-php/{contracts,support,client,store,store-redis,mqtt,sun,runtime,codegen,testing} |
Read-only stewart-php/<name> repositories, Packagist |
split.yml |
stewart-php/skeleton |
Read-only stewart-php/skeleton (a GitHub template repository), Packagist |
split.yml |
| Home Assistant integration | Read-only stewart-php/hass-stewart, its releases carry stewart.zip for HACS |
split.yml |
ghcr.io/stewart-php/runtime, …-dev |
GHCR, linux/amd64 and linux/arm64 | release.yml, rebuild.yml via runtime-image.yml |
oci://ghcr.io/stewart-php/charts/stewart |
GHCR | release.yml |
| Release notes | GitHub releases | release.yml, from CHANGELOG.md |
| Documentation | stewart-php.github.io/docs and /docs-dev, from stewart-php/stewart-php.github.io |
docs.yml |
Versioning
Section titled “Versioning”- Lockstep. One version for every package, the image, the chart, the skeleton and the Home Assistant
integration. A tag
vX.Y.Zreleases all of them, even the ones that did not change. Packages require each other withself.version, so an installation never mixes versions. - Semver. Only a major release breaks, and its changelog section has an “Upgrading” part. The public surface is
what apps code against:
stewart-php/contracts, the generated classes, configuration keys, environment variables, console commands and the image entrypoint settings.make bc-checkguards the PHP part. - Trunk and tags. Releases are cut from
main. A fix for an older minor is not backported; upgrade instead. - Branch alias.
dev-mainisX.x-devfor the current major; at a new major change it in everypackages/*/composer.json, the root path repository’sversions,PackageManifestTest::BRANCH_ALIAS,bin/test-package.shandbin/bc-check.shtogether.
Image tags
Section titled “Image tags”The runtime image holds PHP, the extensions, Composer, git and the entrypoint; a project’s composer.lock decides the
framework version. Its tags follow the release:
X.Y.ZandX.Y.Z-dev: the release as built, never changed afterwards.X.YandX.Y-dev: the latestX.Y.Z.rebuild.ymlrebuilds only the latest release every week, so an older minor’s tag stops getting PHP and Alpine fixes.XandX-dev: the latest minor of a major, rebuilt every week. Projects use these.- No
latest, and no rolling0.
The image uses the newest PHP minor that CI proves (PHP_VERSION in .docker/php/Dockerfile). Move it only in a
minor release, after make check is green on that PHP in CI, and say so in the changelog.
Cutting a release
Section titled “Cutting a release”- Move the
Unreleasedentries inCHANGELOG.mdunder## [X.Y.Z] - YYYY-MM-DD. When projects have something to change, add “Upgrading” notes. - For a new minor, point the skeleton at it:
^X.Yfor thestewart-php/*requirements inskeleton/composer.json. For a new major, alsoghcr.io/stewart-php/runtime:X(X-devincompose.dev.yaml) inskeleton/Dockerfile,skeleton/compose.yaml,skeleton/compose.dev.yamlandskeleton/deploy/compose.git.yaml.release.ymlrefuses a tag that does not match. - Set
versioninintegrations/home-assistant/custom_components/stewart/manifest.jsontoX.Y.Z;release.ymlrefuses a tag that does not match. - Commit and
git push origin main, then wait forCIto pass on that commit. - Tag and push the tag:
git tag -s vX.Y.Z -m vX.Y.Z && git push origin vX.Y.Z.release.ymlrefuses a commit without a passingCIrun; once CI passes, re-run the failed jobs instead of moving the tag. It runs theDistributionchecks before it builds the image, and the image is scanned before it is tagged and signed. - Watch
Split,ReleaseandDocs. When they are green,composer create-project stewart-php/skeletonin a scratch directory should installX.Y.Z, andstewart-php/hass-stewartshould have anX.Y.Zrelease withstewart.zip, andhttps://stewart-php.github.io/docs/should show the new version’s pages.
A broken release is fixed by a new patch release, never by moving or deleting a tag.
One-time setup
Section titled “One-time setup”Done once, by an owner of the stewart-php organization, before v0.1.0.
- Repositories. Create
client,codegen,contracts,mqtt,runtime,store,store-redis,sun,support,testing,skeletonandhass-stewartunderstewart-php, each empty, with issues, wiki and projects off. Their description says they are read-only splits. Markskeletonas a template repository. Givehass-stewartthe topicshome-assistant,hacsandintegration, which HACS validation checks. - Split token. Create a GitHub App owned by
stewart-phpwith Contents and Workflows: read and write (every split carries.github/workflows), install it on those twelve repositories, then add its client ID as the variableSPLIT_APP_CLIENT_IDand its private key as the secretSPLIT_APP_PRIVATE_KEYin this repository. Until the variable exists,Splitis skipped. - Packagist. Run
Splitfrom the Actions tab so it fills the repositories. Then submit each of the eleven PHP ones on packagist.org under thestewart-phpvendor and enable the GitHub hook. Optionally, addPACKAGIST_USERNAME(variable) andPACKAGIST_TOKEN(secret) sosplit.ymlalso triggers an update itself. - GHCR. After the first release, open the
runtimeandcharts/stewartpackages in the organization’s packages, make them public, and link them to this repository. - Docker Hub. Create a read-only Docker Hub access token, then add the username as the variable
DOCKERHUB_USERNAMEand the token as the secretDOCKERHUB_TOKEN; image builds log in with them so Docker Hub’s anonymous rate limit does not fail them. - Runners.
ubuntu-24.04-armrunners must be available to the organization; they are free for public repositories. - HACS. Until
hass-stewartis in the HACS default store, users add it as a custom repository (category Integration); its README says how. - Documentation site. Create the public repository
stewart-php/stewart-php.github.iowith amainbranch holding a.nojekyllfile and a placeholderindex.html. In its settings, set Pages to deploy from themainbranch, root folder. Install the split GitHub App on it too (it needs Contents: read and write). Never create astewartdirectory there:stewart-php.github.io/stewart/belongs to this repository’s quality reports. Then run Docs by hand once. - Optional. List the chart on Artifact Hub (
oci://ghcr.io/stewart-php/charts/stewart).
Documentation
Section titled “Documentation”help/upgrading.mdin the user docs is generated from the “Upgrading” sections ofCHANGELOG.md. After editing them, runmake docs-reference;make test-docsfails until you do.docs.ymlbuilds both sites from the release tag and pushes them intodocs/anddocs-dev/ofstewart-php/stewart-php.github.io. It keeps the site root (a landing page),/docs/<major>.x/and/docs/next/.- Every push to
mainthat changesdocs/publishes the user docs ofmainto/docs/next/, with a banner andnoindex;make docs-build-nextbuilds it locally. - A docs-only fix after a release: merge it, then run Docs by hand with the ref to publish (empty means the
latest tag;
mainpublishes unreleased docs, so only do that on purpose). - At a new major, before its first publish: copy the current
docs/of the site repository todocs/<old>.x/, add a note on its pages that they describe an old version, and commit it. Then tag the release.
Verifying a published release
Section titled “Verifying a published release”cosign verify ghcr.io/stewart-php/runtime:X.Y.Z \ --certificate-identity-regexp 'https://github.com/stewart-php/stewart/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comdocker buildx imagetools inspect ghcr.io/stewart-php/runtime:X.Y.Z --format '{{json .Provenance}}'helm show chart oci://ghcr.io/stewart-php/charts/stewart --version X.Y.Z