molecule-core/.github/workflows
Hongming Wang ea8ff626a9 ci: hard gate against migration version collisions (#2341)
Two PRs targeting staging can each add a migration with the same
numeric prefix (e.g. 044_*.up.sql). Each passes CI independently.
They collide at merge time. Worst case: second migration silently
doesn't apply and prod schema drifts from what the code expects.

Caught manually 2026-04-30 during PR #2276 rebase: 044_runtime_image_pins
collided with 044_platform_inbound_secret from RFC #2312. This workflow
makes that detection automatic at PR-open time.

How it works:
  scripts/ops/check_migration_collisions.py runs on every PR that
  touches workspace-server/migrations/**. For each new/modified
  migration filename, extracts the numeric prefix and checks:

  1. Does the base branch already have a DIFFERENT migration file with
     the same prefix? (PR branched off an old base, base advanced and
     another PR landed the same number — needs rebase.)

  2. Is another OPEN PR (not this one) also adding a migration with
     the same prefix? (Race-window collision — both pass CI separately,
     would collide at merge time.)

Either case → exit 1 with a clear ::error:: message naming the
conflicting PR(s) so the author knows what to renumber.

Implementation notes:
  - Uses git ls-tree (not working-tree walk) so it works against any
    base ref without checkout.
  - Uses gh pr diff --name-only per open PR, bounded by `gh pr list
    --limit 100`. ~30s worst case for a busy repo, <5s normally.
  - --diff-filter=AM picks up Added or Modified — renaming a migration
    in place is also flagged (intentional; renaming migrations isn't
    safe).
  - Same filename in both PR and base = no collision (PR is editing
    in-place, fine).

Tests:
  scripts/ops/test_check_migration_collisions.py — 9 cases on the
  regex classifier (the load-bearing piece). End-to-end git/gh path
  is exercised by running the workflow against real PRs.

Hard-gates Tier 1 item 1 (#2341). Cheapest, cleanest gate. Catches
one specific class of merge-time foot-gun automatically.

Refs hard-gates discussion 2026-04-30. Tier 1 of 4 (others tracked
in #2342, #2343, #2344).
2026-04-29 21:42:42 -07:00
..
auto-promote-on-e2e.yml ci: ancestry-check on auto-promote :latest (#2244) 2026-04-29 16:18:42 -07:00
auto-promote-staging.yml Merge remote-tracking branch 'origin/staging' into docs/auto-promote-staging-prereq-comment 2026-04-28 20:46:42 -07:00
auto-sync-main-to-staging.yml fix(ci): auto-sync opens a PR + uses merge queue, not direct push 2026-04-28 15:59:26 -07:00
auto-tag-runtime.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
block-internal-paths.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
canary-staging.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
canary-verify.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
check-merge-group-trigger.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
check-migration-collisions.yml ci: hard gate against migration version collisions (#2341) 2026-04-29 21:42:42 -07:00
ci.yml ci: collapse all 4 path-filtered required checks to single-job-with-conditional-steps 2026-04-29 16:09:22 -07:00
codeql.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
e2e-api.yml ci: collapse two-jobs-sharing-name path-filter pattern in e2e-api/e2e-staging-canvas 2026-04-29 17:29:44 -07:00
e2e-staging-canvas.yml fix(e2e-canvas): kill teardown race that poisons concurrent runs 2026-04-29 19:23:56 -07:00
e2e-staging-saas.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
e2e-staging-sanity.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
pr-guards.yml ci: add pr-guards caller that disables auto-merge on push 2026-04-27 06:39:31 -07:00
promote-latest.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
publish-canvas-image.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
publish-runtime.yml Merge pull request #2249 from Molecule-AI/fix/publish-runtime-cascade-hard-fail-on-push 2026-04-29 01:33:10 +00:00
publish-workspace-server-image.yml ci: serialize publish + auto-redeploy staging tenants 2026-04-29 21:11:45 -07:00
railway-pin-audit.yml ci: daily Railway pin-audit cron + issue-on-failure (#2169) 2026-04-29 17:43:01 -07:00
redeploy-tenants-on-main.yml ci: add concurrency block to redeploy-tenants-on-main for parity 2026-04-29 21:14:41 -07:00
redeploy-tenants-on-staging.yml ci: serialize publish + auto-redeploy staging tenants 2026-04-29 21:11:45 -07:00
retarget-main-to-staging.yml ci(retarget): handle 422 'duplicate PR' by closing redundant main-PR (closes #1884) 2026-04-26 00:53:55 -07:00
runtime-pin-compat.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
runtime-prbuild-compat.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
secret-pattern-drift.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00
secret-scan.yml chore(security): pin Actions to SHAs + enable Dependabot auto-bumps 2026-04-28 15:37:06 -07:00
sweep-cf-orphans.yml Merge pull request #2248 from Molecule-AI/fix/sweep-cf-orphans-hard-fail-on-schedule 2026-04-29 01:16:22 +00:00
sweep-cf-tunnels.yml feat(ops): add sweep-cf-tunnels janitor — orphan Cloudflare Tunnels accumulate 2026-04-29 19:42:47 -07:00
sweep-stale-e2e-orgs.yml ci: hourly sweep of stale e2e-* orgs on staging 2026-04-24 23:07:57 -07:00
test-ops-scripts.yml chore(deps): batch dep bumps — 6 safe upgrades (4 actions majors + 2 npm dev deps) 2026-04-28 17:44:55 -07:00