left4me: trigger alembic_upgrade from git_deploy (catch migrations on code updates)

pip_install's `unless` (import l4d2host, l4d2web) skips when both
packages are already installed — so on a code-only apply, pip_install
doesn't fire and alembic_upgrade (which it triggers) never runs.
The new 0008 migration would silently get skipped, leaving the DB
out of sync with the new schema.

Wire git_deploy → alembic_upgrade directly. alembic upgrade head is
idempotent (no-op when at head); seed_overlays + service:restart
cascade off alembic, so editable-install code changes also get picked
up by gunicorn.

Edge case noted (deferred): a migration-only change with no code
change has the same matching git rev, so this won't fire either. In
practice migrations always come with the code change that uses them.
This commit is contained in:
CroneKorkN 2026-05-10 21:27:40 +02:00
parent 7265c4aab1
commit 09d236ded5
Signed by: cronekorkn
SSH key fingerprint: SHA256:v0410ZKfuO1QHdgKBsdQNF64xmTxOF8osF1LIqwTcVw

View file

@ -135,12 +135,23 @@ git_deploy = {
'/opt/left4me/src': { '/opt/left4me/src': {
'repo': node.metadata.get('left4me/git_url'), 'repo': node.metadata.get('left4me/git_url'),
'rev': node.metadata.get('left4me/git_branch'), 'rev': node.metadata.get('left4me/git_branch'),
# No triggers list — both downstream actions (chown_src and 'triggers': [
# pip_install) run every apply gated by their own `unless` # On a code-update apply, refresh the DB schema. pip_install
# guards, which makes the chain self-healing after a partial # would have triggered alembic in the create_venv path, but on
# failure. Chaining via triggers would have made them only # a normal apply pip_install's `unless` skips (packages still
# fire when git_deploy itself fired, leaving stuck states # importable from the previous editable install), and that
# unrecoverable. # would leave alembic_upgrade dormant. Wiring git_deploy →
# alembic directly ensures new migrations land whenever new
# code lands. alembic upgrade head is idempotent (no-op when
# already at head), so this is safe to fire on every code
# update; the seed_overlays + service:restart cascade off
# alembic also covers picking up the new code in gunicorn.
'action:left4me_alembic_upgrade',
],
# chown_src and pip_install are NOT in triggers — they run every
# apply gated by their own `unless` guards, which makes the chain
# self-healing after a partial failure. (Items in a triggers list
# must be triggered:True, which would lose that property.)
}, },
} }