Skip to content

Commit

Permalink
Remove serverless functions on version archivation (#9535)
Browse files Browse the repository at this point in the history
Fixes twentyhq/core-team-issues#52
- contrary to title, we do not remove serverless functions on workflow
version archivation because serverless fucntion might be used in another
workflow version
- we fix the serverless funciton version displayed in the code step
- we allow test function version in step display right drawer
- we delete serverless function only when serverless function has no
published version
  • Loading branch information
martmull authored Jan 13, 2025
1 parent 8643eaa commit 5783d68
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -591,13 +591,17 @@ describe('should work as expected for the different field types', () => {
],
},
{
not: {
phones: {
primaryPhoneNumber: {
ilike: '%1234567890%',
and: [
{
not: {
phones: {
primaryPhoneNumber: {
ilike: '%1234567890%',
},
},
},
},
},
],
},
{
and: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ const computeFilterRecordGqlOperationFilter = (
],
};
case ViewFilterOperand.DoesNotContain:
return {
return {
and: [
{
not: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ export const isRecordMatchingFilter = ({
case FieldMetadataType.Phones: {
const phonesFilter = filterValue as PhonesFilter;

const keys: (keyof PhonesFilter)[] = [
'primaryPhoneNumber'
];
const keys: (keyof PhonesFilter)[] = ['primaryPhoneNumber'];

return keys.some((key) => {
const value = phonesFilter[key];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ import { useRecoilState } from 'recoil';
import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
import { isDefined } from 'twenty-ui';

export const useTestServerlessFunction = (
serverlessFunctionId: string,
callback?: (testResult: object) => void,
) => {
export const useTestServerlessFunction = ({
serverlessFunctionId,
serverlessFunctionVersion = 'draft',
callback,
}: {
serverlessFunctionId: string;
serverlessFunctionVersion?: string;
callback?: (testResult: object) => void;
}) => {
const { executeOneServerlessFunction } = useExecuteOneServerlessFunction();
const [serverlessFunctionTestData, setServerlessFunctionTestData] =
useRecoilState(serverlessFunctionTestDataFamilyState(serverlessFunctionId));
Expand All @@ -15,7 +20,7 @@ export const useTestServerlessFunction = (
const result = await executeOneServerlessFunction({
id: serverlessFunctionId,
payload: serverlessFunctionTestData.input,
version: 'draft',
version: serverlessFunctionVersion,
});

if (isDefined(result?.data?.executeOneServerlessFunction?.data)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('useServerlessFunctionUpdateFormState', () => {
},
);
const { result } = renderHook(
() => useServerlessFunctionUpdateFormState(serverlessFunctionId),
() => useServerlessFunctionUpdateFormState({ serverlessFunctionId }),
{
wrapper: RecoilRoot,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ type SetServerlessFunctionFormValues = Dispatch<
SetStateAction<ServerlessFunctionFormValues>
>;

export const useServerlessFunctionUpdateFormState = (
serverlessFunctionId: string,
): {
export const useServerlessFunctionUpdateFormState = ({
serverlessFunctionId,
serverlessFunctionVersion = 'draft',
}: {
serverlessFunctionId: string;
serverlessFunctionVersion?: string;
}): {
formValues: ServerlessFunctionFormValues;
setFormValues: SetServerlessFunctionFormValues;
loading: boolean;
Expand All @@ -43,7 +47,7 @@ export const useServerlessFunctionUpdateFormState = (

const { loading } = useGetOneServerlessFunctionSourceCode({
id: serverlessFunctionId,
version: 'draft',
version: serverlessFunctionVersion,
onCompleted: (data: FindOneServerlessFunctionSourceCodeQuery) => {
const newState = {
code: data?.getServerlessFunctionSourceCode || undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export const WorkflowEditActionFormServerlessFunction = ({
actionOptions,
}: WorkflowEditActionFormServerlessFunctionProps) => {
const serverlessFunctionId = action.settings.input.serverlessFunctionId;
const serverlessFunctionVersion =
action.settings.input.serverlessFunctionVersion;
const theme = useTheme();
const tabListId = `${WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID}_${serverlessFunctionId}`;
const { activeTabId, setActiveTabId } = useTabList(tabListId);
Expand All @@ -99,7 +101,10 @@ export const WorkflowEditActionFormServerlessFunction = ({
);

const { formValues, setFormValues, loading } =
useServerlessFunctionUpdateFormState(serverlessFunctionId);
useServerlessFunctionUpdateFormState({
serverlessFunctionId,
serverlessFunctionVersion,
});

const updateOutputSchemaFromTestResult = async (testResult: object) => {
if (actionOptions.readonly === true) {
Expand All @@ -112,10 +117,11 @@ export const WorkflowEditActionFormServerlessFunction = ({
});
};

const { testServerlessFunction } = useTestServerlessFunction(
const { testServerlessFunction } = useTestServerlessFunction({
serverlessFunctionId,
updateOutputSchemaFromTestResult,
);
serverlessFunctionVersion,
callback: updateOutputSchemaFromTestResult,
});

const handleSave = useDebouncedCallback(async () => {
await updateOneServerlessFunction({
Expand Down Expand Up @@ -314,7 +320,6 @@ export const WorkflowEditActionFormServerlessFunction = ({
<WorkflowEditActionFormServerlessFunctionFields
functionInput={serverlessFunctionTestData.input}
onInputChange={handleTestInputChange}
readonly={actionOptions.readonly}
/>
<StyledCodeEditorContainer>
<InputLabel>Result</InputLabel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ export const SettingsServerlessFunctionDetail = () => {
useUpdateOneServerlessFunction(serverlessFunctionId);
const { publishOneServerlessFunction } = usePublishOneServerlessFunction();
const { formValues, setFormValues, loading } =
useServerlessFunctionUpdateFormState(serverlessFunctionId);
const { testServerlessFunction } =
useTestServerlessFunction(serverlessFunctionId);
useServerlessFunctionUpdateFormState({ serverlessFunctionId });
const { testServerlessFunction } = useTestServerlessFunction({
serverlessFunctionId,
});
const { code: latestVersionCode } = useGetOneServerlessFunctionSourceCode({
id: serverlessFunctionId,
version: 'latest',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { basename, dirname, join } from 'path';

import deepEqual from 'deep-equal';
import { Repository } from 'typeorm';
import { IsNull, Not, Repository } from 'typeorm';

import { FileStorageExceptionCode } from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception';
import { ServerlessExecuteResult } from 'src/engine/core-modules/serverless/drivers/interfaces/serverless-driver.interface';
Expand Down Expand Up @@ -58,6 +58,15 @@ export class ServerlessFunctionService {
return this.serverlessFunctionRepository.findBy(where);
}

async hasServerlessFunctionPublishedVersion(serverlessFunctionId: string) {
return await this.serverlessFunctionRepository.exists({
where: {
id: serverlessFunctionId,
latestVersion: Not(IsNull()),
},
});
}

async getServerlessFunctionSourceCode(
workspaceId: string,
id: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,16 @@ export class WorkflowVersionStepWorkspaceService {
}) {
switch (step.type) {
case WorkflowActionType.CODE: {
await this.serverlessFunctionService.deleteOneServerlessFunction({
id: step.settings.input.serverlessFunctionId,
workspaceId,
});

if (
!(await this.serverlessFunctionService.hasServerlessFunctionPublishedVersion(
step.settings.input.serverlessFunctionId,
))
) {
await this.serverlessFunctionService.deleteOneServerlessFunction({
id: step.settings.input.serverlessFunctionId,
workspaceId,
});
}
break;
}
}
Expand Down

0 comments on commit 5783d68

Please sign in to comment.