Closed david5MX53G closed 3 years ago
I got it working. I think the problem had something to do with the order in which I entered my maps, so I'm posting my entire config here for the reference of anyone coming in my humble footsteps.
{
"ChangeSetMappingFile": null,
"Source": {
"$type": "TfsTeamProjectConfig",
"Collection": "https://dev.azure.com/AcmeCoinc/",
"Project": "AcmeCo",
"ReflectedWorkItemIDFieldName": "Custom.ReflectedWorkItemId",
"AllowCrossProjectLinking": false,
"AuthenticationMode": "Prompt",
"PersonalAccessToken": "",
"LanguageMaps": {
"AreaPath": "Area",
"IterationPath": "Iteration"
}
},
"Target": {
"$type": "TfsTeamProjectConfig",
"Collection": "https://dev.azure.com/AcmeCo/",
"Project": "Global Operations",
"ReflectedWorkItemIDFieldName": "Custom.ReflectedWorkItemId",
"AllowCrossProjectLinking": false,
"AuthenticationMode": "Prompt",
"PersonalAccessToken": "",
"LanguageMaps": {
"AreaPath": "Area",
"IterationPath": "Iteration"
}
},
"FieldMaps": [
{
"$type": "FieldValueMapConfig",
"WorkItemTypeName": "*",
"sourceField": "System.AreaPath",
"targetField": "System.AreaPath",
"defaultValue": "Global Operations",
"valueMapping": {
"AcmeCo\\BusinessApps": "Global Operations\\Enterprise Applications\\CRM"
}
},
{
"$type": "FieldValueMapConfig",
"WorkItemTypeName": "*",
"sourceField": "System.IterationPath",
"targetField": "System.IterationPath",
"defaultValue": "Global Operations",
"valueMapping": {
"AcmeCo\\2020-01": "Global Operations\\2020\\01",
"AcmeCo\\2020-02": "Global Operations\\2020\\02",
"AcmeCo\\2020-03": "Global Operations\\2020\\03",
"AcmeCo\\2020-04": "Global Operations\\2020\\04",
"AcmeCo\\2020-05": "Global Operations\\2020\\05",
"AcmeCo\\2020-06": "Global Operations\\2020\\06",
"AcmeCo\\2020-07": "Global Operations\\2020\\07",
"AcmeCo\\2020-08": "Global Operations\\2020\\08",
"AcmeCo\\2020-09": "Global Operations\\2020\\09",
"AcmeCo\\2020-10": "Global Operations\\2020\\10",
"AcmeCo\\2020-11": "Global Operations\\2020\\11",
"AcmeCo\\2020-12": "Global Operations\\2020\\12",
"AcmeCo\\2021-01": "Global Operations\\2021\\01"
}
},
{
"$type": "FieldValueMapConfig",
"WorkItemTypeName": "*",
"sourceField": "WEF_0EB2D7D633B04DFAA8BB93EC6CC32B8D_Kanban.Column",
"targetField": "WEF_11706B94CD66464AA34EBEEB073F6D47_Kanban.Column",
"defaultValue": "New",
"valueMapping": {
"New": "New",
"Waiting for Approval": "Active",
"Approved for Development": "Active",
"Analysis": "Active",
"Development": "Active",
"User Acceptance": "Active",
"Ready for Deployment": "Resolved",
"Closed": "Closed"
}
},
{
"$type": "FieldBlankMapConfig",
"WorkItemTypeName": "*",
"targetField": "TfsMigrationTool.ReflectedWorkItemId"
},
{
"$type": "FieldtoTagMapConfig",
"WorkItemTypeName": "*",
"sourceField": "System.BoardColumn",
"formatExpression": "BoardColumn:{0}"
},
{
"$type": "FieldtoFieldMapConfig",
"WorkItemTypeName": "*",
"sourceField": "Microsoft.VSTS.Common.BacklogPriority",
"targetField": "Microsoft.VSTS.Common.StackRank",
"defaultValue": null
},
{
"$type": "FieldtoTagMapConfig",
"WorkItemTypeName": "*",
"sourceField": "System.State",
"formatExpression": "ScrumState:{0}"
},
{
"$type": "FieldtoTagMapConfig",
"WorkItemTypeName": "*",
"sourceField": "System.BoardLane",
"formatExpression": "ScrumLane:{0}"
},
{
"$type": "RegexFieldMapConfig",
"WorkItemTypeName": "*",
"sourceField": "COMPANY.PRODUCT.Release",
"targetField": "COMPANY.DEVISION.MinorReleaseVersion",
"pattern": "PRODUCT \\d{4}.(\\d{1})",
"replacement": "$1"
},
{
"$type": "FieldValuetoTagMapConfig",
"WorkItemTypeName": "*",
"sourceField": "Microsoft.VSTS.CMMI.Blocked",
"pattern": "Yes",
"formatExpression": "Blocked"
},
{
"$type": "TreeToTagMapConfig",
"WorkItemTypeName": "*",
"toSkip": 3,
"timeTravel": 1
}
],
"GitRepoMapping": null,
"LogLevel": "Information",
"Processors": [
{
"$type": "WorkItemMigrationConfig",
"Enabled": true,
"ReplayRevisions": true,
"PrefixProjectToNodes": false,
"UpdateCreatedDate": true,
"UpdateCreatedBy": true,
"BuildFieldTable": false,
"AppendMigrationToolSignatureFooter": false,
"WIQLQueryBit": "AND [System.Id]=6100 AND [Custom.ReflectedWorkItemId] = '' AND [System.WorkItemType] IN ('Epic', 'Feature', 'Task', 'User Story', 'Bug')",
"WIQLOrderBit": "[System.ChangedDate] desc",
"LinkMigration": true,
"AttachmentMigration": true,
"AttachmentWorkingPath": "c:\\temp\\WorkItemAttachmentWorkingFolder\\",
"FixHtmlAttachmentLinks": false,
"SkipToFinalRevisedWorkItemType": true,
"WorkItemCreateRetryLimit": 5,
"FilterWorkItemsThatAlreadyExistInTarget": true,
"PauseAfterEachWorkItem": false,
"AttachmentMaxSize": 480000000,
"CollapseRevisions": false,
"LinkMigrationSaveEachAsAdded": false,
"GenerateMigrationComment": true,
"NodeBasePaths": ["DUMMY VALUE"],
"WorkItemIDs": null
}
],
"Version": "11.9",
"workaroundForQuerySOAPBugEnabled": false,
"WorkItemTypeDefinition": {
"sourceWorkItemTypeName": "targetWorkItemTypeName"
}
}
Note: the values "WEF_0EB2D7D633B04DFAA8BB93EC6CC32B8D_Kanban" and "WEF_11706B94CD66464AA34EBEEB073F6D47_Kanban" are unique to every board, so I had to use the "Get work item" GET request to find them. That GET request is described in the Azure DevOps API docs.
It turns out the Tool was ignoring my FieldValueMapConfig for Kanban Columns after all; instead, the tool uses the "State mapping" settings of the target board to assign columns for the incoming work items. Thus, I was able to adjust which columns my work items arrived in by changing the state mapping of the source board.
I have entered the following item in my JSON config:
Nevertheless, every item I migrate ends up in the "New" column of the target instance. I expected the Tool to use the mappings I entered above. Am I missing something?