-
Notifications
You must be signed in to change notification settings - Fork 15
feat: add database migration system with clean testing environment #544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add database migration system with clean testing environment #544
Conversation
🦋 Changeset detectedLatest commit: 7caca1d The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
View your CI Pipeline Execution ↗ for commit 7caca1d
☁️ Nx Cloud last updated this comment at |
| if (existing.length > 0) { | ||
| // Another process applied it while we were waiting for lock | ||
| return; | ||
| } | ||
|
|
||
| // Execute migration SQL | ||
| await tx.unsafe(migration.content); | ||
|
|
||
| // Record that migration was applied | ||
| await tx` | ||
| INSERT INTO pgflow_installer.migrations (timestamp) | ||
| VALUES (${migration.timestamp}) | ||
| `; | ||
| }); | ||
|
|
||
| results.push({ timestamp: migration.timestamp, status: 'applied' }); | ||
| applied++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition handling bug causes incorrect statistics. When another process applies a migration while this process waits for the lock, the code returns early at line 68 but execution continues after the transaction block (line 81-82), incorrectly incrementing the applied counter and marking the migration as 'applied' in results.
This causes the applied count in the final result to be wrong - it counts migrations that were actually applied by other processes.
Fix:
Track whether the migration was actually applied in this transaction:
let wasApplied = false;
await this.sql.begin(async (tx) => {
await tx`SELECT pg_advisory_xact_lock(${MIGRATION_LOCK_KEY})`;
const existing = await tx`
SELECT 1 FROM pgflow_installer.migrations
WHERE timestamp = ${migration.timestamp}
`;
if (existing.length > 0) {
return; // Already applied by another process
}
await tx.unsafe(migration.content);
await tx`
INSERT INTO pgflow_installer.migrations (timestamp)
VALUES (${migration.timestamp})
`;
wasApplied = true;
});
if (wasApplied) {
results.push({ timestamp: migration.timestamp, status: 'applied' });
applied++;
} else {
results.push({ timestamp: migration.timestamp, status: 'skipped' });
skipped++;
}| if (existing.length > 0) { | |
| // Another process applied it while we were waiting for lock | |
| return; | |
| } | |
| // Execute migration SQL | |
| await tx.unsafe(migration.content); | |
| // Record that migration was applied | |
| await tx` | |
| INSERT INTO pgflow_installer.migrations (timestamp) | |
| VALUES (${migration.timestamp}) | |
| `; | |
| }); | |
| results.push({ timestamp: migration.timestamp, status: 'applied' }); | |
| applied++; | |
| if (existing.length > 0) { | |
| // Another process applied it while we were waiting for lock | |
| return; | |
| } | |
| // Execute migration SQL | |
| await tx.unsafe(migration.content); | |
| // Record that migration was applied | |
| await tx` | |
| INSERT INTO pgflow_installer.migrations (timestamp) | |
| VALUES (${migration.timestamp}) | |
| `; | |
| // Flag that we applied this migration | |
| wasApplied = true; | |
| }); | |
| if (wasApplied) { | |
| results.push({ timestamp: migration.timestamp, status: 'applied' }); | |
| applied++; | |
| } else { | |
| results.push({ timestamp: migration.timestamp, status: 'skipped' }); | |
| skipped++; | |
| } |
Spotted by Graphite Agent
Is this helpful? React 👍 or 👎 to let us know.
b30d343 to
80a7ac6
Compare
80a7ac6 to
45a8ec7
Compare
45a8ec7 to
7869670
Compare
85ee829 to
db2af28
Compare
db2af28 to
60f9b47
Compare
48136ca to
98cbc89
Compare
98cbc89 to
3a2efa4
Compare
1221280 to
92ae309
Compare
92ae309 to
cd64ae9
Compare
cd64ae9 to
4b6d099
Compare
4b6d099 to
7caca1d
Compare
🔍 Preview Deployment: Website✅ Deployment successful! 🔗 Preview URL: https://pr-544.pgflow.pages.dev 📝 Details:
_Last updated: _ |

Add Database Migration System for Edge Worker
This PR introduces a database migration system for the Edge Worker, enabling automated schema management through a structured approach. Key features include:
Created a
MigrationRunnerclass that handles:Added new API endpoints to the control plane:
GET /migrations/list- Shows all migrations with their statusPOST /migrations/up- Applies pending migrationsImplemented a migration loader that reads SQL files from the @pgflow/core package
Added comprehensive tests for the migration system with a dedicated clean database setup:
Updated Supabase JS dependency from 2.84.0 to 2.86.0
The migration system ensures database schema changes can be applied safely and consistently across environments.