A target's deployment history, stored ON the target (deploy/deployments.json) rather than on whoever's laptop ran the deploy -- so it survives a fresh clone of the project, and describes the truth of that one machine. SyncTask mirrors it into the local store for a fleet-wide view.
class MMO\admin\helpers\Journal
Namespace
MMO\admin\helpers
It is what makes the rest honest:
- `status` compares the recorded state with the live one instead of re-deriving everything over ssh;
- a rollback knows which release to go back to, and which database snapshot goes with it;
- a database patch can be applied exactly once ([`MigrateTask`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/MigrateTask.md#migratetask)).
**Nothing is ever discarded.** An earlier version capped the file at 100 entries and dropped the oldest,
which quietly destroyed the audit trail and -- far worse -- the record of which patches had already run, so
a patch could be applied a second time once its entry aged out. Here the live file is rotated into
`deployments.{n}.json` and [`getAppliedPatches`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/helpers/Journal.md#journal-getappliedpatches) reads back through every one of them.
$journal = new Journal($runner, $target->getJournalFilename());
$journal->last()?->getVersion(); // what is actually live
$journal->append($deployment);
Every database patch already applied on this target, across all deployments -- the basis of
function getAppliedPatches(): arrayReads the ARCHIVES too, always. A patch whose journal entry has rotated out of the live file has still
been applied, and re-running it would be exactly the kind of quiet, destructive mistake this package
exists to make impossible.
The release to roll back to: the one live before the current one.
function getPreviousRelease(): ?stringNot simply `last()->getPrevious()`, because plenty of recorded runs ship nothing -- a database migration,
a backup -- and carry no release transition at all. Reading the newest entry blindly would let a migration
run erase the rollback target, so this walks back to the last entry that actually MOVED the target, and
skips the ones that merely confirm where it already is.