From dadba3f3af89bfa1e71d8d601fe931a1456b7da8 Mon Sep 17 00:00:00 2001 From: Apoorv Mishra Date: Wed, 19 Apr 2023 09:27:50 +0530 Subject: [PATCH] Autorun migrations in community edition (#5141) * fix: autorun migrations in community edition * re-run tests * refactor * fix: review * fix: double error --- Makefile | 1 - server/index.ts | 9 +---- server/utils/startup.ts | 84 +++++++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index dc597047f..4b4b7cda8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ up: docker-compose up -d redis postgres s3 yarn install --pure-lockfile - yarn sequelize db:migrate yarn dev:watch build: diff --git a/server/index.ts b/server/index.ts index 2ebf6a87e..3e6ebc6a2 100644 --- a/server/index.ts +++ b/server/index.ts @@ -18,11 +18,7 @@ import services from "./services"; import { getArg } from "./utils/args"; import { getSSLOptions } from "./utils/ssl"; import { defaultRateLimiter } from "@server/middlewares/rateLimiter"; -import { - checkEnv, - checkMigrations, - checkPendingMigrations, -} from "./utils/startup"; +import { checkEnv, checkPendingMigrations } from "./utils/startup"; import { checkUpdates } from "./utils/updates"; import onerror from "./onerror"; import ShutdownHelper, { ShutdownOrder } from "./utils/ShutdownHelper"; @@ -53,8 +49,7 @@ if (serviceNames.includes("collaboration")) { // This function will only be called once in the original process async function master() { await checkEnv(); - checkPendingMigrations(); - await checkMigrations(); + await checkPendingMigrations(); if (env.TELEMETRY && env.ENVIRONMENT === "production") { checkUpdates(); diff --git a/server/utils/startup.ts b/server/utils/startup.ts index 57f013581..444de475c 100644 --- a/server/utils/startup.ts +++ b/server/utils/startup.ts @@ -1,51 +1,76 @@ import { execSync } from "child_process"; import chalk from "chalk"; +import { isEmpty } from "lodash"; 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() { +function getPendingMigrations() { + const commandResult = execSync( + `yarn sequelize db:migrate:status${ + env.PGSSLMODE === "disable" ? " --env=production-ssl-disabled" : "" + }` + ); + const commandResultArray = Buffer.from(commandResult) + .toString("utf-8") + .split("\n"); + + const pendingMigrations = commandResultArray.filter((line) => + line.startsWith("down") + ); + + return pendingMigrations; +} + +function runMigrations() { + Logger.info("database", "Running migrations..."); + const cmdResult = execSync( + `yarn db:migrate${ + env.PGSSLMODE === "disable" ? " --env=production-ssl-disabled" : "" + }` + ); + const cmdOutput = Buffer.from(cmdResult).toString("utf-8"); + Logger.info("database", cmdOutput); + Logger.info("database", "Done."); +} + +function logMigrations(migrations: string[]) { + Logger.warn("You have pending migrations"); + Logger.warn( + migrations + .map((line, i) => `${i + 1}. ${line.replace("down ", "")}`) + .join("\n") + ); +} + +export async function checkPendingMigrations() { try { - const commandResult = execSync( - `yarn sequelize db:migrate:status${ - env.PGSSLMODE === "disable" ? " --env=production-ssl-disabled" : "" - }` - ); - 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); + const pending = getPendingMigrations(); + if (!isEmpty(pending)) { + if (env.isCloudHosted()) { + logMigrations(pending); + process.exit(1); + } else { + runMigrations(); + } } + await checkDataMigrations(); } catch (err) { if (err.message.includes("ECONNREFUSED")) { Logger.warn( - `Could not connect to the database. Please check your connection settings.` + chalk.red( + `Could not connect to the database. Please check your connection settings.` + ) ); } else { - Logger.warn(err.message); + Logger.warn(chalk.red(err.message)); } process.exit(1); } } -export async function checkMigrations() { +export async function checkDataMigrations() { if (env.isCloudHosted()) { return; } @@ -58,6 +83,7 @@ export async function checkMigrations() { Logger.warn(` This version of Outline cannot start until a data migration is complete. Backup your database, run the database migrations and the following script: +(Note: script run needed only when upgrading to any version between 0.54.0 and 0.61.1, including both) $ node ./build/server/scripts/20210226232041-migrate-authentication.js `);