diff --git a/packages/cli/src/deprecation/__tests__/deprecation.service.test.ts b/packages/cli/src/deprecation/__tests__/deprecation.service.test.ts index 42b8b315ba..591a0348e3 100644 --- a/packages/cli/src/deprecation/__tests__/deprecation.service.test.ts +++ b/packages/cli/src/deprecation/__tests__/deprecation.service.test.ts @@ -3,13 +3,13 @@ import { mockLogger } from '@test/mocking'; import { DeprecationService } from '../deprecation.service'; describe('DeprecationService', () => { - const toTest = (envVar: string, value: string, inUse: boolean) => { + const toTest = (envVar: string, value: string, mustWarn: boolean) => { process.env[envVar] = value; const deprecationService = new DeprecationService(mockLogger()); deprecationService.warn(); - expect(deprecationService.isInUse(envVar)).toBe(inUse); + expect(deprecationService.mustWarn(envVar)).toBe(mustWarn); }; test.each([ @@ -18,16 +18,16 @@ describe('DeprecationService', () => { ['EXECUTIONS_DATA_PRUNE_TIMEOUT', '1', true], ['N8N_CONFIG_FILES', '1', true], ['N8N_SKIP_WEBHOOK_DEREGISTRATION_SHUTDOWN', '1', true], - ])('should detect when %s is in use', (envVar, value, inUse) => { - toTest(envVar, value, inUse); + ])('should detect when %s is in use', (envVar, value, mustWarn) => { + toTest(envVar, value, mustWarn); }); test.each([ ['default', true], ['filesystem', false], ['s3', false], - ])('should handle N8N_BINARY_DATA_MODE as %s', (mode, inUse) => { - toTest('N8N_BINARY_DATA_MODE', mode, inUse); + ])('should handle N8N_BINARY_DATA_MODE as %s', (mode, mustWarn) => { + toTest('N8N_BINARY_DATA_MODE', mode, mustWarn); }); test.each([ @@ -35,7 +35,28 @@ describe('DeprecationService', () => { ['postgresdb', false], ['mysqldb', true], ['mariadb', true], - ])('should handle DB_TYPE as %s', (dbType, inUse) => { - toTest('DB_TYPE', dbType, inUse); + ])('should handle DB_TYPE as %s', (dbType, mustWarn) => { + toTest('DB_TYPE', dbType, mustWarn); + }); + + describe('N8N_RUNNERS_ENABLED', () => { + const envVar = 'N8N_RUNNERS_ENABLED'; + + test.each([ + ['false', true], + ['', true], + ['true', false], + [undefined /* warnIfMissing */, true], + ])('should handle value: %s', (value, mustWarn) => { + if (value === undefined) { + delete process.env[envVar]; + } else { + process.env[envVar] = value; + } + + const deprecationService = new DeprecationService(mockLogger()); + deprecationService.warn(); + expect(deprecationService.mustWarn(envVar)).toBe(mustWarn); + }); }); }); diff --git a/packages/cli/src/deprecation/deprecation.service.ts b/packages/cli/src/deprecation/deprecation.service.ts index 1b2e6c6174..e70cfcd257 100644 --- a/packages/cli/src/deprecation/deprecation.service.ts +++ b/packages/cli/src/deprecation/deprecation.service.ts @@ -12,12 +12,15 @@ type Deprecation = { message: string; /** Function to identify the specific value in the env var that is deprecated. */ - checkValue?: (value: string) => boolean; + checkValue?: (value?: string) => boolean; + + /** Whether to show a deprecation warning if the env var is missing. */ + warnIfMissing?: boolean; }; const SAFE_TO_REMOVE = 'Remove this environment variable; it is no longer needed.'; -/** Responsible for warning about use of deprecated env vars. */ +/** Responsible for warning about deprecations related to env vars. */ @Service() export class DeprecationService { private readonly deprecations: Deprecation[] = [ @@ -39,10 +42,17 @@ export class DeprecationService { envVar: 'N8N_SKIP_WEBHOOK_DEREGISTRATION_SHUTDOWN', message: `n8n no longer deregisters webhooks at startup and shutdown. ${SAFE_TO_REMOVE}`, }, + { + envVar: 'N8N_RUNNERS_ENABLED', + message: + 'Running n8n without task runners is deprecated. Task runners will be turned on by default in a future version. Please set `N8N_RUNNERS_ENABLED=true` to enable task runners now and avoid potential issues in the future. Learn more: https://docs.n8n.io/hosting/configuration/task-runners/', + checkValue: (value?: string) => value?.toLowerCase() !== 'true' && value !== '1', + warnIfMissing: true, + }, ]; - /** Runtime state of deprecated env vars. */ - private readonly state: Record = {}; + /** Runtime state of deprecation-related env vars. */ + private readonly state: Record = {}; constructor(private readonly logger: Logger) {} @@ -50,14 +60,14 @@ export class DeprecationService { this.deprecations.forEach((d) => { const envValue = process.env[d.envVar]; this.state[d.envVar] = { - inUse: d.checkValue - ? envValue !== undefined && d.checkValue(envValue) - : envValue !== undefined, + mustWarn: + (d.warnIfMissing !== undefined && envValue === undefined) || + (d.checkValue ? d.checkValue(envValue) : envValue !== undefined), }; }); - const inUse = Object.entries(this.state) - .filter(([, d]) => d.inUse) + const mustWarn = Object.entries(this.state) + .filter(([, d]) => d.mustWarn) .map(([envVar]) => { const deprecation = this.deprecations.find((d) => d.envVar === envVar); if (!deprecation) { @@ -66,19 +76,19 @@ export class DeprecationService { return deprecation; }); - if (inUse.length === 0) return; + if (mustWarn.length === 0) return; - const header = `The following environment variable${ - inUse.length === 1 ? ' is' : 's are' - } deprecated and will be removed in an upcoming version of n8n. Please take the recommended actions to update your configuration`; - const deprecations = inUse + const header = `There ${ + mustWarn.length === 1 ? 'is a deprecation' : 'are deprecations' + } related to your environment variables. Please take the recommended actions to update your configuration`; + const deprecations = mustWarn .map(({ envVar, message }) => ` - ${envVar} -> ${message}\n`) .join(''); this.logger.warn(`\n${header}:\n${deprecations}`); } - isInUse(envVar: string) { - return this.state[envVar]?.inUse ?? false; + mustWarn(envVar: string) { + return this.state[envVar]?.mustWarn ?? false; } }