Skip to content

Commit c31abdc

Browse files
authored
TfsWorkItemTypeValidatorTool – use field mapping and field value mapping in validation (#3010)
This PR solves the last two items in [improve work item type validation list](#2951). Validation now respects field mapings (`FieldToFieldMultiMap` and `FieldToFieldMap`) and field value mappings (`FieldValueMap`) of `FieldMappingTool`. For `FieldToFieldMap` mappings only the ones with `SourceToTarget` mapping mode are used. Configuration for validator `TfsWorkItemTypeValidatorTool` has changed a bit: - `SourceFieldMappings` is removed, This existed only to define field mappings between source and target. Now real mappings from `FieldMappingTool` are respected. - `FixedTargetFields` was removed. It is not needed and it was not really good because it worked with target fields and basically we validate source fields in target work item type. - `ExcludeSourceFields` was added. Basically it replaces previous two properties and it is a list of source fields which will be excluded from validation. Fields excluded from validation `ExcludeSourceFields` are not really excluded. They are still validated so user knows if there are some issues, but even when the issues are found, they are reported only as information instead of warning and the field itself is considered valid. This is especially useful, if the user still wants to migrate such a field, but it is not possible to define simple mapping for it. For example user will be notified, that the field `X` do not exist in target, but will configure it as excluded and define `FieldMergeMap` for this field. There was a tip, that `FieldSkipMap` can also be used, but it is not possible. This mapping type is for target fields and we need to skip fields in source work item types. ## Example log outputs I tried to log as much thing as possible, so the user will know what to do. ### Field exists and is valid ``` [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Validating source field 'System.Description' (Description). [16:09:37 DBG] [16.3.2-Local.4-5-gb4960cc1] Target field 'System.Description' (Description) exists in 'Bug' and is valid. ``` ### Field is mapped and is valid ``` [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Validating source field 'Kros.VersionNumber' (Kros Version Number). [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Source field 'Kros.VersionNumber' is mapped to 'Custom.KrosVersionNumber'. [16:09:37 DBG] [16.3.2-Local.4-5-gb4960cc1] Target field 'Custom.KrosVersionNumber' (KrosVersionNumber) exists in 'Bug' and is valid. ``` ### Field is missing in target ``` [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Validating source field 'Microsoft.VSTS.Scheduling.Effort' (Effort). [16:09:37 WRN] [16.3.2-Local.4-5-gb4960cc1] Missing field 'Microsoft.VSTS.Scheduling.Effort' in 'Bug'. [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Source field reference name: Microsoft.VSTS.Scheduling.Effort [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Source field name: Effort [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Field type: Double [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Allowed values: [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Allowed values type: Double ``` ### Allowed values for field are missing in target ``` [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Validating source field 'System.State' (State). [16:09:37 DBG] [16.3.2-Local.4-5-gb4960cc1] Allowed values in target field do not match allowed values in source. Checking field value maps. [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Missing values are: 'Approved', 'Committed', 'Done', 'Removed' [16:09:37 DBG] [16.3.2-Local.4-5-gb4960cc1] Value 'Approved' is mapped to 'New', which exists in target. [16:09:37 WRN] [16.3.2-Local.4-5-gb4960cc1] Value 'Done' is mapped to 'Closd', which does not exists in target. This is probably invalid 'FieldValueMap' configuration. [16:09:37 DBG] [16.3.2-Local.4-5-gb4960cc1] Value 'Removed' is mapped to 'Closed', which exists in target. [16:09:37 WRN] [16.3.2-Local.4-5-gb4960cc1] Source field 'System.State' and target field 'System.State' have different allowed values. [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Source allowed values: 'Approved', 'Committed', 'Done', 'New', 'Removed' [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Target allowed values: 'Active', 'Closed', 'New', 'Resolved' [16:09:37 INF] [16.3.2-Local.4-5-gb4960cc1] Missing values in target are: 'Committed', 'Done' ``` ### Field is excluded from validation ``` [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Validating source field 'Microsoft.VSTS.Scheduling.Effort' (Effort). [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Missing field 'Microsoft.VSTS.Scheduling.Effort' in 'Bug'. [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Source field reference name: Microsoft.VSTS.Scheduling.Effort [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Source field name: Effort [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Field type: Double [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Allowed values: [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Allowed values type: Double [08:04:27 INF] [16.3.2-Local.4-7-g1ca7b77d] Field 'Microsoft.VSTS.Scheduling.Effort' is excluded from validation, so it is considered valid. ``` ### Final log if there are any issues ``` [08:21:14 ERR] [16.3.2-Local.4-7-g1ca7b77d] Some work item types or their fields are not valid in the target system (see previous logs). [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] If the work item type does not exist in target system, you can: [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Create it there. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Configure mapping to another work item type which exists in target using 'WorkItemTypeMappingTool' configuration. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Exclude it from validation. To configure which work item types are validated, use either 'IncludeWorkItemTypes' or 'ExcludeWorkItemTypes' of 'TfsWorkItemTypeValidatorTool' configuration (but not both at the same time). [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] If field is missing in target, you can: [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Add missing field to the target work item type. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Configure field mapping using 'FieldToFieldMultiMap' in 'FieldMappingTool' configuration. This is simpler method for source to target field mapping, which allows to map multiple fields at once. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Configure field mapping using 'FieldToFieldMap' in 'FieldMappingTool' configuration. Mapping mode must be of type 'SourceToTarget'. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] If allowed values of the source and target fields do not match, you can: [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Add missing allowed values to the target field. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] - Configure value mapping. Add field maps of type 'FieldValueMap' to 'FieldMappingTool' configuration. [08:21:14 INF] [16.3.2-Local.4-7-g1ca7b77d] To exclude field from validation, just configure it in 'ExcludeSourceFields' of 'TfsWorkItemTypeValidatorTool' configuration. If field is excluded from validation, all the issues are still logged, just the result of validation is 'valid'. ```
2 parents ffa829e + 62ae992 commit c31abdc

17 files changed

+534
-489
lines changed

docs/data/classes/reference.tools.tfsworkitemtypevalidatortool.yaml

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,10 @@ configurationSamples:
5353
{
5454
"$type": "TfsWorkItemTypeValidatorToolOptions",
5555
"Enabled": true,
56-
"IncludeWorkItemtypes": [],
57-
"ExcludeWorkItemtypes": [],
56+
"IncludeWorkItemTypes": [],
57+
"ExcludeWorkItemTypes": [],
5858
"ExcludeDefaultWorkItemTypes": true,
59-
"SourceFieldMappings": {
60-
"User Story": {
61-
"Microsoft.VSTS.Common.Prirucka": "Custom.Prirucka"
62-
}
63-
},
64-
"FixedTargetFields": {
65-
"User Story": [
66-
"Custom.Prirucka"
67-
]
68-
}
59+
"ExcludeSourceFields": {}
6960
}
7061
sampleFor: MigrationTools.Tools.TfsWorkItemTypeValidatorToolOptions
7162
description: >-
@@ -83,48 +74,36 @@ options:
8374
- parameterName: ExcludeDefaultWorkItemTypes
8475
type: Boolean
8576
description: >-
86-
If `true`, some work item types will be automatically added to `ExcludeWorkItemtypes` list.
77+
If `true`, some work item types will be automatically added to `ExcludeWorkItemTypes` list.
8778
Work item types excluded by default are: Code Review Request, Code Review Response, Feedback Request,
8879
Feedback Response, Shared Parameter, Shared Steps.
8980
defaultValue: missing XML code comments
9081
isRequired: false
9182
dotNetType: System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
92-
- parameterName: ExcludeWorkItemtypes
93-
type: List
94-
description: List of work item types which will be excluded from validation.
95-
defaultValue: missing XML code comments
96-
isRequired: false
97-
dotNetType: System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
98-
- parameterName: FixedTargetFields
83+
- parameterName: ExcludeSourceFields
9984
type: Dictionary
10085
description: >-
101-
List of target fields that are considered as `fixed`.
102-
A field marked as fixed will not stop the migration if differences are found.
103-
Instead of a warning, only an informational message will be logged.
86+
List of fields in source work itemt types, that are excluded from validation.
87+
Fields excluded from validation are still validated and all found issues are logged.
88+
But the result of the validation is 'valid' and the issues are logged as information instead of warning.
10489
105-
Use this list when you already know about the differences and have resolved them,
106-
for example by using `FieldMappingTool`.
107-
108-
The key is the target work item type name.
109-
You can also use `*` to define fixed fields that apply to all work item types.
90+
The key is the source work item type name.
91+
You can also use `*` to exclude fields from all source work item types.
11092
defaultValue: null
11193
isRequired: false
11294
dotNetType: System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
113-
- parameterName: IncludeWorkItemtypes
95+
- parameterName: ExcludeWorkItemTypes
11496
type: List
115-
description: List of work item types which will be validated. If this list is empty, all work item types will be validated.
116-
defaultValue: null
97+
description: List of work item types which will be excluded from validation.
98+
defaultValue: missing XML code comments
11799
isRequired: false
118100
dotNetType: System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
119-
- parameterName: SourceFieldMappings
120-
type: Dictionary
121-
description: >-
122-
Field reference name mappings. Key is work item type name, value is dictionary of mapping source filed name to
123-
target field name. Target field name can be empty string to indicate that this field will not be validated in target.
124-
As work item type name, you can use `*` to define mappings which will be applied to all work item types.
101+
- parameterName: IncludeWorkItemTypes
102+
type: List
103+
description: List of work item types which will be validated. If this list is empty, all work item types will be validated.
125104
defaultValue: null
126105
isRequired: false
127-
dotNetType: System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
106+
dotNetType: System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
128107
status: missing XML code comments
129108
processingTarget: missing XML code comments
130109
classFile: src/MigrationTools.Clients.TfsObjectModel/Tools/TfsWorkItemTypeValidatorTool.cs

docs/static/schema/configuration.schema.json

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,22 +2182,6 @@
21822182
}
21832183
}
21842184
},
2185-
"TfsChangeSetMappingTool": {
2186-
"title": "TfsChangeSetMappingTool",
2187-
"description": "missing XML code comments",
2188-
"type": "object",
2189-
"properties": {
2190-
"ChangeSetMappingFile": {
2191-
"description": "missing XML code comments",
2192-
"type": "string"
2193-
},
2194-
"Enabled": {
2195-
"description": "If set to `true` then the tool will run. Set to `false` and the processor will not run.",
2196-
"type": "boolean",
2197-
"default": "true"
2198-
}
2199-
}
2200-
},
22012185
"TfsEmbededImagesTool": {
22022186
"title": "TfsEmbededImagesTool",
22032187
"description": "missing XML code comments",
@@ -2234,6 +2218,22 @@
22342218
}
22352219
}
22362220
},
2221+
"TfsChangeSetMappingTool": {
2222+
"title": "TfsChangeSetMappingTool",
2223+
"description": "missing XML code comments",
2224+
"type": "object",
2225+
"properties": {
2226+
"Enabled": {
2227+
"description": "If set to `true` then the tool will run. Set to `false` and the processor will not run.",
2228+
"type": "boolean",
2229+
"default": "true"
2230+
},
2231+
"ChangeSetMappingFile": {
2232+
"description": "missing XML code comments",
2233+
"type": "string"
2234+
}
2235+
}
2236+
},
22372237
"TfsNodeStructureTool": {
22382238
"title": "TfsNodeStructureTool",
22392239
"description": "Tool for creating missing area and iteration path nodes in the target project during migration. Configurable through TfsNodeStructureToolOptions to specify which node types to create.",
@@ -2469,20 +2469,11 @@
24692469
"default": "true"
24702470
},
24712471
"ExcludeDefaultWorkItemTypes": {
2472-
"description": "If `true`, some work item types will be automatically added to `ExcludeWorkItemtypes` list.\r\n Work item types excluded by default are: Code Review Request, Code Review Response, Feedback Request,\r\n Feedback Response, Shared Parameter, Shared Steps.",
2472+
"description": "If `true`, some work item types will be automatically added to `ExcludeWorkItemTypes` list.\r\n Work item types excluded by default are: Code Review Request, Code Review Response, Feedback Request,\r\n Feedback Response, Shared Parameter, Shared Steps.",
24732473
"type": "boolean"
24742474
},
2475-
"ExcludeWorkItemtypes": {
2476-
"description": "List of work item types which will be excluded from validation.",
2477-
"type": "array",
2478-
"prefixItems": [
2479-
{
2480-
"type": "string"
2481-
}
2482-
]
2483-
},
2484-
"FixedTargetFields": {
2485-
"description": "List of target fields that are considered as `fixed`.\r\n A field marked as fixed will not stop the migration if differences are found.\r\n Instead of a warning, only an informational message will be logged.\r\n\n Use this list when you already know about the differences and have resolved them,\r\n for example by using `FieldMappingTool`.\r\n\n The key is the target work item type name.\r\n You can also use `*` to define fixed fields that apply to all work item types.",
2475+
"ExcludeSourceFields": {
2476+
"description": "List of fields in source work itemt types, that are excluded from validation.\r\n Fields excluded from validation are still validated and all found issues are logged.\r\n But the result of the validation is 'valid' and the issues are logged as information instead of warning.\r\n\n The key is the source work item type name.\r\n You can also use `*` to exclude fields from all source work item types.",
24862477
"type": "object",
24872478
"default": "null",
24882479
"additionalProperties": {
@@ -2494,26 +2485,24 @@
24942485
]
24952486
}
24962487
},
2497-
"IncludeWorkItemtypes": {
2498-
"description": "List of work item types which will be validated. If this list is empty, all work item types will be validated.",
2488+
"ExcludeWorkItemTypes": {
2489+
"description": "List of work item types which will be excluded from validation.",
24992490
"type": "array",
2500-
"default": "null",
25012491
"prefixItems": [
25022492
{
25032493
"type": "string"
25042494
}
25052495
]
25062496
},
2507-
"SourceFieldMappings": {
2508-
"description": "Field reference name mappings. Key is work item type name, value is dictionary of mapping source filed name to\r\n target field name. Target field name can be empty string to indicate that this field will not be validated in target.\r\n As work item type name, you can use `*` to define mappings which will be applied to all work item types.",
2509-
"type": "object",
2497+
"IncludeWorkItemTypes": {
2498+
"description": "List of work item types which will be validated. If this list is empty, all work item types will be validated.",
2499+
"type": "array",
25102500
"default": "null",
2511-
"additionalProperties": {
2512-
"type": "object",
2513-
"additionalProperties": {
2501+
"prefixItems": [
2502+
{
25142503
"type": "string"
25152504
}
2516-
}
2505+
]
25172506
}
25182507
}
25192508
},

docs/static/schema/schema.tools.tfsworkitemtypevalidatortool.json

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,22 @@
1111
"default": "true"
1212
},
1313
"ExcludeDefaultWorkItemTypes": {
14-
"description": "If `true`, some work item types will be automatically added to `ExcludeWorkItemtypes` list.\r\n Work item types excluded by default are: Code Review Request, Code Review Response, Feedback Request,\r\n Feedback Response, Shared Parameter, Shared Steps.",
14+
"description": "If `true`, some work item types will be automatically added to `ExcludeWorkItemTypes` list.\r\n Work item types excluded by default are: Code Review Request, Code Review Response, Feedback Request,\r\n Feedback Response, Shared Parameter, Shared Steps.",
1515
"type": "boolean"
1616
},
17-
"ExcludeWorkItemtypes": {
18-
"description": "List of work item types which will be excluded from validation.",
19-
"type": "array"
20-
},
21-
"FixedTargetFields": {
22-
"description": "List of target fields that are considered as `fixed`.\r\n A field marked as fixed will not stop the migration if differences are found.\r\n Instead of a warning, only an informational message will be logged.\r\n\n Use this list when you already know about the differences and have resolved them,\r\n for example by using `FieldMappingTool`.\r\n\n The key is the target work item type name.\r\n You can also use `*` to define fixed fields that apply to all work item types.",
17+
"ExcludeSourceFields": {
18+
"description": "List of fields in source work itemt types, that are excluded from validation.\r\n Fields excluded from validation are still validated and all found issues are logged.\r\n But the result of the validation is 'valid' and the issues are logged as information instead of warning.\r\n\n The key is the source work item type name.\r\n You can also use `*` to exclude fields from all source work item types.",
2319
"type": "object",
2420
"default": "null"
2521
},
26-
"IncludeWorkItemtypes": {
22+
"ExcludeWorkItemTypes": {
23+
"description": "List of work item types which will be excluded from validation.",
24+
"type": "array"
25+
},
26+
"IncludeWorkItemTypes": {
2727
"description": "List of work item types which will be validated. If this list is empty, all work item types will be validated.",
2828
"type": "array",
2929
"default": "null"
30-
},
31-
"SourceFieldMappings": {
32-
"description": "Field reference name mappings. Key is work item type name, value is dictionary of mapping source filed name to\r\n target field name. Target field name can be empty string to indicate that this field will not be validated in target.\r\n As work item type name, you can use `*` to define mappings which will be applied to all work item types.",
33-
"type": "object",
34-
"default": "null"
3530
}
3631
}
3732
}

src/MigrationTools.Clients.TfsObjectModel.Tests/Tools/FieldReferenceNameMappingToolOptionsTests.cs

Lines changed: 0 additions & 112 deletions
This file was deleted.

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsWorkItemMigrationProcessor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,13 @@ private void ValidateWorkItemTypes()
259259
.ToProject()
260260
.WorkItemTypes
261261
.Cast<WorkItemType>()
262+
.OrderBy(wit => wit.Name)
262263
.ToList();
263264
var targetWits = Target.WorkItems.Project
264265
.ToProject()
265266
.WorkItemTypes
266267
.Cast<WorkItemType>()
268+
.OrderBy(wit => wit.Name)
267269
.ToList();
268270

269271
// Reflected work item ID field is mandatory for migration, so it is validated even if the validator tool is disabled.

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsWorkItemTypeValidatorProcessor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ protected override void InternalExecute()
4141
.ToProject()
4242
.WorkItemTypes
4343
.Cast<WorkItemType>()
44+
.OrderBy(wit => wit.Name)
4445
.ToList();
4546
List<WorkItemType> targetWits = Target.WorkItems.Project
4647
.ToProject()
4748
.WorkItemTypes
4849
.Cast<WorkItemType>()
50+
.OrderBy(wit => wit.Name)
4951
.ToList();
5052
bool containsReflectedWorkItemId = CommonTools.WorkItemTypeValidatorTool
5153
.ValidateReflectedWorkItemIdField(sourceWits, targetWits, Target.Options.ReflectedWorkItemIdField);

0 commit comments

Comments
 (0)