fix(cd): document the upgrade_policy half of CD, and run the hook tests in CI #31
No reviewers
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!31
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "wire-cd-backup-gate"
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?
What I found
The brief for this work assumed lunacycle might have no
on_backuphook, which would have made armingauto_upgradereckless. It has one, and it works —celilo backup list lunacycleon celilo-mgr shows three completed backups, the most recent a 1.1 MB snapshot of module version 1.0.4 at schema v11. The build half is also already real: 8 greenrelease.ymlruns, and Version PR #30 currently open with 1.0.5.So CD is genuinely wired in both directions. The gap is narrower and easier to miss.
The actual trap
manifest.ymlandrelease.ymlboth told the operator to set one key:That arms the poll. It says nothing about whether the upgrade backs the database up first — that's
upgrade_policy, and unset it defaults toby-semver, which backs up on minor/major only.Every lunacycle release to date has been a patch (see
CHANGELOG.md). So an operator following the documented instruction would have armed unattended upgrades of a data-bearing app on the fast path: no pre-deploy backup, and celilo has no rollback. Theon_backuphook would sit there, tested and working, and never be called. The declared posture reads "protected"; the realistic release cadence routes around it.Both keys are now documented together — in
manifest.yml,release.yml, and.changeset/README.md— with why the second one is the load-bearing one.The hook tests had never run in CI
test:unitisvitest runwithinclude: ['tests/unit/**']. The celilo hooks live incelilo/scripts/, deliberately outside the root workspace. So all 57 hook tests — includingbackup.test.tsandrestore.test.ts, which cover the hook the entire safe-upgrade path depends on — ran only on developer laptops.Added
test:hooks+ a step inpr-validate.yml. Wiring it up immediately caught thatcelilo/scripts/bun.lockwas stale (pinned@celilo/capabilitiesat^0.4.2againstpackage.json's^0.5.0), which a frozen install rejects. Regenerated — lockfile metadata only, the installed tree was already correct (Checked 7 installs across 8 packages (no changes)).New guard, watched to fail
celilo/scripts/manifest-cd.test.tsguards the declaration celilo depends on silently. The gate in celilo is:Dropping
on_backupdoes not fail and does not refuse — celilo takes anelse if (posture === 'safe')branch that logs a warning and deploys anyway. Verified by deleting the hook frommanifest.yml:then restored, back to 5 pass.
Removed the
auto_upgradedeclarationIt existed to work around
celilo module config setrejecting undeclared keys. celilo 0.16.0 (#516) madeauto_upgradeandupgrade_policyframework keys settable on any module, and celilo-mgr runs 0.16.2 — verified. Keeping it leaves a second, module-specific source of truth for a framework concern, and declaring only one of the two keys is part of what madeauto_upgradelook like "the switch".Verification
bun run lintbun run typecheckbun run test:unitbun run test:hookscelilo module checkNo application behaviour changes.
Still needs an operator decision
This PR does not turn CD on — deliberately. Arming it is two commands on celilo-mgr, and they should be run together:
Worth weighing first: lunacycle's only e2e suite (
e2e-nightly.yml) has run exactly once and failed — 11 failed, 12 did not run, 6 passed, every failure aseedDatabase()UNIQUE-constraint error.release.ymldeliberately does not gate on it. Filed separately as #32.