Use umzug to autorun migrations (#5281)
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import path from "path";
|
||||
import { Sequelize } from "sequelize-typescript";
|
||||
import { Umzug, SequelizeStorage, MigrationError } from "umzug";
|
||||
import env from "@server/env";
|
||||
import Logger from "../logging/Logger";
|
||||
import * as models from "../models";
|
||||
@@ -32,3 +34,39 @@ export const sequelize = new Sequelize(url, {
|
||||
idle: 10000,
|
||||
},
|
||||
});
|
||||
|
||||
export const migrations = new Umzug({
|
||||
migrations: {
|
||||
glob: ["migrations/*.js", { cwd: path.resolve("server") }],
|
||||
resolve: ({ name, path, context }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const migration = require(path as string);
|
||||
return {
|
||||
name,
|
||||
up: async () => migration.up(context, Sequelize),
|
||||
down: async () => migration.down(context, Sequelize),
|
||||
};
|
||||
},
|
||||
},
|
||||
context: sequelize.getQueryInterface(),
|
||||
storage: new SequelizeStorage({ sequelize }),
|
||||
logger: {
|
||||
warn: (params) => Logger.warn("database", params),
|
||||
error: (params: Record<string, unknown> & MigrationError) =>
|
||||
Logger.error(params.message, params),
|
||||
info: (params) =>
|
||||
Logger.info(
|
||||
"database",
|
||||
params.event === "migrating"
|
||||
? `Migrating ${params.name}…`
|
||||
: `Migrated ${params.name} in ${params.durationSeconds}s`
|
||||
),
|
||||
debug: (params) =>
|
||||
Logger.debug(
|
||||
"database",
|
||||
params.event === "migrating"
|
||||
? `Migrating ${params.name}…`
|
||||
: `Migrated ${params.name} in ${params.durationSeconds}s`
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,58 +1,21 @@
|
||||
import { execSync } from "child_process";
|
||||
import chalk from "chalk";
|
||||
import { isEmpty } from "lodash";
|
||||
import { migrations } from "@server/database/sequelize";
|
||||
import env from "@server/env";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import AuthenticationProvider from "@server/models/AuthenticationProvider";
|
||||
import Team from "@server/models/Team";
|
||||
|
||||
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 pending = getPendingMigrations();
|
||||
const pending = await migrations.pending();
|
||||
if (!isEmpty(pending)) {
|
||||
if (env.isCloudHosted()) {
|
||||
logMigrations(pending);
|
||||
Logger.warn(chalk.red("Migrations are pending"));
|
||||
process.exit(1);
|
||||
} else {
|
||||
runMigrations();
|
||||
Logger.info("database", "Running migrations…");
|
||||
await migrations.up();
|
||||
}
|
||||
}
|
||||
await checkDataMigrations();
|
||||
|
||||
Reference in New Issue
Block a user