Prevent cross version upgrade mismatch in 1.22 (#19627)
## Introduction As the new upgrade sequence engine is released in `1.22` it requires all workspaces to be in `1.21.0` which mean they will have a cursor on the sequence As if if someone upgrades from `1.20` to `1.22` no `upgradeMigration` will exist and throw a pretty basic `Could not find any cursor, database might not been initialized correctly` Here we allow a meaningful error
This commit is contained in:
+16
-16
@@ -3,13 +3,13 @@
|
||||
exports[`InstanceCommandGenerationService should encode version correctly in file and class names 1`] = `
|
||||
{
|
||||
"className": "TestFastInstanceCommand",
|
||||
"fileName": "1-20-instance-command-fast-1775000000000-test.ts",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-test.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.20.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
export class TestFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('SELECT 1');
|
||||
@@ -26,13 +26,13 @@ export class TestFastInstanceCommand implements FastInstanceCommand {
|
||||
exports[`InstanceCommandGenerationService should escape backslashes in SQL queries 1`] = `
|
||||
{
|
||||
"className": "UpdatePathFastInstanceCommand",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-update-path.ts",
|
||||
"fileName": "1-22-instance-command-fast-1775000000000-update-path.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000)
|
||||
export class UpdatePathFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('UPDATE "core"."config" SET "value" = E\\'path\\\\\\\\to\\\\\\\\file\\'');
|
||||
@@ -49,13 +49,13 @@ export class UpdatePathFastInstanceCommand implements FastInstanceCommand {
|
||||
exports[`InstanceCommandGenerationService should escape single quotes in SQL queries 1`] = `
|
||||
{
|
||||
"className": "UpdateConfigFastInstanceCommand",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-update-config.ts",
|
||||
"fileName": "1-22-instance-command-fast-1775000000000-update-config.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000)
|
||||
export class UpdateConfigFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('UPDATE "core"."config" SET "value" = \\'it\\'\\'s done\\'');
|
||||
@@ -72,13 +72,13 @@ export class UpdateConfigFastInstanceCommand implements FastInstanceCommand {
|
||||
exports[`InstanceCommandGenerationService should generate a migration with a single up/down query 1`] = `
|
||||
{
|
||||
"className": "AddFooColumnFastInstanceCommand",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-add-foo-column.ts",
|
||||
"fileName": "1-22-instance-command-fast-1775000000000-add-foo-column.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000)
|
||||
export class AddFooColumnFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TABLE "core"."user" ADD "foo" varchar');
|
||||
@@ -95,13 +95,13 @@ export class AddFooColumnFastInstanceCommand implements FastInstanceCommand {
|
||||
exports[`InstanceCommandGenerationService should generate a migration with multiple queries 1`] = `
|
||||
{
|
||||
"className": "CreateTaskTableFastInstanceCommand",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-create-task-table.ts",
|
||||
"fileName": "1-22-instance-command-fast-1775000000000-create-task-table.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000)
|
||||
export class CreateTaskTableFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('CREATE TABLE "core"."task" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" varchar NOT NULL)');
|
||||
@@ -120,13 +120,13 @@ export class CreateTaskTableFastInstanceCommand implements FastInstanceCommand {
|
||||
exports[`InstanceCommandGenerationService should generate a migration with query parameters 1`] = `
|
||||
{
|
||||
"className": "SeedSettingFastInstanceCommand",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-seed-setting.ts",
|
||||
"fileName": "1-22-instance-command-fast-1775000000000-seed-setting.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000)
|
||||
export class SeedSettingFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('INSERT INTO "core"."setting" ("key", "value") VALUES ($1, $2)', ["theme","dark"]);
|
||||
@@ -143,13 +143,13 @@ export class SeedSettingFastInstanceCommand implements FastInstanceCommand {
|
||||
exports[`InstanceCommandGenerationService should generate a slow instance command with populated up/down 1`] = `
|
||||
{
|
||||
"className": "MakeColumnNotNullableSlowInstanceCommand",
|
||||
"fileName": "1-21-instance-command-slow-1775000000000-make-column-not-nullable.ts",
|
||||
"fileName": "1-22-instance-command-slow-1775000000000-make-column-not-nullable.ts",
|
||||
"fileTemplate": "import { DataSource, QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { SlowInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/slow-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000, { type: 'slow' })
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000, { type: 'slow' })
|
||||
export class MakeColumnNotNullableSlowInstanceCommand implements SlowInstanceCommand {
|
||||
async runDataMigration(dataSource: DataSource): Promise<void> {
|
||||
// TODO: implement data backfill before the DDL migration
|
||||
@@ -170,13 +170,13 @@ export class MakeColumnNotNullableSlowInstanceCommand implements SlowInstanceCom
|
||||
exports[`InstanceCommandGenerationService should use default migration name in class and file names 1`] = `
|
||||
{
|
||||
"className": "AutoGeneratedFastInstanceCommand",
|
||||
"fileName": "1-21-instance-command-fast-1775000000000-auto-generated.ts",
|
||||
"fileName": "1-22-instance-command-fast-1775000000000-auto-generated.ts",
|
||||
"fileTemplate": "import { QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
@RegisteredInstanceCommand('1.21.0', 1775000000000)
|
||||
@RegisteredInstanceCommand('1.22.0', 1775000000000)
|
||||
export class AutoGeneratedFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TABLE "core"."user" ADD "bar" integer');
|
||||
|
||||
+19
-12
@@ -2,6 +2,11 @@ import { Test } from '@nestjs/testing';
|
||||
import { getDataSourceToken } from '@nestjs/typeorm';
|
||||
|
||||
import { InstanceCommandGenerationService } from 'src/database/commands/instance-command-generation.service';
|
||||
import { TWENTY_CURRENT_VERSION } from 'src/engine/core-modules/upgrade/constants/twenty-current-version.constant';
|
||||
import { TWENTY_PREVIOUS_VERSIONS } from 'src/engine/core-modules/upgrade/constants/twenty-previous-versions.constant';
|
||||
|
||||
const VERSION_A = TWENTY_CURRENT_VERSION;
|
||||
const VERSION_B = TWENTY_PREVIOUS_VERSIONS[0];
|
||||
|
||||
const FIXED_TIMESTAMP = 1775000000000;
|
||||
|
||||
@@ -39,7 +44,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'no-changes',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -54,7 +59,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'add-foo-column',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -81,7 +86,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'create-task-table',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -107,7 +112,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'seed-setting',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -122,7 +127,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'update-config',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -141,7 +146,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'update-path',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -156,7 +161,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'auto-generated',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -171,7 +176,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'test',
|
||||
version: '1.20.0',
|
||||
version: VERSION_B,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
});
|
||||
|
||||
@@ -183,7 +188,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'no-changes',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
type: 'slow',
|
||||
});
|
||||
@@ -207,7 +212,7 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'make-column-not-nullable',
|
||||
version: '1.21.0',
|
||||
version: VERSION_A,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
type: 'slow',
|
||||
});
|
||||
@@ -223,13 +228,15 @@ describe('InstanceCommandGenerationService', () => {
|
||||
|
||||
const result = await service.generateInstanceCommand({
|
||||
migrationName: 'backfill-data',
|
||||
version: '1.20.0',
|
||||
version: VERSION_B,
|
||||
timestamp: FIXED_TIMESTAMP,
|
||||
type: 'slow',
|
||||
});
|
||||
|
||||
const versionSlug = VERSION_B.split('.').slice(0, 2).join('-');
|
||||
|
||||
expect(result?.fileName).toBe(
|
||||
'1-20-instance-command-slow-1775000000000-backfill-data.ts',
|
||||
`${versionSlug}-instance-command-slow-${FIXED_TIMESTAMP}-backfill-data.ts`,
|
||||
);
|
||||
expect(result?.className).toBe('BackfillDataSlowInstanceCommand');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user