Changelog - Version 7.0
Status: in development. This document tracks changes landing on the
7.0branch. Nothing here is released yet, and the contents may still change.
Breaking Changes
-
config/dev/03-api.phpbuilds the OpenAPISchemawithSchema::fromFile(). It usedSchema::getInstance(), which byjg/swagger-test 7.0 removes (deprecated since 6.0): a project created from an earlier template fails every API test withclass ByJG\ApiTools\Base\Schema does not have a method "getInstance"once it updates. Make the same change in the project:Schema::class => DI::bind(Schema::class)->withFactoryMethod('fromFile', [__DIR__ . '/../../public/docs/openapi.json'])->toSingleton(),fromFile()exists since swagger-test 6.0, so the change can be made before updating. -
byjg/swagger-test 7.0 also removes
assertRequest()(deprecated since 6.0), the former name ofsendRequest(). The template's tests already usesendRequest(); a project's own test that calls$this->assertRequest($request)must call$this->sendRequest($request).
Changes
-
The database server is the
gluo-databaseservice, indocker-compose.database.yml. It wasmysql-container(postgres-containerfor PostgreSQL) indocker-compose.yml, with fixedcontainer_names (resttest,mysql-container) that made every project created from the template claim the same names: a second project could not start while another one's containers existed, even stopped. Nowdocker-compose.ymlholds the API and the frontend and includesdocker-compose.database.yml, which holds the server of the database chosen (none for SQLite). Compose names the containers after the project (<project>-rest-1). Usedocker compose exec rest ...instead ofdocker exec resttest .... -
No
/etc/hostsentry for the database.config/devandconfig/testconnected tomysql-container, which the commands run on the host (./gluo,composer test) only reached with127.0.0.1 mysql-containerin/etc/hosts. They now connect to127.0.0.1, the published port, and therestservice setsDBDRIVER_CONNECTIONtogluo-databasefor the app in the container. The tests always use the test database:tests/bootstrap.phpkeeps the server of aDBDRIVER_CONNECTIONset in the environment and replaces its database with the test one (it ignores a SQLite one: the test file ofconfig/testapplies), so they run on the host, in therestcontainer (docker compose exec rest composer test) or in a CI job that sets the variable, and never on the dev database. -
composer create-projectno longer creates a git repository. The installer rangit initand made an "Initial commit", so a project created inside an existing repository (a monorepo, a demo with several apps) got a nested.gitto remove by hand. Rungit inityourself when the project is a repository of its own. The installer no longer asks for the git user name and email, and no longer needs git;git_user_nameandgit_user_emailinsetup.jsonare ignored. -
composer create-projectno longer leaves the starter's changelogs in the new project.CHANGELOG-*.mdare the history of this starter, not of the project being created, so the installer removes them, as it already did withdocs/. -
?orderBy=works on the list endpoints, and?filter=is gone. The example controllers (Project,Task,Note) documented both parameters and applied neither.orderByis now applied throughByJG\Gluo\Util\OrderBy::fromQueryString(), which only accepts fields of the model (?orderBy=name desc,id; anything else is a 400).filterwas removed from the OpenAPI attributes because it never had a defined format. See Filtering and Ordering. -
The frontend is published over HTTPS too.
docker-compose.ymlnow maps7443:8443on thefrontendservice, so the SPA answers on https://localhost:7443 with the self-signed certificatebyjg/static-httpservergenerates at start. HTTP on:7080is unchanged. See Frontend. -
./gluois the command-line entry point. It replaces the Composer scripts for the framework tasks and runs your own commands by a short name:New Was ./gluo --env=dev migrate:updatecomposer migrate -- --env=dev update./gluo --env=dev codegen:all --table=product --savecomposer codegen -- --env=dev --table=product all --save./gluo openapicomposer openapi./gluo terminalcomposer terminal./gluo user:cleanup 30scriptify run "\\MyApp\\Service\\MaintenanceService::cleanOldRecords" --arg 30The Composer scripts remain as aliases that call
./gluo, so existing pipelines keep working. Project commands are declared in the newsrc/Command/Commands.php, aByJG\Scriptify\CommandProviderthat the./gluoscript passes to the launcher, with class references (PaymentCommands::class) instead of strings. They run with the Gluo container, so a command's class gets its constructor dependencies../gluo list --checkvalidates every command without running it, and./gluo --env=prod install <command>installs one as a system service. See The gluo Command.Builder\Scriptslost its static Composer entry points (migrate,codeGenerator,genOpenApiDocs,checkOpenApi); therun*methods the launcher calls are unchanged. -
The config cache is set in
config/ConfigBootstrap.php.byjg/gluo-coreno longer caches the resolved container for staging and prod; the template now does it inconfigureDefinition(), with the sameFileSystemCacheEngineas before, so the behaviour doesn't change. Change it there if your deploy needs another cache (see Environment-Specific Caching). -
composer create-projectno longer copiesdocs/into the new project. The copy was frozen at creation time whilebyjg/gluo-corekeeps updating throughcomposer update, so it drifted out of date. The project now gets a shortREADME.mdwith a quick start, the common commands and links to the online documentation at https://opensource.byjg.com/docs/php/gluo/. The.claude/skills are still copied. -
The test namespace is
Tests\, notTest\.composer.jsonmapsTests\totests/, the classes undertests/and the documentation follow, andbyjg/gluo-coregenerates new tests inTests\Controller. A project created from an earlier template keeps working as it is; rename its namespace when you want the generated tests to match.
Bug Fixes
-
The Docker image copied
./gluoandcomposer.json"for the migration script", but notdb/, so./gluo migrate:updatein the image had no migrations to run. It now copiesdb/(a local SQLite database file in it stays out, through.dockerignore). -
A project created with
db_schemasqliteorpostgresdid not work: only the connection string changed. Now:- the project gets the SQL and the server of its database. The template keeps them in
.db-dialects/<mysql|postgres|sqlite>/(db/anddocker-compose.yml); the installer writes the set chosen todb/anddocker-compose.database.ymland removes.db-dialects/, so a project keeps onedb/base.sql, onedb/migrations/and one database server (none for SQLite); - a SQLite database is a file under
db/,sqlite://{__ROOT__}/db/<name>.sqlite, which works on the host and in Docker (it wassqlite:///<name>, a file at the filesystem root), and*.sqliteis ignored by git; - the staging and prod placeholder connections use the scheme of the database chosen;
- the questions use the user of the database chosen (
root,postgres), and SQLite is not asked for a host, user or password.
The installer offers
mysql,postgresandsqlite.sqlsrvis no longer offered: a project created with it could not run its migrations. The create-project CI job runs every database. This needs, from the libraries: byjg/anydataset-db (thepostgres://alias), byjg/migration (postgres://migrations), byjg/micro-orm (an empty key and "now" on PostgreSQL), byjg/authuser (user properties on PostgreSQL) and byjg/gluo-core (BaseApiTestCasepicking the database). - the project gets the SQL and the server of its database. The template keeps them in
-
An unattended setup that could not read its answers fell back to the questions, and so created the project with the default answers: a
SETUP_JSONnaming a file that is not there (a Composer running in a container sees only the directories mounted into it), or asetup.jsonthat is not valid JSON. Both now stop the setup with an error naming the file. -
A Composer running in a container (a dockerised
composer) warned that Docker is not installed and waited for ENTER, because the container has nodockercommand. Inside a container the setup now says Docker could not be checked, and goes on. -
A new project kept the starter's own
composer.jsondescription ("Runcomposer create-project byjg/gluo…", with the project's name in it). It is now "A PHP REST API built with Gluo." -
The installer rewrites
byjg/gluoto the project's composer name wherever the template names itself, and some comments about the framework saidbyjg/gluowhere they meantbyjg/gluo-core: a new project gotBaseUser (acme/shop)insrc/Model/User.php, and the same inLoginController.php. Those comments now namebyjg/gluo-core, which the rewrite leaves alone. -
src/Generator/UuidSeedGenerator.phpis removed. Nothing in the template used it, and it ran the MySQL-onlySELECT hex(uuid_to_bin(uuid())).TableUuidPKAttributegenerates UUID keys; for a seed function of your own, returnHexUuidLiteral::forDatabase($executor, HexUuidLiteral::v7()). -
composer create-projectwrote the package name twice when the chosen name started withbyjg/gluo(byjg/gluo-shopbecamebyjg/gluo-shop-shopincomposer.json). The installer now replaces only the template's exact name. Names with any other vendor or prefix were never affected. -
UserandTaskused micro-orm'sTableMySqlUuidPKAttribute, which asked MySQL foruuid_to_bin(uuid()), so every insert intousersortaskfailed on any other database. They now useTableUuidPKAttribute, which generates a version 7 UUID in PHP. A project created from an earlier template keeps working on MySQL; replace the attribute to run it elsewhere. -
The installer accepted only PHP 8.3, 8.4 and 8.5, although the project supports 8.6. It now accepts
8.6too (interactive prompt andphp_versioninsetup.json).
Requirements
- PHP 8.3, 8.4, 8.5 and 8.6 are now supported:
"php": ">=8.3 <8.7". The previous<8.6upper bound excluded PHP 8.6, since<8.6is exclusive. - The Docker image is based on
byjg/php:8.5-fpm-nginx-2026.10(was2026.06). The installer replaces the PHP version in that tag, and2026.06was never published for 8.6;2026.10exists for 8.3, 8.4, 8.5 and 8.6.
ByJG dependencies
byjg/gluo-coreis now^7.0.byjg/scriptifyis now^7.0.
While 7.0 is unreleased these resolve to 7.0.x-dev from each component's
7.0 branch, via minimum-stability: dev with prefer-stable: true.
Toolchain
-
PHPUnit updated to
^12.5. -
Psalm is installed as
psalm/pharinstead ofvimeo/psalm.vimeo/psalmlists the PHP versions it supports and no published release includes 8.6, so as a dev dependency it madecomposer installfail on the 8.6 build job before any test ran.psalm/pharrequires onlyphp ^8.2and bundles its own dependencies, so it installs on every PHP version in the matrix and cannot conflict with the project's. Psalm itself still refuses to run on 8.6, which is why the Psalm job uses 8.5.composer psalmruns it. -
PHPUnit 13 is deliberately not used. It requires PHP
>=8.4.1, breaking the 8.3 floor.
Continuous Integration
- The build matrix now includes PHP 8.6.
- The Psalm job runs on PHP 8.5.
Housekeeping
- In this repository,
docker-compose.yml,docker-compose.database.yml,db/base.sqlanddb/migrations/are no longer versioned:./gluo --env=dev db:dialect <mysql|postgres|sqlite>writes them from.db-dialects/, the only place to change them. The command and.db-dialects/are removed from a created project. The CI runs the command before the tests and before building the image. phpunit.xml.distrenamed tophpunit.xml..vscode/launch.jsonis removed, and.vscodeis ignored by git.