From eace10e66be9e61ac54b88bd386d16f045d3bb49 Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Thu, 23 Jan 2025 17:33:50 +0100 Subject: [PATCH] fix(medusa,cli): Resources not correctly loaded when running the migration scripts (#11108) FIXES FRMW-2888 **What** Since the migration scripts runner run as part of the migrate script, we were cleaning up the resources but we didn't take into consideration that links are loading automagically by just importing the links. The issue is that once a link have been imported, the next import will rely on the cached module and therefore when cleaning the resources, re importing those links is not enough. Instead, we are now treating the run-script as a separate command that we run during running the migration so that resources are isolated and loaded according to the need of each script themselves --- packages/cli/medusa-cli/src/create-cli.ts | 10 +++ packages/medusa/src/commands/db/migrate.ts | 33 ++++++--- .../medusa/src/commands/db/run-scripts.ts | 69 ++++++++++++------- 3 files changed, 76 insertions(+), 36 deletions(-) diff --git a/packages/cli/medusa-cli/src/create-cli.ts b/packages/cli/medusa-cli/src/create-cli.ts index 20ae5d8ca0..14c2c38dc3 100644 --- a/packages/cli/medusa-cli/src/create-cli.ts +++ b/packages/cli/medusa-cli/src/create-cli.ts @@ -204,6 +204,16 @@ function buildLocalCommands(cli, isLocalProject) { }) ), }) + .command({ + command: "db:migrate:scripts", + desc: "Run all migration scripts", + handler: handlerP( + getCommandHandler("db/run-scripts", (args, cmd) => { + process.env.NODE_ENV = process.env.NODE_ENV || `development` + return cmd(args) + }) + ), + }) .command({ command: "db:rollback [modules...]", desc: "Rollback last batch of executed migrations for a given module", diff --git a/packages/medusa/src/commands/db/migrate.ts b/packages/medusa/src/commands/db/migrate.ts index 1828115ecd..046210360b 100644 --- a/packages/medusa/src/commands/db/migrate.ts +++ b/packages/medusa/src/commands/db/migrate.ts @@ -1,20 +1,22 @@ -import { join } from "path" +import { MEDUSA_CLI_PATH, MedusaAppLoader } from "@medusajs/framework" +import { LinkLoader } from "@medusajs/framework/links" +import { logger } from "@medusajs/framework/logger" import { ContainerRegistrationKeys, mergePluginModules, } from "@medusajs/framework/utils" -import { LinkLoader } from "@medusajs/framework/links" -import { logger } from "@medusajs/framework/logger" -import { MedusaAppLoader } from "@medusajs/framework" +import { join } from "path" -import { syncLinks } from "./sync-links" -import { ensureDbExists } from "../utils" +import { fork } from "child_process" +import path from "path" import { initializeContainer } from "../../loaders" import { getResolvedPlugins } from "../../loaders/helpers/resolve-plugins" -import { runMigrationScripts } from "./run-scripts" - +import { ensureDbExists } from "../utils" +import { syncLinks } from "./sync-links" const TERMINAL_SIZE = process.stdout.columns +const cliPath = path.resolve(MEDUSA_CLI_PATH, "..", "..", "cli.js") + /** * A low-level utility to migrate the database. This util should * never exit the process implicitly. @@ -77,9 +79,18 @@ export async function migrate({ * Run migration scripts */ console.log(new Array(TERMINAL_SIZE).join("-")) - await runMigrationScripts({ - directory, - container, + const childProcess = fork(cliPath, ["db:migrate:scripts"], { + cwd: directory, + env: process.env, + }) + + await new Promise((resolve, reject) => { + childProcess.on("error", (error) => { + reject(error) + }) + childProcess.on("close", () => { + resolve() + }) }) } diff --git a/packages/medusa/src/commands/db/run-scripts.ts b/packages/medusa/src/commands/db/run-scripts.ts index 60d7cc4468..67a4241a6c 100644 --- a/packages/medusa/src/commands/db/run-scripts.ts +++ b/packages/medusa/src/commands/db/run-scripts.ts @@ -9,7 +9,7 @@ import { import { dirname, join } from "path" import { MedusaModule } from "@medusajs/framework/modules-sdk" -import { MedusaContainer } from "@medusajs/types" +import { MedusaContainer, PluginDetails } from "@medusajs/types" import { initializeContainer } from "../../loaders" import { getResolvedPlugins } from "../../loaders/helpers/resolve-plugins" import { ensureDbExists } from "../utils" @@ -22,46 +22,30 @@ const TERMINAL_SIZE = process.stdout.columns */ export async function runMigrationScripts({ directory, - container, }: { directory: string - container?: MedusaContainer }): Promise { - /** - * Clear all module instances to prevent cache from kicking in - */ - MedusaModule.clearInstances() - - let container_: MedusaContainer = container! let onApplicationPrepareShutdown: () => Promise = async () => Promise.resolve() let onApplicationShutdown: () => Promise = async () => Promise.resolve() + let container_: MedusaContainer + let plugins: PluginDetails[] try { - /** - * Setup - */ - container_ ??= await initializeContainer(directory) + container_ = await initializeContainer(directory) await ensureDbExists(container_) const configModule = container_.resolve( ContainerRegistrationKeys.CONFIG_MODULE ) - const plugins = await getResolvedPlugins(directory, configModule, true) + plugins = await getResolvedPlugins(directory, configModule, true) mergePluginModules(configModule, plugins) - const linksSourcePaths = plugins.map((plugin) => - join(plugin.resolve, "links") - ) - await new LinkLoader(linksSourcePaths).load() - - const medusaAppResources = await new MedusaAppLoader().load() - onApplicationPrepareShutdown = - medusaAppResources.onApplicationPrepareShutdown - onApplicationShutdown = medusaAppResources.onApplicationShutdown - await medusaAppResources.onApplicationStart() + const resources = await loadResources(plugins) + onApplicationPrepareShutdown = resources.onApplicationPrepareShutdown + onApplicationShutdown = resources.onApplicationShutdown const scriptsSourcePaths = [ join(dirname(require.resolve("@medusajs/medusa")), "migration-scripts"), @@ -97,7 +81,42 @@ export async function runMigrationScripts({ } } -const main = async function ({ directory }: { directory: string }) { +async function loadResources(plugins: any): Promise<{ + onApplicationPrepareShutdown: () => Promise + onApplicationShutdown: () => Promise +}> { + /** + * Clear all module instances to prevent cache from kicking in + */ + MedusaModule.clearInstances() + + /** + * Setup + */ + + const linksSourcePaths = plugins.map((plugin) => + join(plugin.resolve, "links") + ) + await new LinkLoader(linksSourcePaths).load() + + const medusaAppResources = await new MedusaAppLoader().load() + const onApplicationPrepareShutdown = + medusaAppResources.onApplicationPrepareShutdown + const onApplicationShutdown = medusaAppResources.onApplicationShutdown + await medusaAppResources.onApplicationStart() + + return { + onApplicationPrepareShutdown, + onApplicationShutdown, + } +} + +const main = async function ({ + directory, +}: { + directory: string + container?: MedusaContainer +}) { try { const migrated = await runMigrationScripts({ directory,