diff --git a/.changeset/wild-buses-notice.md b/.changeset/wild-buses-notice.md new file mode 100644 index 0000000000..7c67ec685b --- /dev/null +++ b/.changeset/wild-buses-notice.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Added the option to skip database migrations by setting `skipMigrations: true` in options. This can be done globally in the database config or by plugin id. diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index fee8846c4b..35de7ccdac 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -375,6 +375,108 @@ export interface Config { }; }; + /** Database connection configuration, select base database type using the `client` field */ + database: { + /** Default database client to use */ + client: 'better-sqlite3' | 'sqlite3' | 'pg'; + /** + * Base database connection string, or object with individual connection properties + * @visibility secret + */ + connection: + | string + | { + /** + * Password that belongs to the client User + * @visibility secret + */ + password?: string; + /** + * Other connection settings + */ + [key: string]: unknown; + }; + /** Database name prefix override */ + prefix?: string; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to true if unspecified. + */ + ensureExists?: boolean; + /** + * Whether to ensure the given database schema exists by creating it if it does not. + * Defaults to false if unspecified. + * + * NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema + */ + ensureSchemaExists?: boolean; + /** + * How plugins databases are managed/divided in the provided database instance. + * + * `database` -> Plugins are each given their own database to manage their schemas/tables. + * + * `schema` -> Plugins will be given their own schema (in the specified/default database) + * to manage their tables. + * + * NOTE: Currently only supported by the `pg` client. + * + * @default database + */ + pluginDivisionMode?: 'database' | 'schema'; + /** Configures the ownership of newly created schemas in pg databases. */ + role?: string; + /** + * Skip running database migrations. + * NOTE: Currently only supported by the `pg` client. + */ + skipMigrations?: boolean; + /** + * Arbitrary config object to pass to knex when initializing + * (https://knexjs.org/#Installation-client). Most notable is the debug + * and asyncStackTraces booleans + */ + knexConfig?: object; + /** Plugin specific database configuration and client override */ + plugin?: { + [pluginId: string]: { + /** Database client override */ + client?: 'better-sqlite3' | 'sqlite3' | 'pg'; + /** + * Database connection string or Knex object override + * @visibility secret + */ + connection?: string | object; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to base config if unspecified. + */ + ensureExists?: boolean; + /** + * Whether to ensure the given database schema exists by creating it if it does not. + * Defaults to false if unspecified. + * + * NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema + */ + ensureSchemaExists?: boolean; + /** + * Arbitrary config object to pass to knex when initializing + * (https://knexjs.org/#Installation-client). Most notable is the + * debug and asyncStackTraces booleans. + * + * This is merged recursively into the base knexConfig + */ + knexConfig?: object; + /** Configures the ownership of newly created schemas in pg databases. */ + role?: string; + /** + * Skip running database migrations. + * NOTE: Currently only supported by the `pg` client. + */ + skipMigrations?: boolean; + }; + }; + }; + /** * Options used by the default discovery service. */ diff --git a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts index 347ec742c0..630dfa6061 100644 --- a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts +++ b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts @@ -107,9 +107,15 @@ describe('DatabaseManagerImpl', () => { }); const impl2 = new DatabaseManagerImpl( - new ConfigReader({ client: 'pg' }), - { pg: connector }, - { migrations: { skip: true } }, + new ConfigReader({ + client: 'pg', + backend: { + database: { plugin: { plugin1: { skipMigrations: true } } }, + }, + }), + { + pg: connector, + }, ); expect((await impl1.forPlugin('plugin1')).migrations).toEqual({ @@ -119,5 +125,23 @@ describe('DatabaseManagerImpl', () => { expect((await impl2.forPlugin('plugin1')).migrations).toEqual({ skip: true, }); + + const impl3 = new DatabaseManagerImpl( + new ConfigReader({ + client: 'pg', + backend: { + database: { + skipMigrations: true, + plugin: { plugin1: { skipMigrations: false } }, + }, + }, + }), + { + pg: connector, + }, + ); + expect((await impl3.forPlugin('plugin1')).migrations).toEqual({ + skip: true, + }); }); }); diff --git a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts index 7e3adf17df..f756e11aac 100644 --- a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts +++ b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts @@ -41,7 +41,6 @@ function pluginPath(pluginId: string): string { * @public */ export type DatabaseManagerOptions = { - migrations?: DatabaseService['migrations']; logger?: LoggerService; }; @@ -86,7 +85,16 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { ); } const getClient = () => this.getDatabase(pluginId, connector, deps); - const migrations = { skip: false, ...this.options?.migrations }; + + const migrationConfig = + this.config.getOptionalBoolean('backend.database.skipMigrations') || + this.config.getOptionalBoolean( + `backend.database.plugin.${pluginId}.skipMigrations`, + ); + const migrations = { + skip: migrationConfig || false, + }; + return { getClient, migrations }; }