feat: Migrate integer primary keys to nanoids (#6345)

* first commit for postgres migration

* (not working)

* sqlite migration

* quicksave

* fix tests

* fix pg test

* fix postgres

* fix variables import

* fix execution saving

* add user settings fix

* change migration to single lines

* patch preferences endpoint

* cleanup

* improve variable import

* cleanup unusued code

* Update packages/cli/src/PublicApi/v1/handlers/workflows/workflows.handler.ts

Co-authored-by: Omar Ajoue <krynble@gmail.com>

* address review notes

* fix var update/import

* refactor: Separate execution data to its own table (#6323)

* wip: Temporary migration process

* refactor: Create boilerplate repository methods for executions

* fix: Lint issues

* refactor: Added search endpoint to repository

* refactor: Make the execution list work again

* wip: Updating how we create and update executions everywhere

* fix: Lint issues and remove most of the direct access to execution model

* refactor: Remove includeWorkflowData flag and fix more tests

* fix: Lint issues

* fix: Fixed ordering of executions for FE, removed transaction when saving execution and removed unnecessary update

* refactor: Add comment about missing feature

* refactor: Refactor counting executions

* refactor: Add migration for other dbms and fix issues found

* refactor: Fix lint issues

* refactor: Remove unnecessary comment and auto inject repo to internal hooks

* refactor: remove type assertion

* fix: Fix broken tests

* fix: Remove unnecessary import

* Remove unnecessary toString() call

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>

* fix: Address comments after review

* refactor: Remove unused import

* fix: Lint issues

* fix: Add correct migration files

---------

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>

* remove null values from credential export

* fix: Fix an issue with queue mode where all running execution would be returned

* fix: Update n8n node to allow for workflow ids with letters

* set upstream on set branch

* remove typo

* add nodeAccess to credentials

* fix unsaved run check for undefined id

* fix(core): Rename version control feature to source control (#6480)

* rename versionControl to sourceControl

* fix source control tooltip wording

---------

Co-authored-by: Romain Minaud <romain.minaud@gmail.com>

* fix(editor): Pay 548 hide the set up version control button (#6485)

* feat(DebugHelper Node): Fix and include in main app (#6406)

* improve node a bit

* fixing continueOnFail() ton contain error in json

* improve pairedItem

* fix random data returning object results

* fix nanoId length typo

* update pnpm-lock file

---------

Co-authored-by: Marcus <marcus@n8n.io>

* fix(editor): Remove setup source control CTA button

* fix(editor): Remove setup source control CTA button

---------

Co-authored-by: Michael Auerswald <michael.auerswald@gmail.com>
Co-authored-by: Marcus <marcus@n8n.io>

* fix(editor): Update source control docs links (#6488)

* feat(DebugHelper Node): Fix and include in main app (#6406)

* improve node a bit

* fixing continueOnFail() ton contain error in json

* improve pairedItem

* fix random data returning object results

* fix nanoId length typo

* update pnpm-lock file

---------

Co-authored-by: Marcus <marcus@n8n.io>

* feat(editor): Replace root events with event bus events (no-changelog) (#6454)

* feat: replace root events with event bus events

* fix: prevent cypress from replacing global with globalThis in import path

* feat: remove emitter mixin

* fix: replace component events with event bus

* fix: fix linting issue

* fix: fix breaking expression switch

* chore: prettify ndv e2e suite code

* fix(editor): Update source control docs links

---------

Co-authored-by: Michael Auerswald <michael.auerswald@gmail.com>
Co-authored-by: Marcus <marcus@n8n.io>
Co-authored-by: Alex Grozav <alex@grozav.com>

* fix tag endpoint regex

---------

Co-authored-by: Omar Ajoue <krynble@gmail.com>
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Romain Minaud <romain.minaud@gmail.com>
Co-authored-by: Csaba Tuncsik <csaba@n8n.io>
Co-authored-by: Marcus <marcus@n8n.io>
Co-authored-by: Alex Grozav <alex@grozav.com>
This commit is contained in:
Michael Auerswald
2023-06-20 19:13:18 +02:00
committed by GitHub
parent da330f0648
commit c3ba0123ad
156 changed files with 3499 additions and 2594 deletions

View File

@@ -21,7 +21,7 @@ import cookieParser from 'cookie-parser';
import express from 'express';
import { engine as expressHandlebars } from 'express-handlebars';
import type { ServeStaticOptions } from 'serve-static';
import type { FindManyOptions } from 'typeorm';
import type { FindManyOptions, FindOptionsWhere } from 'typeorm';
import { Not, In } from 'typeorm';
import type { AxiosRequestConfig } from 'axios';
import axios from 'axios';
@@ -114,7 +114,6 @@ import type {
ICredentialsDb,
ICredentialsOverwrite,
IDiagnosticInfo,
IExecutionFlattedDb,
IExecutionsStopData,
} from '@/Interfaces';
import { ActiveExecutions } from '@/ActiveExecutions';
@@ -167,10 +166,12 @@ import {
isLdapCurrentAuthenticationMethod,
isSamlCurrentAuthenticationMethod,
} from './sso/ssoHelpers';
import { isVersionControlLicensed } from '@/environments/versionControl/versionControlHelper.ee';
import { VersionControlService } from '@/environments/versionControl/versionControl.service.ee';
import { VersionControlController } from '@/environments/versionControl/versionControl.controller.ee';
import { VersionControlPreferencesService } from './environments/versionControl/versionControlPreferences.service.ee';
import { isSourceControlLicensed } from '@/environments/sourceControl/sourceControlHelper.ee';
import { SourceControlService } from '@/environments/sourceControl/sourceControl.service.ee';
import { SourceControlController } from '@/environments/sourceControl/sourceControl.controller.ee';
import { SourceControlPreferencesService } from './environments/sourceControl/sourceControlPreferences.service.ee';
import { ExecutionRepository } from './databases/repositories';
import type { ExecutionEntity } from './databases/entities/ExecutionEntity';
const exec = promisify(callbackExec);
@@ -312,7 +313,7 @@ export class Server extends AbstractServer {
logStreaming: false,
advancedExecutionFilters: false,
variables: false,
versionControl: false,
sourceControl: false,
auditLogs: false,
},
hideUsagePage: config.getEnv('hideUsagePage'),
@@ -430,7 +431,7 @@ export class Server extends AbstractServer {
saml: isSamlLicensed(),
advancedExecutionFilters: isAdvancedExecutionFiltersEnabled(),
variables: isVariablesEnabled(),
versionControl: isVersionControlLicensed(),
sourceControl: isSourceControlLicensed(),
});
if (isLdapEnabled()) {
@@ -467,8 +468,8 @@ export class Server extends AbstractServer {
const mailer = Container.get(UserManagementMailer);
const postHog = this.postHog;
const samlService = Container.get(SamlService);
const versionControlService = Container.get(VersionControlService);
const versionControlPreferencesService = Container.get(VersionControlPreferencesService);
const sourceControlService = Container.get(SourceControlService);
const sourceControlPreferencesService = Container.get(SourceControlPreferencesService);
const controllers: object[] = [
new EventBusController(),
@@ -497,7 +498,7 @@ export class Server extends AbstractServer {
postHog,
}),
new SamlController(samlService),
new VersionControlController(versionControlService, versionControlPreferencesService),
new SourceControlController(sourceControlService, sourceControlPreferencesService),
];
if (isLdapEnabled()) {
@@ -637,15 +638,12 @@ export class Server extends AbstractServer {
this.app.use(`/${this.restEndpoint}/variables`, variablesController);
// ----------------------------------------
// Version Control
// Source Control
// ----------------------------------------
// initialize SamlService if it is licensed, even if not enabled, to
// set up the initial environment
try {
await Container.get(VersionControlService).init();
await Container.get(SourceControlService).init();
} catch (error) {
LoggerProxy.warn(`Version Control initialization failed: ${error.message}`);
LoggerProxy.warn(`Source Control initialization failed: ${error.message}`);
}
// ----------------------------------------
@@ -1154,7 +1152,9 @@ export class Server extends AbstractServer {
if (!currentlyRunningExecutionIds.length) return [];
const findOptions: FindManyOptions<IExecutionFlattedDb> = {
const findOptions: FindManyOptions<ExecutionEntity> & {
where: FindOptionsWhere<ExecutionEntity>;
} = {
select: ['id', 'workflowId', 'mode', 'retryOf', 'startedAt', 'stoppedAt', 'status'],
order: { id: 'DESC' },
where: {
@@ -1170,19 +1170,23 @@ export class Server extends AbstractServer {
if (req.query.filter) {
const { workflowId, status, finished } = jsonParse<any>(req.query.filter);
if (workflowId && sharedWorkflowIds.includes(workflowId)) {
Object.assign(findOptions.where!, { workflowId });
Object.assign(findOptions.where, { workflowId });
} else {
Object.assign(findOptions.where, { workflowId: In(sharedWorkflowIds) });
}
if (status) {
Object.assign(findOptions.where!, { status: In(status) });
Object.assign(findOptions.where, { status: In(status) });
}
if (finished) {
Object.assign(findOptions.where!, { finished });
Object.assign(findOptions.where, { finished });
}
} else {
Object.assign(findOptions.where!, { workflowId: In(sharedWorkflowIds) });
Object.assign(findOptions.where, { workflowId: In(sharedWorkflowIds) });
}
const executions = await Db.collections.Execution.find(findOptions);
const executions = await Container.get(ExecutionRepository).findMultipleExecutions(
findOptions,
);
if (!executions.length) return [];
@@ -1247,14 +1251,16 @@ export class Server extends AbstractServer {
throw new ResponseHelper.NotFoundError('Execution not found');
}
const execution = await Db.collections.Execution.exist({
where: {
id: executionId,
workflowId: In(sharedWorkflowIds),
const fullExecutionData = await Container.get(ExecutionRepository).findSingleExecution(
executionId,
{
where: {
workflowId: In(sharedWorkflowIds),
},
},
});
);
if (!execution) {
if (!fullExecutionData) {
throw new ResponseHelper.NotFoundError('Execution not found');
}
@@ -1292,11 +1298,6 @@ export class Server extends AbstractServer {
await queue.stopJob(job);
}
const executionDb = (await Db.collections.Execution.findOneBy({
id: req.params.id,
})) as IExecutionFlattedDb;
const fullExecutionData = ResponseHelper.unflattenExecutionData(executionDb);
const returnData: IExecutionsStopData = {
mode: fullExecutionData.mode,
startedAt: new Date(fullExecutionData.startedAt),