ci: Fix CI timeout issues (no-changelog) (#5250)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2023-01-26 11:44:50 +01:00 committed by GitHub
parent 54333398ce
commit c8a146ba31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 19 deletions

View file

@ -3,6 +3,9 @@ import express, { Router } from 'express';
import fs from 'fs/promises'; import fs from 'fs/promises';
import path from 'path'; import path from 'path';
import validator from 'validator';
import { middleware as openapiValidatorMiddleware } from 'express-openapi-validator';
import YAML from 'yamljs';
import type { HttpError } from 'express-openapi-validator/dist/framework/types'; import type { HttpError } from 'express-openapi-validator/dist/framework/types';
import type { OpenAPIV3 } from 'openapi-types'; import type { OpenAPIV3 } from 'openapi-types';
import type { JsonObject } from 'swagger-ui-express'; import type { JsonObject } from 'swagger-ui-express';
@ -16,11 +19,9 @@ async function createApiRouter(
version: string, version: string,
openApiSpecPath: string, openApiSpecPath: string,
handlersDirectory: string, handlersDirectory: string,
swaggerThemeCss: string,
publicApiEndpoint: string, publicApiEndpoint: string,
): Promise<Router> { ): Promise<Router> {
const n8nPath = config.getEnv('path'); const n8nPath = config.getEnv('path');
const YAML = await import('yamljs');
const swaggerDocument = YAML.load(openApiSpecPath) as JsonObject; const swaggerDocument = YAML.load(openApiSpecPath) as JsonObject;
// add the server depending on the config so the user can interact with the API // add the server depending on the config so the user can interact with the API
// from the Swagger UI // from the Swagger UI
@ -33,6 +34,8 @@ async function createApiRouter(
if (!config.getEnv('publicApi.swaggerUi.disabled')) { if (!config.getEnv('publicApi.swaggerUi.disabled')) {
const { serveFiles, setup } = await import('swagger-ui-express'); const { serveFiles, setup } = await import('swagger-ui-express');
const swaggerThemePath = path.join(__dirname, 'swaggerTheme.css');
const swaggerThemeCss = await fs.readFile(swaggerThemePath, { encoding: 'utf-8' });
apiController.use( apiController.use(
`/${publicApiEndpoint}/${version}/docs`, `/${publicApiEndpoint}/${version}/docs`,
@ -45,12 +48,10 @@ async function createApiRouter(
); );
} }
const { default: validator } = await import('validator');
const { middleware } = await import('express-openapi-validator');
apiController.use( apiController.use(
`/${publicApiEndpoint}/${version}`, `/${publicApiEndpoint}/${version}`,
express.json(), express.json(),
middleware({ openapiValidatorMiddleware({
apiSpec: openApiSpecPath, apiSpec: openApiSpecPath,
operationHandlers: handlersDirectory, operationHandlers: handlersDirectory,
validateRequests: true, validateRequests: true,
@ -129,15 +130,13 @@ async function createApiRouter(
export const loadPublicApiVersions = async ( export const loadPublicApiVersions = async (
publicApiEndpoint: string, publicApiEndpoint: string,
): Promise<{ apiRouters: express.Router[]; apiLatestVersion: number }> => { ): Promise<{ apiRouters: express.Router[]; apiLatestVersion: number }> => {
const swaggerThemePath = path.join(__dirname, 'swaggerTheme.css');
const folders = await fs.readdir(__dirname); const folders = await fs.readdir(__dirname);
const css = (await fs.readFile(swaggerThemePath)).toString();
const versions = folders.filter((folderName) => folderName.startsWith('v')); const versions = folders.filter((folderName) => folderName.startsWith('v'));
const apiRouters = await Promise.all( const apiRouters = await Promise.all(
versions.map(async (version) => { versions.map(async (version) => {
const openApiPath = path.join(__dirname, version, 'openapi.yml'); const openApiPath = path.join(__dirname, version, 'openapi.yml');
return createApiRouter(version, openApiPath, __dirname, css, publicApiEndpoint); return createApiRouter(version, openApiPath, __dirname, publicApiEndpoint);
}), }),
); );

View file

@ -22,6 +22,7 @@ if (inE2ETests) {
} }
if (inTest) { if (inTest) {
process.env.N8N_PUBLIC_API_DISABLED = 'true'; process.env.N8N_PUBLIC_API_DISABLED = 'true';
process.env.N8N_PUBLIC_API_SWAGGERUI_DISABLED = 'true';
} else { } else {
dotenv.config(); dotenv.config();
} }

View file

@ -18,7 +18,11 @@ let credentialOwnerRole: Role;
let saveCredential: SaveCredentialFunction; let saveCredential: SaveCredentialFunction;
beforeAll(async () => { beforeAll(async () => {
app = await utils.initTestServer({ endpointGroups: ['publicApi'], applyAuth: false }); app = await utils.initTestServer({
endpointGroups: ['publicApi'],
applyAuth: false,
enablePublicAPI: true,
});
await testDb.init(); await testDb.init();
utils.initConfigFile(); utils.initConfigFile();

View file

@ -13,7 +13,11 @@ let globalOwnerRole: Role;
let workflowRunner: ActiveWorkflowRunner; let workflowRunner: ActiveWorkflowRunner;
beforeAll(async () => { beforeAll(async () => {
app = await utils.initTestServer({ endpointGroups: ['publicApi'], applyAuth: false }); app = await utils.initTestServer({
endpointGroups: ['publicApi'],
applyAuth: false,
enablePublicAPI: true,
});
await testDb.init(); await testDb.init();
globalOwnerRole = await testDb.getGlobalOwnerRole(); globalOwnerRole = await testDb.getGlobalOwnerRole();
@ -43,7 +47,7 @@ beforeEach(async () => {
}); });
afterEach(async () => { afterEach(async () => {
await workflowRunner.removeAll(); await workflowRunner?.removeAll();
}); });
afterAll(async () => { afterAll(async () => {

View file

@ -17,7 +17,11 @@ let workflowOwnerRole: Role;
let workflowRunner: ActiveWorkflowRunner; let workflowRunner: ActiveWorkflowRunner;
beforeAll(async () => { beforeAll(async () => {
app = await utils.initTestServer({ endpointGroups: ['publicApi'], applyAuth: false }); app = await utils.initTestServer({
endpointGroups: ['publicApi'],
applyAuth: false,
enablePublicAPI: true,
});
await testDb.init(); await testDb.init();
const [fetchedGlobalOwnerRole, fetchedGlobalMemberRole, fetchedWorkflowOwnerRole] = const [fetchedGlobalOwnerRole, fetchedGlobalMemberRole, fetchedWorkflowOwnerRole] =
@ -49,7 +53,7 @@ beforeEach(async () => {
}); });
afterEach(async () => { afterEach(async () => {
await workflowRunner.removeAll(); await workflowRunner?.removeAll();
}); });
afterAll(async () => { afterAll(async () => {

View file

@ -95,7 +95,8 @@ export async function init() {
* Drop test DB, closing bootstrap connection if existing. * Drop test DB, closing bootstrap connection if existing.
*/ */
export async function terminate() { export async function terminate() {
await Db.getConnection().destroy(); const connection = Db.getConnection();
if (connection.isInitialized) await connection.destroy();
} }
/** /**

View file

@ -82,16 +82,15 @@ CredentialTypes(loadNodesAndCredentials);
/** /**
* Initialize a test server. * Initialize a test server.
*
* @param applyAuth Whether to apply auth middleware to test server.
* @param endpointGroups Groups of endpoints to apply to test server.
*/ */
export async function initTestServer({ export async function initTestServer({
applyAuth, applyAuth,
endpointGroups, endpointGroups,
enablePublicAPI = false,
}: { }: {
applyAuth: boolean; applyAuth: boolean;
endpointGroups?: EndpointGroup[]; endpointGroups?: EndpointGroup[];
enablePublicAPI?: boolean;
}) { }) {
const testServer = { const testServer = {
app: express(), app: express(),
@ -124,17 +123,20 @@ export async function initTestServer({
const [routerEndpoints, functionEndpoints] = classifyEndpointGroups(endpointGroups); const [routerEndpoints, functionEndpoints] = classifyEndpointGroups(endpointGroups);
if (routerEndpoints.length) { if (routerEndpoints.length) {
const { apiRouters } = await loadPublicApiVersions(testServer.publicApiEndpoint);
const map: Record<string, express.Router | express.Router[] | any> = { const map: Record<string, express.Router | express.Router[] | any> = {
credentials: { controller: credentialsController, path: 'credentials' }, credentials: { controller: credentialsController, path: 'credentials' },
workflows: { controller: workflowsController, path: 'workflows' }, workflows: { controller: workflowsController, path: 'workflows' },
nodes: { controller: nodesController, path: 'nodes' }, nodes: { controller: nodesController, path: 'nodes' },
license: { controller: licenseController, path: 'license' }, license: { controller: licenseController, path: 'license' },
eventBus: { controller: eventBusRouter, path: 'eventbus' }, eventBus: { controller: eventBusRouter, path: 'eventbus' },
publicApi: apiRouters,
ldap: { controller: ldapController, path: 'ldap' }, ldap: { controller: ldapController, path: 'ldap' },
}; };
if (enablePublicAPI) {
const { apiRouters } = await loadPublicApiVersions(testServer.publicApiEndpoint);
map.publicApi = apiRouters;
}
for (const group of routerEndpoints) { for (const group of routerEndpoints) {
if (group === 'publicApi') { if (group === 'publicApi') {
testServer.app.use(...(map[group] as express.Router[])); testServer.app.use(...(map[group] as express.Router[]));