Repository navigation
ci: apply Cloud VM migrations on every main push that adds one - #13402
austinywang wants to merge 3 commits into
Conversation
Regression pin only; it fails until the next commit. A migration merged to main deployed to Vercel immediately but was only applied to the databases by a manual dispatch, so production ran code against a schema without the tables it needed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Vercel deploys main on each push, but cloud-vm-migrate.yml only ran when someone dispatched it, and the last production run was 2026-09-17. Five migrations merged since then were never applied: on 2026-09-21 the deploy that made beginCreate insert into cloud_runtimes (#13329) turned every Cloud create into a 503 vm_cloud_state_unavailable, and device-token reads had been failing on missing columns since #12924 shipped. The workflow now also triggers on a push to main that touches web/db/migrations/**. A push applies staging first; the production job keeps its cloud-vm-production environment, whose required reviewers must approve the run, so production still gets a human decision, now one click after the merge instead of a dispatch someone has to remember. Manual dispatch is unchanged. CLAUDE.md records the rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
All contributors have signed the CLA ✍️ ✅ |
|
Understand this PR’s impact Explore downstream dependencies and potential security impact with Blast Radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe migration workflow now runs for migration changes pushed to ChangesCloud VM migration automation
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant GitHub
participant CloudVMMigrationWorkflow
participant Staging
participant Production
GitHub->>CloudVMMigrationWorkflow: Push migration changes to main
CloudVMMigrationWorkflow->>Staging: Apply migrations at github.sha
Staging->>Production: Complete staging migration
CloudVMMigrationWorkflow->>Production: Await required approval, then apply migrations
🚥 Pre-merge checks | ✅ 24 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (24 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (2 skipped: 2 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…roval Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
| def test_push_to_main_with_a_migration_triggers_the_workflow(self) -> None: | ||
| on = load()[True] if True in load() else load()["on"] | ||
| self.assertIn("workflow_dispatch", on, "manual dispatch stays available") | ||
| push = on.get("push") | ||
| self.assertIsNotNone(push, "a main push must run the migration workflow") | ||
| self.assertEqual(push.get("branches"), ["main"]) | ||
| self.assertIn("web/db/migrations/**", push.get("paths", [])) | ||
|
|
||
| def test_push_applies_staging_then_production(self) -> None: | ||
| jobs = load()["jobs"] | ||
| staging = jobs["migrate-staging"] | ||
| production = jobs["migrate-production"] | ||
| self.assertIn("github.event_name == 'push'", staging["if"]) | ||
| self.assertIn("github.event_name == 'push'", production["if"]) | ||
| self.assertIn("migrate-staging", production["needs"]) | ||
| self.assertEqual(production["environment"], "cloud-vm-production") | ||
| # A dispatched staging-only run must still stop before production. | ||
| self.assertIn("inputs.target == 'production'", production["if"]) | ||
| self.assertNotIn("inputs.target == 'staging'", production["if"]) |
There was a problem hiding this comment.
This regression test is not executed by CI. The repository invokes workflow tests individually from .github/workflows/ci.yml, while the broad Python check only compiles test files without running their assertions. As a result, removing the migration push trigger or production ordering would still pass CI. Add this test to the workflow-guard test job alongside the existing workflow tests.
|
Automatic catch-up: I tried to catch this branch up with
Nothing was pushed. Merge Automatic catch-up will not try this head again; a new push or |
Problem
Since the 2026-09-21 03:03 PT production deploy, every Cloud
New Machine(sheet andcmux vm new) fails in about 2 s with "The Cloud VM request failed". Production logs showPOST /api/vmanswering 503vm_cloud_state_unavailablefrombeginCreate: #13329 made the create transaction insert intocloud_runtimes, and that table's migration (20260921030000_hive_runtime_registry) was never applied to production. The last production migration run was 2026-09-17T04:08Z; five migrations merged after it were pending (vm_coderouter_scope,push_e2e_keys,push_token_revocation,push_token_revocation_installation,hive_runtime_registry). The same logs showGET /api/device-tokensfailing withcolumn "installation_id" does not existsince #12924 shipped, and staging had the same relation errors.Root cause:
cloud-vm-migrate.ymlonly runs on manual dispatch, while Vercel deploysmainon every push, so any PR that adds a migration ships code ahead of its schema until someone remembers to dispatch the workflow.Change
cloud-vm-migrate.ymlalso triggers on a push tomainthat touchesweb/db/migrations/**. A push applies staging first, then the production job runs under the existingcloud-vm-productionenvironment, whose three required reviewers must approve it, so production keeps a human decision, one click after the merge. Manual dispatch is unchanged; the checkout ref for a push is the pushed commit.web/AGENTS.md(the database notes on main) records the rule so a PR that adds a migration is not treated as live until that run is approved and green.tests/test_cloud_vm_migrate_workflow.pypins the trigger, the staging-then-production order, and that a dispatched staging-only run still stops before production. It lands as its own commit first (red), then the workflow change (green).Remaining gap
A push still deploys and migrates concurrently, so a migration-dependent route can fail for the minutes between the deploy going live and the production job being approved. Closing that fully means running the migration inside the deploy (before
next build) or gating the deploy on the run, which is a bigger change for the owner of the Vercel setup to decide.Verified
staging PlanetScale migration applied); the production run is dispatched and waiting for reviewer approval.python3 -m unittest tests/test_cloud_vm_migrate_workflow.pyfails on the old workflow and passes on the new one; the YAML parses.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
mainnow run automatically when migration files change.Documentation
Tests