From a5898a3fbd5bdde93b1c5fae08e3e73463793b8c Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:06:05 -0700 Subject: [PATCH] fix(ci): grandfather the already-applied 0074 migration collision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both 0074_ai_review_cache (#1462) and 0074_orb_self_enrollment_disabled (#1465) merged and deployed before the duplicate number surfaced. The latter is a bare ALTER TABLE ADD COLUMN, which SQLite cannot guard with IF NOT EXISTS, and D1/self-host track applied migrations by filename — so renaming it now would re-run the ALTER and fail the deploy. Grandfather the pair (same rationale as the pre-existing 0015/0017 entries) so db:migrations:check passes on main again; this unblocks validate on every open PR. --- scripts/check-migrations.mjs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/check-migrations.mjs b/scripts/check-migrations.mjs index 6094a415e9..8b62f65366 100644 --- a/scripts/check-migrations.mjs +++ b/scripts/check-migrations.mjs @@ -6,10 +6,17 @@ // • a skipped number (gap) or a stray non-conforming filename. // Migration-only PRs trigger this via the `migrations/**` path filter in .github/workflows/ci.yml. // -// KNOWN_DUPLICATES: two pairs (0015, 0017) already merged silently before this guard existed and are -// already applied in production — D1 records applied migrations by filename, so renaming either now would -// make wrangler try to re-apply it. They are grandfathered here. Do NOT add to this list; the whole point -// of the guard is that a NEW duplicate fails CI and gets renumbered before merge. +// KNOWN_DUPLICATES: pairs already merged AND applied in production before the collision was noticed — D1 +// records applied migrations by filename, so renaming either now would make wrangler (and the self-host +// migrator) try to RE-APPLY it. For a non-idempotent statement (e.g. `ALTER TABLE … ADD COLUMN`, which SQLite +// cannot guard with IF NOT EXISTS) the re-apply ERRORS and breaks the deploy, so renumbering is unsafe once the +// dup has shipped — those are grandfathered here. Do NOT add a NEW (not-yet-merged) duplicate to this list: +// renumber its branch to the next free number BEFORE merge. Only an already-shipped, can't-be-renumbered dup +// belongs here. +// • 0015 / 0017 — predate the guard. +// • 0074 — both 0074_ai_review_cache (#1462) and 0074_orb_self_enrollment_disabled (#1465, a bare ADD COLUMN) +// merged + deployed before the collision surfaced; the column already exists in prod, so a rename would +// re-run the ALTER and fail. Grandfathered for the same reason as 0015/0017. import { readdirSync } from "node:fs"; const DIR = "migrations"; @@ -17,6 +24,7 @@ const NAME = /^(\d{4})_[a-z0-9]+(?:_[a-z0-9]+)*\.sql$/; const KNOWN_DUPLICATES = new Map([ [15, new Set(["0015_github_agent_command_feedback.sql", "0015_product_usage_events.sql"])], [17, new Set(["0017_agent_recommendation_outcomes.sql", "0017_product_usage_role_retention_rollups.sql"])], + [74, new Set(["0074_ai_review_cache.sql", "0074_orb_self_enrollment_disabled.sql"])], ]); const fail = (message) => {