Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bed46f12df | |||
| 26709bcc43 | |||
| 35817d5fae | |||
| 0a75cbd06c | |||
| 3e731da69c |
@@ -22,6 +22,7 @@ setup_and_migrate_db() {
|
||||
|
||||
# Run setup and migration scripts
|
||||
NODE_OPTIONS="--max-old-space-size=1500" tsx ./scripts/setup-db.ts
|
||||
yarn database:migrate:prod
|
||||
fi
|
||||
|
||||
yarn command:prod upgrade
|
||||
|
||||
+17
@@ -57,6 +57,7 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
}
|
||||
|
||||
private async checkIfFileIsFound(path: string, workspaceId: string) {
|
||||
this.logger.log(`Checking if file is found ${path}`);
|
||||
if (path.startsWith('https://')) return true; // seed data
|
||||
|
||||
try {
|
||||
@@ -70,14 +71,18 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
error instanceof FileStorageException &&
|
||||
error.code === FileStorageExceptionCode.FILE_NOT_FOUND
|
||||
) {
|
||||
this.logger.log(`File not found`);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.logger.log(`File found`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async cleanWorkspaceLogo(workspaceId: string, dryRun: boolean) {
|
||||
this.logger.log(`Cleaning workspace logo for workspace ${workspaceId}`);
|
||||
const workspace = await this.workspaceRepository.findOneOrFail({
|
||||
where: {
|
||||
id: workspaceId,
|
||||
@@ -86,6 +91,8 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
|
||||
if (!isNonEmptyString(workspace.logo)) return;
|
||||
|
||||
this.logger.log(`Processing workspace logo for workspace ${workspace.id}`);
|
||||
|
||||
const isFileFound = await this.checkIfFileIsFound(
|
||||
workspace.logo,
|
||||
workspace.id,
|
||||
@@ -104,6 +111,7 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
}
|
||||
|
||||
private async softDeleteAttachments(workspaceId: string, dryRun: boolean) {
|
||||
this.logger.log(`Cleaning attachments for workspace ${workspaceId}`);
|
||||
const attachmentRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<AttachmentWorkspaceEntity>(
|
||||
workspaceId,
|
||||
@@ -122,6 +130,7 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
|
||||
const attachmentIdsToSoftDeleteChunk = await Promise.all(
|
||||
attachmentsChunk.map(async (attachment) => {
|
||||
this.logger.log(`Processing attachment ${attachment.id}`);
|
||||
const isFileFound = await this.checkIfFileIsFound(
|
||||
attachment.fullPath,
|
||||
workspaceId,
|
||||
@@ -150,6 +159,9 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
workspaceId: string,
|
||||
dryRun: boolean,
|
||||
) {
|
||||
this.logger.log(
|
||||
`Cleaning workspace members avatarUrl for workspace ${workspaceId}`,
|
||||
);
|
||||
const workspaceMemberRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>(
|
||||
workspaceId,
|
||||
@@ -164,6 +176,8 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
const workspaceMemberIdsToUpdate: string[] = [];
|
||||
|
||||
for (const workspaceMember of workspaceMembers) {
|
||||
this.logger.log(`Processing workspaceMember ${workspaceMember.id}`);
|
||||
|
||||
const isFileFound = await this.checkIfFileIsFound(
|
||||
workspaceMember.avatarUrl,
|
||||
workspaceId,
|
||||
@@ -187,6 +201,7 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
}
|
||||
|
||||
private async cleanPeopleAvatarUrl(workspaceId: string, dryRun: boolean) {
|
||||
this.logger.log(`Cleaning people avatarUrl for workspace ${workspaceId}`);
|
||||
const personRepository =
|
||||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<PersonWorkspaceEntity>(
|
||||
workspaceId,
|
||||
@@ -201,6 +216,8 @@ export class CleanNotFoundFilesCommand extends ActiveOrSuspendedWorkspacesMigrat
|
||||
const personIdsToUpdate: string[] = [];
|
||||
|
||||
for (const person of people) {
|
||||
this.logger.log('Processing person', person.id);
|
||||
|
||||
const isFileFound = await this.checkIfFileIsFound(
|
||||
person.avatarUrl,
|
||||
workspaceId,
|
||||
|
||||
+19
-36
@@ -69,20 +69,11 @@ export class DatabaseMigrationService {
|
||||
});
|
||||
}
|
||||
|
||||
async shouldRunMigrationsIfAllWorkspaceAreAboveVersion0_53(): Promise<boolean> {
|
||||
const coreWorkspaceSchemaExists = await this.checkCoreWorkspaceExists();
|
||||
async shouldSkipUpgradeIfFreshInstallation(): Promise<boolean> {
|
||||
const activeWorkspaceOrSuspendedWorkspaceCount =
|
||||
await this.loadActiveOrSuspendedWorkspace();
|
||||
|
||||
if (!coreWorkspaceSchemaExists) {
|
||||
this.logger.log(
|
||||
'core.workspace does not exist. Running migrations for fresh installation.',
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
this.logger.log('Not a first installation, checking workspace versions...');
|
||||
|
||||
return await this.areAllWorkspacesAboveVersion0_53();
|
||||
return activeWorkspaceOrSuspendedWorkspaceCount.length === 0;
|
||||
}
|
||||
|
||||
async runMigrations(): Promise<void> {
|
||||
@@ -114,26 +105,7 @@ export class DatabaseMigrationService {
|
||||
}
|
||||
}
|
||||
|
||||
private async checkCoreWorkspaceExists(): Promise<boolean> {
|
||||
try {
|
||||
const result = await this.workspaceRepository.query(`
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'core'
|
||||
AND table_name = 'workspace'
|
||||
);
|
||||
`);
|
||||
|
||||
return result[0].exists;
|
||||
} catch (error) {
|
||||
this.logger.error('Error checking core.workspace existence:', error);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async areAllWorkspacesAboveVersion0_53(): Promise<boolean> {
|
||||
public async areAllWorkspacesAboveVersion0_53(): Promise<boolean> {
|
||||
try {
|
||||
const allActiveOrSuspendedWorkspaces =
|
||||
await this.loadActiveOrSuspendedWorkspace();
|
||||
@@ -293,10 +265,21 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
passedParams: string[],
|
||||
options: ActiveOrSuspendedWorkspacesMigrationCommandOptions,
|
||||
): Promise<void> {
|
||||
const shouldRunMigrateAsPartOfUpgrade =
|
||||
await this.databaseMigrationService.shouldRunMigrationsIfAllWorkspaceAreAboveVersion0_53();
|
||||
const shouldSkipUpgradeIfFreshInstallation =
|
||||
await this.databaseMigrationService.shouldSkipUpgradeIfFreshInstallation();
|
||||
|
||||
if (!shouldRunMigrateAsPartOfUpgrade) {
|
||||
if (shouldSkipUpgradeIfFreshInstallation) {
|
||||
this.logger.log(
|
||||
chalk.blue('Fresh installation detected, skipping migration'),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldPreventFromUpgradingIfWorkspaceIsBelowVersion0_53 =
|
||||
!(await this.databaseMigrationService.areAllWorkspacesAboveVersion0_53());
|
||||
|
||||
if (shouldPreventFromUpgradingIfWorkspaceIsBelowVersion0_53) {
|
||||
this.logger.log(
|
||||
chalk.red(
|
||||
'Not able to run migrate command, aborting the whole migrate-upgrade operation',
|
||||
|
||||
+18
-8
@@ -28,23 +28,33 @@ export class WorkflowTriggerController {
|
||||
|
||||
@Post('workflows/:workspaceId/:workflowId')
|
||||
async runWorkflowByPostRequest(
|
||||
@Param('workspaceId') workspaceId: string,
|
||||
@Param('workflowId') workflowId: string,
|
||||
@Req() request: Request,
|
||||
) {
|
||||
return await this.runWorkflow({ workflowId, payload: request.body || {} });
|
||||
return await this.runWorkflow({
|
||||
workflowId,
|
||||
payload: request.body || {},
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
@Get('workflows/:workspaceId/:workflowId')
|
||||
async runWorkflowByGetRequest(@Param('workflowId') workflowId: string) {
|
||||
return await this.runWorkflow({ workflowId });
|
||||
async runWorkflowByGetRequest(
|
||||
@Param('workspaceId') workspaceId: string,
|
||||
@Param('workflowId') workflowId: string,
|
||||
) {
|
||||
return await this.runWorkflow({ workflowId, workspaceId });
|
||||
}
|
||||
|
||||
private async runWorkflow({
|
||||
workflowId,
|
||||
payload,
|
||||
workspaceId,
|
||||
}: {
|
||||
workflowId: string;
|
||||
payload?: object;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
const workflowRepository =
|
||||
await this.twentyORMManager.getRepository<WorkflowWorkspaceEntity>(
|
||||
@@ -57,7 +67,7 @@ export class WorkflowTriggerController {
|
||||
|
||||
if (!isDefined(workflow)) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow not found',
|
||||
`[Webhook trigger] Workflow ${workflowId} not found in workspace ${workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
@@ -67,7 +77,7 @@ export class WorkflowTriggerController {
|
||||
workflow.lastPublishedVersionId === ''
|
||||
) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow has not been activated',
|
||||
`[Webhook trigger] Workflow ${workflowId} has not been activated in workspace ${workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_STATUS,
|
||||
);
|
||||
}
|
||||
@@ -82,21 +92,21 @@ export class WorkflowTriggerController {
|
||||
|
||||
if (!isDefined(workflowVersion)) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow version not found',
|
||||
`[Webhook trigger] No workflow version activated for workflow ${workflowId} in workspace ${workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_VERSION,
|
||||
);
|
||||
}
|
||||
|
||||
if (workflowVersion.trigger?.type !== WorkflowTriggerType.WEBHOOK) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow does not have a Webhook trigger',
|
||||
`[Webhook trigger] Workflow ${workflowId} does not have a Webhook trigger in workspace ${workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_TRIGGER,
|
||||
);
|
||||
}
|
||||
|
||||
if (workflowVersion.status !== WorkflowVersionStatus.ACTIVE) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow version is not active',
|
||||
`[Webhook trigger] Workflow version ${workflowVersion.id} is not active in workspace ${workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_STATUS,
|
||||
);
|
||||
}
|
||||
|
||||
+4
-4
@@ -52,14 +52,14 @@ export class WorkflowTriggerJob {
|
||||
|
||||
if (!workflow) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow not found',
|
||||
`Workflow ${data.workflowId} not found in workspace ${data.workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
if (!workflow.lastPublishedVersionId) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow has no published version',
|
||||
`Workflow ${data.workflowId} has no published version in workspace ${data.workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.INTERNAL_ERROR,
|
||||
);
|
||||
}
|
||||
@@ -75,13 +75,13 @@ export class WorkflowTriggerJob {
|
||||
|
||||
if (!workflowVersion) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow version not found',
|
||||
`Workflow version ${workflow.lastPublishedVersionId} not found in workspace ${data.workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
if (workflowVersion.status !== WorkflowVersionStatus.ACTIVE) {
|
||||
throw new WorkflowTriggerException(
|
||||
'Workflow version is not active',
|
||||
`Workflow version ${workflowVersion.id} is not active in workspace ${data.workspaceId}`,
|
||||
WorkflowTriggerExceptionCode.INTERNAL_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user