mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
ci(core): Load config schema after process.env has been overwritten (no-changelog) (#7550)
This commit is contained in:
parent
60314248f4
commit
f0fc5b16d3
|
@ -19,7 +19,12 @@ import type { ServeStaticOptions } from 'serve-static';
|
||||||
import type { FindManyOptions, FindOptionsWhere } from 'typeorm';
|
import type { FindManyOptions, FindOptionsWhere } from 'typeorm';
|
||||||
import { Not, In } from 'typeorm';
|
import { Not, In } from 'typeorm';
|
||||||
|
|
||||||
import { LoadMappingOptions, LoadNodeParameterOptions, LoadNodeListSearch } from 'n8n-core';
|
import {
|
||||||
|
LoadMappingOptions,
|
||||||
|
LoadNodeParameterOptions,
|
||||||
|
LoadNodeListSearch,
|
||||||
|
InstanceSettings,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
INodeCredentials,
|
INodeCredentials,
|
||||||
|
@ -46,7 +51,6 @@ import { getSharedWorkflowIds } from '@/WorkflowHelpers';
|
||||||
import { workflowsController } from '@/workflows/workflows.controller';
|
import { workflowsController } from '@/workflows/workflows.controller';
|
||||||
import {
|
import {
|
||||||
EDITOR_UI_DIST_DIR,
|
EDITOR_UI_DIST_DIR,
|
||||||
GENERATED_STATIC_DIR,
|
|
||||||
inDevelopment,
|
inDevelopment,
|
||||||
inE2ETests,
|
inE2ETests,
|
||||||
N8N_VERSION,
|
N8N_VERSION,
|
||||||
|
@ -951,11 +955,12 @@ export class Server extends AbstractServer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { staticCacheDir } = Container.get(InstanceSettings);
|
||||||
if (frontendService) {
|
if (frontendService) {
|
||||||
const staticOptions: ServeStaticOptions = {
|
const staticOptions: ServeStaticOptions = {
|
||||||
cacheControl: false,
|
cacheControl: false,
|
||||||
setHeaders: (res: express.Response, path: string) => {
|
setHeaders: (res: express.Response, path: string) => {
|
||||||
const isIndex = path === pathJoin(GENERATED_STATIC_DIR, 'index.html');
|
const isIndex = path === pathJoin(staticCacheDir, 'index.html');
|
||||||
const cacheControl = isIndex
|
const cacheControl = isIndex
|
||||||
? 'no-cache, no-store, must-revalidate'
|
? 'no-cache, no-store, must-revalidate'
|
||||||
: 'max-age=86400, immutable';
|
: 'max-age=86400, immutable';
|
||||||
|
@ -981,7 +986,7 @@ export class Server extends AbstractServer {
|
||||||
|
|
||||||
this.app.use(
|
this.app.use(
|
||||||
'/',
|
'/',
|
||||||
express.static(GENERATED_STATIC_DIR),
|
express.static(staticCacheDir),
|
||||||
express.static(EDITOR_UI_DIST_DIR, staticOptions),
|
express.static(EDITOR_UI_DIST_DIR, staticOptions),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -991,7 +996,7 @@ export class Server extends AbstractServer {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.app.use('/', express.static(GENERATED_STATIC_DIR));
|
this.app.use('/', express.static(staticCacheDir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
||||||
import * as Db from '@/Db';
|
import * as Db from '@/Db';
|
||||||
import * as GenericHelpers from '@/GenericHelpers';
|
import * as GenericHelpers from '@/GenericHelpers';
|
||||||
import { Server } from '@/Server';
|
import { Server } from '@/Server';
|
||||||
import { EDITOR_UI_DIST_DIR, GENERATED_STATIC_DIR, LICENSE_FEATURES } from '@/constants';
|
import { EDITOR_UI_DIST_DIR, LICENSE_FEATURES } from '@/constants';
|
||||||
import { eventBus } from '@/eventbus';
|
import { eventBus } from '@/eventbus';
|
||||||
import { BaseCommand } from './BaseCommand';
|
import { BaseCommand } from './BaseCommand';
|
||||||
import { InternalHooks } from '@/InternalHooks';
|
import { InternalHooks } from '@/InternalHooks';
|
||||||
|
@ -169,10 +169,11 @@ export class Start extends BaseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
const closingTitleTag = '</title>';
|
const closingTitleTag = '</title>';
|
||||||
|
const { staticCacheDir } = this.instanceSettings;
|
||||||
const compileFile = async (fileName: string) => {
|
const compileFile = async (fileName: string) => {
|
||||||
const filePath = path.join(EDITOR_UI_DIST_DIR, fileName);
|
const filePath = path.join(EDITOR_UI_DIST_DIR, fileName);
|
||||||
if (/(index\.html)|.*\.(js|css)/.test(filePath) && existsSync(filePath)) {
|
if (/(index\.html)|.*\.(js|css)/.test(filePath) && existsSync(filePath)) {
|
||||||
const destFile = path.join(GENERATED_STATIC_DIR, fileName);
|
const destFile = path.join(staticCacheDir, fileName);
|
||||||
await mkdir(path.dirname(destFile), { recursive: true });
|
await mkdir(path.dirname(destFile), { recursive: true });
|
||||||
const streams = [
|
const streams = [
|
||||||
createReadStream(filePath, 'utf-8'),
|
createReadStream(filePath, 'utf-8'),
|
||||||
|
|
|
@ -2,7 +2,6 @@ import convict from 'convict';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { setGlobalState } from 'n8n-workflow';
|
import { setGlobalState } from 'n8n-workflow';
|
||||||
import { schema } from './schema';
|
|
||||||
import { inTest, inE2ETests } from '@/constants';
|
import { inTest, inE2ETests } from '@/constants';
|
||||||
|
|
||||||
if (inE2ETests) {
|
if (inE2ETests) {
|
||||||
|
@ -25,6 +24,8 @@ if (inE2ETests) {
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load schema after process.env has been overwritten
|
||||||
|
import { schema } from './schema';
|
||||||
const config = convict(schema, { args: [] });
|
const config = convict(schema, { args: [] });
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { resolve, join, dirname } from 'path';
|
import { resolve, join, dirname } from 'path';
|
||||||
import { Container } from 'typedi';
|
|
||||||
import type { n8n } from 'n8n-core';
|
import type { n8n } from 'n8n-core';
|
||||||
import { InstanceSettings } from 'n8n-core';
|
|
||||||
import { jsonParse } from 'n8n-workflow';
|
import { jsonParse } from 'n8n-workflow';
|
||||||
|
|
||||||
const { NODE_ENV, E2E_TESTS } = process.env;
|
const { NODE_ENV, E2E_TESTS } = process.env;
|
||||||
|
@ -17,10 +15,6 @@ export const CUSTOM_API_CALL_KEY = '__CUSTOM_API_CALL__';
|
||||||
export const CLI_DIR = resolve(__dirname, '..');
|
export const CLI_DIR = resolve(__dirname, '..');
|
||||||
export const TEMPLATES_DIR = join(CLI_DIR, 'templates');
|
export const TEMPLATES_DIR = join(CLI_DIR, 'templates');
|
||||||
export const NODES_BASE_DIR = dirname(require.resolve('n8n-nodes-base'));
|
export const NODES_BASE_DIR = dirname(require.resolve('n8n-nodes-base'));
|
||||||
export const GENERATED_STATIC_DIR = join(
|
|
||||||
Container.get(InstanceSettings).userHome,
|
|
||||||
'.cache/n8n/public',
|
|
||||||
);
|
|
||||||
export const EDITOR_UI_DIST_DIR = join(dirname(require.resolve('n8n-editor-ui')), 'dist');
|
export const EDITOR_UI_DIST_DIR = join(dirname(require.resolve('n8n-editor-ui')), 'dist');
|
||||||
|
|
||||||
export function getN8nPackageJson() {
|
export function getN8nPackageJson() {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type {
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { InstanceSettings } from 'n8n-core';
|
import { InstanceSettings } from 'n8n-core';
|
||||||
|
|
||||||
import { GENERATED_STATIC_DIR, LICENSE_FEATURES } from '@/constants';
|
import { LICENSE_FEATURES } from '@/constants';
|
||||||
import { CredentialsOverwrites } from '@/CredentialsOverwrites';
|
import { CredentialsOverwrites } from '@/CredentialsOverwrites';
|
||||||
import { CredentialTypes } from '@/CredentialTypes';
|
import { CredentialTypes } from '@/CredentialTypes';
|
||||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||||
|
@ -205,8 +205,9 @@ export class FrontendService {
|
||||||
async generateTypes() {
|
async generateTypes() {
|
||||||
this.overwriteCredentialsProperties();
|
this.overwriteCredentialsProperties();
|
||||||
|
|
||||||
|
const { staticCacheDir } = this.instanceSettings;
|
||||||
// pre-render all the node and credential types as static json files
|
// pre-render all the node and credential types as static json files
|
||||||
await mkdir(path.join(GENERATED_STATIC_DIR, 'types'), { recursive: true });
|
await mkdir(path.join(staticCacheDir, 'types'), { recursive: true });
|
||||||
const { credentials, nodes } = this.loadNodesAndCredentials.types;
|
const { credentials, nodes } = this.loadNodesAndCredentials.types;
|
||||||
this.writeStaticJSON('nodes', nodes);
|
this.writeStaticJSON('nodes', nodes);
|
||||||
this.writeStaticJSON('credentials', credentials);
|
this.writeStaticJSON('credentials', credentials);
|
||||||
|
@ -303,7 +304,8 @@ export class FrontendService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private writeStaticJSON(name: string, data: INodeTypeBaseDescription[] | ICredentialType[]) {
|
private writeStaticJSON(name: string, data: INodeTypeBaseDescription[] | ICredentialType[]) {
|
||||||
const filePath = path.join(GENERATED_STATIC_DIR, `types/${name}.json`);
|
const { staticCacheDir } = this.instanceSettings;
|
||||||
|
const filePath = path.join(staticCacheDir, `types/${name}.json`);
|
||||||
const stream = createWriteStream(filePath, 'utf-8');
|
const stream = createWriteStream(filePath, 'utf-8');
|
||||||
stream.write('[\n');
|
stream.write('[\n');
|
||||||
data.forEach((entry, index) => {
|
data.forEach((entry, index) => {
|
||||||
|
|
|
@ -36,6 +36,7 @@ afterEach(() => {
|
||||||
|
|
||||||
test('should not init license if instance is follower in multi-main scenario', async () => {
|
test('should not init license if instance is follower in multi-main scenario', async () => {
|
||||||
config.set('executions.mode', 'queue');
|
config.set('executions.mode', 'queue');
|
||||||
|
config.set('endpoints.disableUi', true);
|
||||||
config.set('leaderSelection.enabled', true);
|
config.set('leaderSelection.enabled', true);
|
||||||
|
|
||||||
jest.spyOn(MultiMainInstancePublisher.prototype, 'isFollower', 'get').mockReturnValue(true);
|
jest.spyOn(MultiMainInstancePublisher.prototype, 'isFollower', 'get').mockReturnValue(true);
|
||||||
|
|
|
@ -16,11 +16,14 @@ type Settings = ReadOnlySettings & WritableSettings;
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class InstanceSettings {
|
export class InstanceSettings {
|
||||||
readonly userHome = this.getUserHome();
|
private readonly userHome = this.getUserHome();
|
||||||
|
|
||||||
/** The path to the n8n folder in which all n8n related data gets saved */
|
/** The path to the n8n folder in which all n8n related data gets saved */
|
||||||
readonly n8nFolder = path.join(this.userHome, '.n8n');
|
readonly n8nFolder = path.join(this.userHome, '.n8n');
|
||||||
|
|
||||||
|
/** The path to the folder where all generated static assets are copied to */
|
||||||
|
readonly staticCacheDir = path.join(this.userHome, '.cache/n8n/public');
|
||||||
|
|
||||||
/** The path to the folder containing custom nodes and credentials */
|
/** The path to the folder containing custom nodes and credentials */
|
||||||
readonly customExtensionDir = path.join(this.n8nFolder, 'custom');
|
readonly customExtensionDir = path.join(this.n8nFolder, 'custom');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue