Move a project to a new train
A new train moves core, every module and every theme at once. Most of the work is reading the plan before anything changes.
Before you start
Commit what you are working on. The project repository tracks grim.json, grim.lock and whatever you added to the allowlist in .gitignore. Core and the modules are rebuilt from the lock, so the trace an update leaves in git is the diff of grim.lock. Mixed with your own changes, that diff says nothing.
Bring the stack up. After a train change grim runs composer install and the migrations in the running app container. With the stack down it skips both and leaves them to you.
$ git status --short
$ grim upThe ritual, in order
Six steps. Only the fourth changes the project.
Update grim itself
The infrastructure templates of step five come from the grim on this machine, and so does the logic that decides what an update removes. Take the newest release first with
grim self-update.$ grim self-updateRead the plan
Nothing is written. The dry run of
grim updatechecks that every package can be installed, resolves the train, and prints what would move and what would be removed.$ grim update --dry-run Train 2.4 → 2.5 available (core 2.5.0) core 2.4.2 → 2.5.0 (2.5.*) cart 2.4.0 → 2.5.0 (~2.0) theme/admin:float 2.4.1 → 2.5.0 (~2.0) Would remove tests/Feature/LegacyHealthTest.phpWhen it prints
Everything is up to date on train 2.4.instead, the project is already on the newest train itscoreconstraint allows. A constraint such as2.4.*pins one train on purpose. Change it ingrim.jsonto move on.Decide what the plan turned up
Four kinds of line around the table need a person. Everything else is automatic.
Line Decide Would remove …A file core dropped, unchanged in your project. It goes. If your code still uses it, copy what you need somewhere of your own now. Kept … modified locallyCore dropped it, you had edited it, so it stays. Keep it as yours, or delete it by hand. … left core in train …A whole module is no longer part of core. Nothing is deleted. Add it to grim.jsonwithgrim require, or take it out withgrim remove.⚠ module … has no release on train …Everything else moves and that module stays where it is. Wait for its release, or go on without it and update it later. Board the train
The same plan, applied. Every removed file is named as it goes, the modules and themes are checked out at their new tags, the lock is written, and the app container runs
composer installand the migrations.$ grim updateIf a checkout would overwrite untracked files inside a module, the update stops, lists them and asks. Read the list before you answer.
Renew the infrastructure files
grim updatenever touches the Docker files. They come from the templates of the grim you updated in step one, andgrim upgradewrites them.$ grim upgrade $ grim down $ grim upThe managed files are overwritten without a question, without a backup and without a preview.
docker-compose.ymland the other files you own are left alone. The restart makes the containers read the new files. A managed file you once edited by hand is back to the template now, unless you had put it on the.gitignoreallowlist and can restore it from git.Test, then commit the lock
The lock is the record of what this project runs. Commit it once
grim testagrees.$ grim test $ git diff grim.lock $ git add grim.json grim.lock $ git commit -m "chore: move to train 2.5"
What you have now
A lock that names the new train, and a project whose files match it, minus what core no longer ships.
{
"train": "2.5",
"core_version": "2.5.0",
"modules": {
"cart": { "version": "2.5.0" }
}
}Your colleagues get the same versions from git pull and grim install, which lands what the lock records. Nothing is deployed yet. The train reaches a server the way every change does, as a new image.
When it does not work
A package cannot be installed
The update stops before it touches anything and lists every package it cannot have. An archived module usually says what replaced it. Often that is core itself, and then the module comes out of grim.json. A private one means your GitHub account lacks access to it.
“Cannot read the grim-core … tree”
Cannot read the grim-core 2.4.2 tree (…) — nothing removed. means grim could not look up the core release the lock names, typically with a lock written before trains existed. The train still landed. Nothing was deleted, so files core no longer ships stay in the project until you remove them by hand. The next update, from the lock this one wrote, removes normally.
“Environment is down”
Environment is down — run `grim up` to apply composer and migrations. means the stack was not running, so both were skipped. grim up alone does not catch up: on your machine it installs Composer packages only into an empty vendor/ and never migrates. Run the three commands.
$ grim up
$ grim composer install
$ grim artisan migrateThe suite fails on the new train
There is no downgrade command, and an older train gets no fixes. The way out is forward. Find the module the failure lives in with grim why, report it or fix it, and take the patch release when it lands, which is the recipe Take one module fix mid-train.
Do not edit versions in grim.lock by hand to hold one module back. grim ignores a locked version from another train, and a module from one train against the core of another is the breakage trains exist to prevent.
Next recipe
Take one module fix mid-train
Read the one-row plan, move a single module to its newest release on the train the project is locked to, run its migrations, test, commit the lock and land it on the other machines.
Read itSpells used here
grim self-update
Update grim itself
Replace the grim phar with the newest release. Projects are not touched.
grim update
Board the newest train
Move core, every module and every theme onto the newest release train grim.json allows, or a single module within the train it is on.
grim upgrade
Renew the infrastructure files
Rewrite the Docker and nginx files of a project from the templates of the grim you have installed.
grim test
Run the test suite
Run the project's tests in the app container against a separate test database that grim creates and migrates for you.
grim why
Ask why a module is here
Show the chain of requirements that leads from grim.json to an installed module, and what that module requires in turn.