Drizzle migrations only run on restore, so a deploy carrying a new migration never applies it #63
Labels
No labels
area/auth
area/backend
area/ci
area/deploy
area/e2e
area/frontend
area/shared
blocked
good-first-issue
needs-info
priority/high
priority/low
priority/medium
type/bug
type/chore
type/docs
type/feature
type/tech-debt
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
celilo/lunacycle#63
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while designing an app server for byoi (build-your-own-internet), which was going to copy lunacycle's migration approach. It should not copy how the migration is triggered.
What lunacycle does right
scripts/migrate.shwalks Drizzle'smeta/_journal.jsonand applies pending.sqlfiles withsqlite3. It tracks what has been applied by row count in__drizzle_migrationsrather than by hash, because Drizzle stores a rolling snapshot hash and not a per-file checksum, so hash matching fails on any database the ORM itself migrated. The script itself is sound, and the comment explaining the row-count decision is good.It is copied into
dist/bymanifest.yml:221,228.The defect
migrate.shhas exactly one caller in the tree:The module's hooks are
on_install,on_uninstall,health_check,on_backup,on_backup_analyze, andon_restore. Only the restore path migrates.So deploying a new lunacycle version that carries a new migration does not apply it. The app comes up against the old schema and stays quiet until something reads or writes a column that is not there.
This is celilo#169 ("apt upgrade does not run DB migrations") live in a module whose state is
VERIFIED.modules/wireguard-manager/server/src/store.tscites celilo#169 as its reason for using plainbun:sqlitewithCREATE TABLE IF NOT EXISTSand no migration runner at all, which is a different and also valid answer to the same hazard.Two ways to fix it
Call
migrate.shfromon_installas well ason_restore. Smallest change. It still depends on someone remembering to add the call to any future hook that can land a new version.Move the migration run into the app at startup. An upgrade restarts the unit, so an upgrade migrates. There is no hook anyone can forget. This is the approach byoi is taking, written up in its design doc as decision D8.
Either way, the gate should be seen to fail before it is trusted: deploy a version carrying a pending migration and confirm the schema actually changed without anyone running a hook by hand.
Smaller thing worth a look while in there
Tracking applied migrations by position rather than by hash means deleting or reordering an entry in
_journal.jsonsilently misaligns every migration after it. The comment inmigrate.shexplains why hashes were rejected, so this may well be the right trade, but it deserves a line in the script saying so rather than being implicit in the arithmetic.Not affected
byoi needs no change. Its design already deviates.