13058 workflow with code fail to run (#13118)
- update publishOneServerlessFunction so it does not break the workflow if failing - update upgrade documentation to update `docker-compose.yml` when mutated Fixes https://github.com/twentyhq/twenty/issues/13058
This commit is contained in:
@ -163,7 +163,7 @@ export class ServerlessFunctionResolver {
|
|||||||
try {
|
try {
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
return await this.serverlessFunctionService.publishOneServerlessFunction(
|
return await this.serverlessFunctionService.publishOneServerlessFunctionOrFail(
|
||||||
id,
|
id,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -30,6 +30,10 @@ import {
|
|||||||
ServerlessFunctionException,
|
ServerlessFunctionException,
|
||||||
ServerlessFunctionExceptionCode,
|
ServerlessFunctionExceptionCode,
|
||||||
} from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
|
} from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
|
||||||
|
import {
|
||||||
|
WorkflowVersionStepException,
|
||||||
|
WorkflowVersionStepExceptionCode,
|
||||||
|
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ServerlessFunctionService {
|
export class ServerlessFunctionService {
|
||||||
@ -137,7 +141,7 @@ export class ServerlessFunctionService {
|
|||||||
return resultServerlessFunction;
|
return resultServerlessFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
async publishOneServerlessFunction(id: string, workspaceId: string) {
|
async publishOneServerlessFunctionOrFail(id: string, workspaceId: string) {
|
||||||
const existingServerlessFunction =
|
const existingServerlessFunction =
|
||||||
await this.serverlessFunctionRepository.findOneOrFail({
|
await this.serverlessFunctionRepository.findOneOrFail({
|
||||||
where: {
|
where: {
|
||||||
@ -159,10 +163,7 @@ export class ServerlessFunctionService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (deepEqual(latestCode, draftCode)) {
|
if (deepEqual(latestCode, draftCode)) {
|
||||||
throw new ServerlessFunctionException(
|
return existingServerlessFunction;
|
||||||
'Cannot publish a new version when code has not changed',
|
|
||||||
ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_CODE_UNCHANGED,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +175,7 @@ export class ServerlessFunctionService {
|
|||||||
serverlessFunction: existingServerlessFunction,
|
serverlessFunction: existingServerlessFunction,
|
||||||
version: 'draft',
|
version: 'draft',
|
||||||
});
|
});
|
||||||
|
|
||||||
const newFolderPath = getServerlessFolder({
|
const newFolderPath = getServerlessFolder({
|
||||||
serverlessFunction: existingServerlessFunction,
|
serverlessFunction: existingServerlessFunction,
|
||||||
version: newVersion,
|
version: newVersion,
|
||||||
@ -197,9 +199,26 @@ export class ServerlessFunctionService {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.serverlessFunctionRepository.findOneBy({
|
const publishedServerlessFunction =
|
||||||
id: existingServerlessFunction.id,
|
await this.serverlessFunctionRepository.findOneOrFail({
|
||||||
});
|
where: {
|
||||||
|
id,
|
||||||
|
workspaceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// This check should never be thrown, but we encounter some issue with
|
||||||
|
// publishing serverless function in self hosted instances
|
||||||
|
// See https://github.com/twentyhq/twenty/issues/13058
|
||||||
|
// TODO: remove this check when issue solved
|
||||||
|
if (!isDefined(publishedServerlessFunction.latestVersion)) {
|
||||||
|
throw new WorkflowVersionStepException(
|
||||||
|
`Fail to publish serverlessFunction ${publishedServerlessFunction.id}.Received latest version ${publishedServerlessFunction.latestVersion}`,
|
||||||
|
WorkflowVersionStepExceptionCode.FAILURE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return publishedServerlessFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteOneServerlessFunction({
|
async deleteOneServerlessFunction({
|
||||||
|
|||||||
@ -50,7 +50,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mockServerlessFunctionService = {
|
const mockServerlessFunctionService = {
|
||||||
publishOneServerlessFunction: jest.fn(),
|
publishOneServerlessFunctionOrFail: jest.fn(),
|
||||||
findOneOrFail: jest.fn(),
|
findOneOrFail: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -256,6 +256,9 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
mockServerlessFunctionService.findOneOrFail.mockResolvedValue(
|
mockServerlessFunctionService.findOneOrFail.mockResolvedValue(
|
||||||
mockServerlessFunction,
|
mockServerlessFunction,
|
||||||
);
|
);
|
||||||
|
mockServerlessFunctionService.publishOneServerlessFunctionOrFail.mockResolvedValue(
|
||||||
|
mockServerlessFunction,
|
||||||
|
);
|
||||||
|
|
||||||
await job.handle(event);
|
await job.handle(event);
|
||||||
|
|
||||||
@ -264,7 +267,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
mockWorkflowVersionRepository.findOneOrFail,
|
mockWorkflowVersionRepository.findOneOrFail,
|
||||||
).toHaveBeenCalledTimes(1);
|
).toHaveBeenCalledTimes(1);
|
||||||
expect(
|
expect(
|
||||||
mockServerlessFunctionService.publishOneServerlessFunction,
|
mockServerlessFunctionService.publishOneServerlessFunctionOrFail,
|
||||||
).toHaveBeenCalledWith('serverless-1', '1');
|
).toHaveBeenCalledWith('serverless-1', '1');
|
||||||
expect(mockWorkflowVersionRepository.update).toHaveBeenCalledWith('1', {
|
expect(mockWorkflowVersionRepository.update).toHaveBeenCalledWith('1', {
|
||||||
steps: [
|
steps: [
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { Processor } from 'src/engine/core-modules/message-queue/decorators/proc
|
|||||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||||
import { ServerlessFunctionExceptionCode } from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
|
|
||||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
@ -198,33 +197,11 @@ export class WorkflowStatusesUpdateJob {
|
|||||||
const newStep = { ...step };
|
const newStep = { ...step };
|
||||||
|
|
||||||
if (step.type === WorkflowActionType.CODE) {
|
if (step.type === WorkflowActionType.CODE) {
|
||||||
try {
|
const serverlessFunction =
|
||||||
await this.serverlessFunctionService.publishOneServerlessFunction(
|
await this.serverlessFunctionService.publishOneServerlessFunctionOrFail(
|
||||||
step.settings.input.serverlessFunctionId,
|
step.settings.input.serverlessFunctionId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
|
||||||
// publishOneServerlessFunction throws if no change have been
|
|
||||||
// applied between draft and lastPublished version.
|
|
||||||
// If no change have been applied, we just use the same
|
|
||||||
// serverless function version
|
|
||||||
if (
|
|
||||||
e.code !==
|
|
||||||
ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_CODE_UNCHANGED
|
|
||||||
) {
|
|
||||||
this.logger.error(
|
|
||||||
`Error while publishing serverless function '${step.settings.input.serverlessFunctionId}': ${e}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const serverlessFunction =
|
|
||||||
await this.serverlessFunctionRepository.findOneOrFail({
|
|
||||||
where: {
|
|
||||||
id: step.settings.input.serverlessFunctionId,
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const newStepSettings = { ...step.settings };
|
const newStepSettings = { ...step.settings };
|
||||||
|
|
||||||
@ -233,6 +210,7 @@ export class WorkflowStatusesUpdateJob {
|
|||||||
|
|
||||||
newStep.settings = newStepSettings;
|
newStep.settings = newStepSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
newSteps.push(newStep);
|
newSteps.push(newStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -119,6 +119,11 @@ yarn database:migrate:prod
|
|||||||
yarn command:prod upgrade
|
yarn command:prod upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Docker-compose.yml mutation
|
||||||
|
|
||||||
|
This version includes a `docker-compose.yml` mutation to give `worker` service access to the `server-local-data` volume.
|
||||||
|
Please update your local `docker-compose.yml` with [v0.50.0 docker-compose.yml](https://github.com/twentyhq/twenty/blob/v0.50.0/packages/twenty-docker/docker-compose.yml)
|
||||||
|
|
||||||
### v0.43.0 to v0.44.0
|
### v0.43.0 to v0.44.0
|
||||||
|
|
||||||
Upgrade your Twenty instance to use v0.44.0 image
|
Upgrade your Twenty instance to use v0.44.0 image
|
||||||
|
|||||||
Reference in New Issue
Block a user