diff --git a/server/index.ts b/server/index.ts index d6ca0940e..8688b8b74 100644 --- a/server/index.ts +++ b/server/index.ts @@ -20,7 +20,11 @@ import { requestErrorHandler } from "./logging/sentry"; import services from "./services"; import { getArg } from "./utils/args"; import { getSSLOptions } from "./utils/ssl"; -import { checkEnv, checkMigrations } from "./utils/startup"; +import { + checkEnv, + checkMigrations, + checkPendingMigrations, +} from "./utils/startup"; import { checkUpdates } from "./utils/updates"; // If a services flag is passed it takes priority over the environment variable @@ -53,6 +57,7 @@ if (serviceNames.includes("collaboration")) { // This function will only be called once in the original process async function master() { await checkEnv(); + checkPendingMigrations(); await checkMigrations(); if (env.TELEMETRY && env.ENVIRONMENT === "production") { diff --git a/server/utils/startup.ts b/server/utils/startup.ts index fb6e0993b..8f5a67e54 100644 --- a/server/utils/startup.ts +++ b/server/utils/startup.ts @@ -1,9 +1,35 @@ +import { execSync } from "child_process"; import chalk from "chalk"; import env from "@server/env"; import Logger from "@server/logging/Logger"; import AuthenticationProvider from "@server/models/AuthenticationProvider"; import Team from "@server/models/Team"; +export function checkPendingMigrations() { + const commandResult = execSync("yarn sequelize db:migrate:status"); + const commandResultArray = Buffer.from(commandResult) + .toString("utf-8") + .split("\n"); + + const pendingMigrations = commandResultArray.filter((line) => + line.startsWith("down") + ); + + if (pendingMigrations.length) { + Logger.warn("You have pending migrations"); + Logger.warn( + pendingMigrations + .map((line, i) => `${i + 1}. ${line.replace("down ", "")}`) + .join("\n") + ); + Logger.warn( + "Please run `yarn db:migrate` or `yarn db:migrate --env production-ssl-disabled` to run all pending migrations" + ); + + process.exit(1); + } +} + export async function checkMigrations() { if (env.DEPLOYMENT === "hosted") { return;