This commit is contained in:
Adria Navarro 2023-12-05 15:29:11 +01:00
parent e12fc874c8
commit a8070829c9
5 changed files with 32 additions and 35 deletions

View File

@ -4,7 +4,12 @@ import { MIGRATIONS } from "./migrations"
export * from "./appMigrationMetadata" export * from "./appMigrationMetadata"
export const latestMigration = MIGRATIONS.map(m => m.migrationId) export type AppMigration = {
id: string
func: () => Promise<void>
}
export const latestMigration = MIGRATIONS.map(m => m.id)
.sort() .sort()
.reverse()[0] .reverse()[0]

View File

@ -1,8 +1,7 @@
// This file should never be manually modified, use `yarn add-app-migration` in order to add a new one // This file should never be manually modified, use `yarn add-app-migration` in order to add a new one
export const MIGRATIONS: { import { AppMigration } from "."
migrationId: string
migrationFunc: () => Promise<void> export const MIGRATIONS: AppMigration[] = [
}[] = [
// Migrations will be executed sorted by migrationId // Migrations will be executed sorted by migrationId
] ]

View File

@ -5,13 +5,11 @@ import {
getAppMigrationVersion, getAppMigrationVersion,
updateAppMigrationMetadata, updateAppMigrationMetadata,
} from "./appMigrationMetadata" } from "./appMigrationMetadata"
import { AppMigration } from "."
export async function processMigrations( export async function processMigrations(
appId: string, appId: string,
migrations: { migrations: AppMigration[]
migrationId: string
migrationFunc: () => Promise<void>
}[]
) { ) {
console.log(`Processing app migration for "${appId}"`) console.log(`Processing app migration for "${appId}"`)
@ -26,31 +24,31 @@ export async function processMigrations(
let currentVersion = await getAppMigrationVersion(appId) let currentVersion = await getAppMigrationVersion(appId)
const pendingMigrations = migrations const pendingMigrations = migrations
.filter(m => m.migrationId > currentVersion) .filter(m => m.id > currentVersion)
.sort((a, b) => a.migrationId.localeCompare(b.migrationId)) .sort((a, b) => a.id.localeCompare(b.id))
const migrationIds = migrations.map(m => m.migrationId).sort() const migrationIds = migrations.map(m => m.id).sort()
let index = 0 let index = 0
for (const { migrationId, migrationFunc } of pendingMigrations) { for (const { id, func } of pendingMigrations) {
const expectedMigration = const expectedMigration =
migrationIds[migrationIds.indexOf(currentVersion) + 1] migrationIds[migrationIds.indexOf(currentVersion) + 1]
if (expectedMigration !== migrationId) { if (expectedMigration !== id) {
throw `Migration ${migrationId} could not run, update for "${migrationId}" is running but ${expectedMigration} is expected` throw `Migration ${id} could not run, update for "${id}" is running but ${expectedMigration} is expected`
} }
const counter = `(${++index}/${pendingMigrations.length})` const counter = `(${++index}/${pendingMigrations.length})`
console.info(`Running migration ${migrationId}... ${counter}`, { console.info(`Running migration ${id}... ${counter}`, {
migrationId, migrationId: id,
appId, appId,
}) })
await migrationFunc() await func()
await updateAppMigrationMetadata({ await updateAppMigrationMetadata({
appId, appId,
version: migrationId, version: id,
}) })
currentVersion = migrationId currentVersion = id
} }
}) })
} }

View File

@ -10,10 +10,10 @@ describe("migration", () => {
await config.doInContext(config.getAppId(), async () => { await config.doInContext(config.getAppId(), async () => {
const db = context.getAppDB() const db = context.getAppDB()
for (const migration of MIGRATIONS) { for (const migration of MIGRATIONS) {
await migration.migrationFunc() await migration.func()
const docs = await db.allDocs({ include_docs: true }) const docs = await db.allDocs({ include_docs: true })
await migration.migrationFunc() await migration.func()
const latestDocs = await db.allDocs({ include_docs: true }) const latestDocs = await db.allDocs({ include_docs: true })
expect(docs).toEqual(latestDocs) expect(docs).toEqual(latestDocs)

View File

@ -2,16 +2,14 @@ import * as setup from "../../api/routes/tests/utilities"
import { processMigrations } from "../migrationsProcessor" import { processMigrations } from "../migrationsProcessor"
import { getAppMigrationVersion } from "../appMigrationMetadata" import { getAppMigrationVersion } from "../appMigrationMetadata"
import { context } from "@budibase/backend-core" import { context } from "@budibase/backend-core"
import { AppMigration } from ".."
describe("migrationsProcessor", () => { describe("migrationsProcessor", () => {
it("running migrations will update the latest applied migration", async () => { it("running migrations will update the latest applied migration", async () => {
const testMigrations: { const testMigrations: AppMigration[] = [
migrationId: string { id: "123", func: async () => {} },
migrationFunc: () => Promise<void> { id: "124", func: async () => {} },
}[] = [ { id: "125", func: async () => {} },
{ migrationId: "123", migrationFunc: async () => {} },
{ migrationId: "124", migrationFunc: async () => {} },
{ migrationId: "125", migrationFunc: async () => {} },
] ]
const config = setup.getConfig() const config = setup.getConfig()
@ -29,13 +27,10 @@ describe("migrationsProcessor", () => {
}) })
it("no context can be initialised within a migration", async () => { it("no context can be initialised within a migration", async () => {
const testMigrations: { const testMigrations: AppMigration[] = [
migrationId: string
migrationFunc: () => Promise<void>
}[] = [
{ {
migrationId: "123", id: "123",
migrationFunc: async () => { func: async () => {
await context.doInAppMigrationContext("any", () => {}) await context.doInAppMigrationContext("any", () => {})
}, },
}, },