Cap plugin revision ids at the 32 chars MySQL stores

Rolling the containers failed on strict MySQL: the endpoints chain could not
stamp its new head with "Data too long for column version_num". Plugin version
tables declare version_num VARCHAR(32) and the new revision id was 33 chars.

Nothing in the suite caught it. The tests run on SQLite, which does not enforce
declared column widths, so an over-long id passes locally and fails only on a
real deploy - after the migration body has run and only the stamp fails. The
rollback was clean here, but the failure lands at the worst possible point.

Shorten the id and assert the limit in the test that already parses every
plugin revision, so the next over-long id fails on a laptop instead of during
a roll. Core is deliberately not covered: its alembic_version is VARCHAR(128),
and it already carries ids longer than 32 that are correct.
This commit is contained in:
benjamin.baker
2026-09-08 16:47:56 -04:00
parent 8f115ca330
commit 0b5546bcef
2 changed files with 16 additions and 3 deletions

View File

@@ -39,7 +39,7 @@ Idempotent on the policy names, so a re-run neither duplicates the split rows
nor resurrects the bundle. Guards on the policy tables being present and no-ops
if they are not, matching 0007.
Revision ID: endpoints0019splitmonitorpolicies
Revision ID: endpoints0019splitpolicies
Revises: endpoints0018endpointlocks
"""
from alembic import op
@@ -49,7 +49,9 @@ import sqlalchemy as sa
from datetime import datetime
revision = 'endpoints0019splitmonitorpolicies'
# Alembic stores this in alembic_version.version_num, a VARCHAR(32). A longer
# id passes on SQLite and fails on strict MySQL with "Data too long".
revision = 'endpoints0019splitpolicies'
down_revision = 'endpoints0018endpointlocks'
branch_labels = None
depends_on = None

View File

@@ -115,7 +115,7 @@ EXPECTED_HEAD_REVISION['warranty'] = 'warranty0002proof'
# on one endpoint, a caller-authority axis separate from the policy hold.
# 0019 splits the 0007 bundle into one shipped Configuration Policy per monitor
# and drops the shipped Business Policy, so sites compose their own.
EXPECTED_HEAD_REVISION['endpoints'] = 'endpoints0019splitmonitorpolicies'
EXPECTED_HEAD_REVISION['endpoints'] = 'endpoints0019splitpolicies'
# Plugins built after the cutover: their 0001 baseline really creates tables the
# core chain never owned.
@@ -208,6 +208,17 @@ def test_plugin_has_migration_chain(plugin):
if isinstance(node.value, ast.Constant):
down = node.value.value
assert rev, f"{plugin}: {script.name} has no revision id"
# alembic_version_<plugin>.version_num is VARCHAR(32). A longer id
# passes every SQLite test and then fails the real deploy on strict
# MySQL with "Data too long for column 'version_num'", after the
# migration body has already run. Caught
# endpoints0019splitmonitorpolicies (33 chars) during a container roll.
# The CORE chain's alembic_version is VARCHAR(128), so core ids are not
# bound by this and are not checked here.
assert len(rev) <= 32, (
f"{plugin}: {script.name} revision id {rev!r} is {len(rev)} chars; "
'alembic_version.version_num holds 32'
)
assert found_down, f"{plugin}: {script.name} has no down_revision"
revisions.add(rev)
if down is None: