As we are nearing the date of 4.0.0 alpha2, and are getting ready to prepare for 4.0.0 stable, there has been a lot of discussion regarding the release process of the SilverStripe core, as well as the way that we version and manage dependencies.
The problem
In 4.0.0 we have introduced a new module (so far),
https://github.com/silverstripe/silverstripe-asset-admin/ which is currently not versioned as `self.version`, as in fact the current version is 1.0.0-alpha1. As we continue to split the silverstripe core into independent components, we are looking to tie less and less into a single versioning system, thus the demand for a new versioning and release process has become apparent.
Yet another issue we have struggled with is inter-dependency between modules; Releasing a new version of one module requires a release of all other core modules to simply satisfy the self.version dependency. For modules such as reports or siteconfig, which rarely change, this is highly unnecessary.
We also run into issues where the installer project doesn't quite match the desired configuration; We currently release both with-cms, and framework only distributions of installer, normally involving manual changes in order to generate the framework-only version. What we are looking to potentially do in future releases is to include groups of complementary modules as "recipes", which are typically 1-6 modules with a set of default configuration.
The proposal
My proposal is to do away with the silverstripe/installer, as it's far too limited and rigid, and to instead introduce a new module type; `silverstripe-recipe`. A recipe is a library which may EITHER be installed directly via `composer create-project`, but also can be composed into other recipes which may extend on them.
I've built a proof of concept of how a recipe system could work; By generating a tractorcow/recipe-core module (representing a framework-only recipe), and a tractorcow/recipe-cms module (representing a standard recipe with cms and asset admin).
The repos for these are:
This system is supported by a custom composer plugin built to manage project-assets.
https://github.com/tractorcow/recipe-plugin. Any recipe may declare a "project-files" option, which is a list of files (or file wildcards) which represent files which should be copied to the project root, and should be modified directly by the developer. These files are only copied once, when the module is added for the first time. This means that assets between recipes are not duplicated, and allows recursive inheritance of other recipe assets.
Instead of declaring 'self.version' as the dependency module, recipes will be locked to specific versions. E.g. `4.0.0`. The intent is that we would control installed version via branch-alias tags in source control (e.g. alias dev-master as 4.0.0), as well as the `minimum-stability` in recipe composer.json. We would update our release process to automate the increment of these versions so that "everything works" while doing rapid releases.
In the future
Another feature that I had discussed with Sam earlier was the need to shift dependency management up into the top level composer.json. The intent is that once a recipe is declared, they should be able to be installed "inline", which means that rather than a single require being added to your root composer.json when pulling in a new recipe, the recipe will actually copy its own dependencies up into the top level. Similar to how top-level project files are installed in this proof of concept, this should give developers much greater fine-level control over which parts of any recipe make its way into a project. Not every part of a recipe is always necessary, and the ability to remove sub-components is just as important as the ability to add them.
E.g. a theoretical command `composer add-recipe silverstripe/recipe-blog` would:
- copy a default `blog.yml` into mysite/_config/
- install a set of dependency modules (blog, lumberjack, comments)
- Add installed dependencies to the root composer.json require
We could also include `composer upgrade-recipe` to perform incremental upgrades.
Testing it out
You can test out the proof of concepts for core and cms with the following commands:
composer create-project tractorcow/recipe-core ./recipe-test-coreonly dev-master
Or
composer create-project tractorcow/recipe-cms ./recipe-test-cms dev-master
Please let me know what you think. :D
Kind regards,
Damian