diff --git a/packages/cli/src/environments.ee/source-control/__tests__/source-control-helper.ee.test.ts b/packages/cli/src/environments.ee/source-control/__tests__/source-control-helper.ee.test.ts index 29bd09fb0c..5748bf2321 100644 --- a/packages/cli/src/environments.ee/source-control/__tests__/source-control-helper.ee.test.ts +++ b/packages/cli/src/environments.ee/source-control/__tests__/source-control-helper.ee.test.ts @@ -15,11 +15,28 @@ import { getTrackingInformationFromPostPushResult, getTrackingInformationFromPrePushResult, getTrackingInformationFromPullResult, + isWorkflowModified, sourceControlFoldersExistCheck, } from '@/environments.ee/source-control/source-control-helper.ee'; import type { SourceControlPreferencesService } from '@/environments.ee/source-control/source-control-preferences.service.ee'; import type { License } from '@/license'; +import type { SourceControlWorkflowVersionId } from '../types/source-control-workflow-version-id'; + +function createWorkflowVersion( + overrides: Partial = {}, +): SourceControlWorkflowVersionId { + return { + id: 'workflow123', + versionId: 'version1', + filename: 'workflows/workflow123.json', + parentFolderId: 'folder1', + updatedAt: '2023-07-10T10:10:59.000Z', + name: 'Test Workflow', + ...overrides, + }; +} + const pushResult: SourceControlledFile[] = [ { file: 'credential_stubs/kkookWGIeey9K4Kt.json', @@ -252,3 +269,47 @@ describe('Source Control', () => { }); }); }); + +describe('isWorkflowModified', () => { + it('should detect modifications when version IDs differ', () => { + const local = createWorkflowVersion(); + const remote = createWorkflowVersion({ versionId: 'version2' }); + + expect(isWorkflowModified(local, remote)).toBe(true); + }); + + it('should detect modifications when parent folder IDs differ', () => { + const local = createWorkflowVersion(); + const remote = createWorkflowVersion({ parentFolderId: 'folder2' }); + + expect(isWorkflowModified(local, remote)).toBe(true); + }); + + it('should not detect modifications when version IDs and parent folder IDs are the same', () => { + const local = createWorkflowVersion(); + const remote = createWorkflowVersion(); + + expect(isWorkflowModified(local, remote)).toBe(false); + }); + + it('should not consider it modified when remote parent folder ID is undefined', () => { + const local = createWorkflowVersion(); + const remote = createWorkflowVersion({ parentFolderId: undefined }); + + expect(isWorkflowModified(local, remote)).toBe(false); + }); + + it('should detect modifications when parent folder IDs differ and remote parent folder ID is defined', () => { + const local = createWorkflowVersion({ parentFolderId: null }); + const remote = createWorkflowVersion(); + + expect(isWorkflowModified(local, remote)).toBe(true); + }); + + it('should handle null parent folder IDs correctly', () => { + const local = createWorkflowVersion({ parentFolderId: null }); + const remote = createWorkflowVersion({ parentFolderId: null }); + + expect(isWorkflowModified(local, remote)).toBe(false); + }); +}); diff --git a/packages/cli/src/environments.ee/source-control/source-control-helper.ee.ts b/packages/cli/src/environments.ee/source-control/source-control-helper.ee.ts index 1dc436ac6f..bd83b23ca9 100644 --- a/packages/cli/src/environments.ee/source-control/source-control-helper.ee.ts +++ b/packages/cli/src/environments.ee/source-control/source-control-helper.ee.ts @@ -18,6 +18,7 @@ import { } from './constants'; import type { KeyPair } from './types/key-pair'; import type { KeyPairType } from './types/key-pair-type'; +import type { SourceControlWorkflowVersionId } from './types/source-control-workflow-version-id'; export function stringContainsExpression(testString: string): boolean { return /^=.*\{\{.*\}\}/.test(testString); @@ -204,3 +205,17 @@ export function normalizeAndValidateSourceControlledFilePath( return normalizedPath; } + +/** + * Checks if a workflow has been modified by comparing version IDs and parent folder IDs + * between local and remote versions + */ +export function isWorkflowModified( + local: SourceControlWorkflowVersionId, + remote: SourceControlWorkflowVersionId, +): boolean { + return ( + remote.versionId !== local.versionId || + (remote.parentFolderId !== undefined && remote.parentFolderId !== local.parentFolderId) + ); +} diff --git a/packages/cli/src/environments.ee/source-control/source-control.service.ee.ts b/packages/cli/src/environments.ee/source-control/source-control.service.ee.ts index 51d7e587f2..0e9fe5b2ba 100644 --- a/packages/cli/src/environments.ee/source-control/source-control.service.ee.ts +++ b/packages/cli/src/environments.ee/source-control/source-control.service.ee.ts @@ -32,6 +32,7 @@ import { getTrackingInformationFromPrePushResult, getTrackingInformationFromPullResult, getVariablesPath, + isWorkflowModified, normalizeAndValidateSourceControlledFilePath, sourceControlFoldersExistCheck, } from './source-control-helper.ee'; @@ -571,25 +572,37 @@ export class SourceControlService { ); const wfModifiedInEither: SourceControlWorkflowVersionId[] = []; - wfLocalVersionIds.forEach((local) => { - const mismatchingIds = wfRemoteVersionIds.find( - (remote) => - remote.id === local.id && - (remote.versionId !== local.versionId || remote.parentFolderId !== local.parentFolderId), + + wfLocalVersionIds.forEach((localWorkflow) => { + const remoteWorkflowWithSameId = wfRemoteVersionIds.find( + (removeWorkflow) => removeWorkflow.id === localWorkflow.id, ); - let name = (options?.preferLocalVersion ? local?.name : mismatchingIds?.name) ?? 'Workflow'; - if (local.name && mismatchingIds?.name && local.name !== mismatchingIds.name) { - name = options?.preferLocalVersion - ? `${local.name} (Remote: ${mismatchingIds.name})` - : (name = `${mismatchingIds.name} (Local: ${local.name})`); + + if (!remoteWorkflowWithSameId) { + return; } - if (mismatchingIds) { + + if (isWorkflowModified(localWorkflow, remoteWorkflowWithSameId)) { + let name = + (options?.preferLocalVersion ? localWorkflow?.name : remoteWorkflowWithSameId?.name) ?? + 'Workflow'; + if ( + localWorkflow.name && + remoteWorkflowWithSameId?.name && + localWorkflow.name !== remoteWorkflowWithSameId.name + ) { + name = options?.preferLocalVersion + ? `${localWorkflow.name} (Remote: ${remoteWorkflowWithSameId.name})` + : (name = `${remoteWorkflowWithSameId.name} (Local: ${localWorkflow.name})`); + } wfModifiedInEither.push({ - ...local, + ...localWorkflow, name, - versionId: options.preferLocalVersion ? local.versionId : mismatchingIds.versionId, - localId: local.versionId, - remoteId: mismatchingIds.versionId, + versionId: options.preferLocalVersion + ? localWorkflow.versionId + : remoteWorkflowWithSameId.versionId, + localId: localWorkflow.versionId, + remoteId: remoteWorkflowWithSameId.versionId, }); } });