Field Mapping Tool
The Field Mapping Tool applies field transformation strategies during work item migration, enabling sophisticated field mappings, value transformations, and data manipulations between source and target systems.
Overview
The Field Mapping Tool is a core component of the Azure DevOps Migration Tools that enables sophisticated field transformations during work item migration. It applies configured field mappings to work items as they are processed, allowing you to transform data, map fields between different schemas, and manipulate values to match your target system requirements.
The tool supports a wide variety of field mapping strategies through its extensible field map system, from simple field-to-field mappings to complex calculations and regex transformations.
topHow It Works
The Field Mapping Tool operates during work item processing in migration processors. When a work item is being migrated:
Initialization: The tool loads all configured field maps during startup, organizing them by work item type
Application: During migration, the tool applies field maps in two phases:
- Universal mappings: Maps configured with
ApplyTo: ["*"]
are applied to all work items - Type-specific mappings: Maps configured for the specific work item type are applied
- Universal mappings: Maps configured with
Processing: Each field map executes its transformation logic on the source and target work item data
The tool is automatically invoked by migration processors including:
- TfsWorkItemMigrationProcessor: Applies field mappings during standard work item migration
- TfsWorkItemOverwriteProcessor: Applies field mappings when overwriting existing work items
Field Map Types
The Field Mapping Tool supports numerous field map types, each designed for specific transformation scenarios. All available field maps are documented in the Field Maps section .
Key categories include:
- Direct Mapping: Simple field-to-field copying and transformations
- Value Mapping: Converting values using lookup tables and conditional logic
- Calculations: Mathematical operations and computed field values
- Text Processing: Regex transformations, merging, and text manipulations
- Metadata Handling: Working with tags, areas, iterations, and other metadata
- Conditional Logic: Applying mappings based on specific conditions
Configuration Structure
Field mappings are configured in the FieldMaps
array within the FieldMappingTool
section. Each field map includes:
- FieldMapType: Specifies which field map implementation to use
- ApplyTo: Array of work item types the mapping applies to (use
["*"]
for all types) - Additional Properties: Configuration specific to each field map type
Common Configuration Pattern
{
"FieldMappingTool": {
"Enabled": true,
"FieldMaps": [
{
"FieldMapType": "FieldToFieldMap",
"ApplyTo": ["Bug", "Task"],
"sourceField": "Source.Field",
"targetField": "Target.Field"
}
]
}
}
Field Map Defaults
The FieldMapDefaults
section allows you to set default ApplyTo
values that will be inherited by field maps that don’t specify their own ApplyTo
configuration:
{
"FieldMappingTool": {
"Enabled": true,
"FieldMapDefaults": {
"ApplyTo": ["Bug", "Task", "User Story"]
},
"FieldMaps": [
// Field maps without ApplyTo will inherit the defaults above
]
}
}
Best Practices
topOrder Matters
Field maps are processed in the order they appear in the configuration. Consider dependencies between mappings when ordering them.
topWork Item Type Targeting
Use specific work item types in ApplyTo
rather than ["*"]
when possible to avoid unintended side effects.
Testing Field Maps
Test field mappings with a small subset of work items before running full migrations to ensure they produce expected results.
topPerformance Considerations
- Complex regex patterns and calculations can impact migration performance
- Consider the frequency of execution when designing field mappings
- Use specific work item type targeting to reduce unnecessary processing
Tool for applying field mapping transformations to work items during migration, supporting various field mapping strategies like direct mapping, regex transformations, and value lookups.
Options
topSamples
topSample
{
"MigrationTools": {
"Version": "16.0",
"CommonTools": {
"FieldMappingTool": {
"Enabled": "True",
"FieldMaps": [
{
"ApplyTo": [
"Bug",
"Task"
],
"expression": "[effort] * [rate]",
"FieldMapType": "FieldCalculationMap",
"parameters": {
"effort": "Custom.EstimatedHours",
"rate": "Custom.HourlyRate"
},
"targetField": "Custom.EstimatedCost"
},
{
"ApplyTo": [
"SomeWorkItemType"
],
"FieldMapType": "FieldMergeMap",
"formatExpression": "{0} \n {1}",
"sourceFields": [
"Custom.FieldA",
"Custom.FieldB"
],
"targetField": "Custom.FieldC"
},
{
"ApplyTo": [
"SomeWorkItemType"
],
"defaultValue": "New",
"FieldMapType": "FieldValueMap",
"sourceField": "System.State",
"targetField": "System.State",
"valueMapping": {
"Active": "InProgress",
"Closed": "Done",
"Resolved": "InProgress"
}
},
{
"ApplyTo": [
"SomeWorkItemType"
],
"defaultValue": "42",
"FieldMapType": "FieldToFieldMap",
"sourceField": "Microsoft.VSTS.Common.BacklogPriority",
"targetField": "Microsoft.VSTS.Common.StackRank"
}
],
"FieldMapSamples": {
"FieldCalculationMap": {
"ApplyTo": [
"Bug",
"Task"
],
"expression": "[effort] * [rate]",
"FieldMapType": "FieldCalculationMap",
"parameters": {
"effort": "Custom.EstimatedHours",
"rate": "Custom.HourlyRate"
},
"targetField": "Custom.EstimatedCost"
},
"FieldClearMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"targetField": "Custom.FieldC"
},
"FieldLiteralMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"targetField": "Custom.SomeField",
"value": "New field value"
},
"FieldMergeMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"formatExpression": "{0} \n {1}",
"sourceFields": [
"Custom.FieldA",
"Custom.FieldB"
],
"targetField": "Custom.FieldC"
},
"FieldToFieldMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"defaultValue": "42",
"sourceField": "Microsoft.VSTS.Common.BacklogPriority",
"targetField": "Microsoft.VSTS.Common.StackRank"
},
"FieldToFieldMultiMap": {
"ApplyTo": [
"SomeWorkItemType",
"SomeOtherWorkItemType"
],
"SourceToTargetMappings": {
"SourceField1": "TargetField1",
"SourceField2": "TargetField2"
}
},
"FieldToTagFieldMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"formatExpression": "{0} <br/><br/><h3>Acceptance Criteria</h3>{1}",
"sourceFields": [
"System.Description",
"Microsoft.VSTS.Common.AcceptanceCriteria"
],
"targetField": "System.Description"
},
"FieldToTagMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"formatExpression": "ScrumState:{0}",
"sourceField": "System.State"
},
"FieldValueMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"defaultValue": "StateB",
"sourceField": "System.State",
"targetField": "System.State",
"valueMapping": {
"StateA": "StateB"
}
},
"FieldValueToTagMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"formatExpression": "{0}",
"pattern": "Yes",
"sourceField": "Microsoft.VSTS.CMMI.Blocked"
},
"MultiValueConditionalMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"sourceFieldsAndValues": {
"Field1": "Value1",
"Field2": "Value2"
},
"targetFieldsAndValues": {
"Field1": "Value1",
"Field2": "Value2"
}
},
"RegexFieldMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"pattern": "PRODUCT \\d{4}.(\\d{1})",
"replacement": "$1",
"sourceField": "COMPANY.PRODUCT.Release",
"targetField": "COMPANY.DEVISION.MinorReleaseVersion"
},
"targetFieldsAndValues": {
"ApplyTo": [
"SomeWorkItemType"
],
"targetField": "Custom.ReflectedWorkItemId"
},
"TreeToTagMap": {
"ApplyTo": [
"SomeWorkItemType"
],
"timeTravel": "1",
"toSkip": "3"
}
}
}
}
}
}
Defaults
{
"MigrationTools": {
"Version": "16.0",
"CommonTools": {
"FieldMappingTool": {
"Enabled": "False",
"FieldMapDefaults": {
"ApplyTo": [
"*"
]
},
"FieldMaps": null
}
}
}
}
Classic
{
"$type": "FieldMappingToolOptions",
"Enabled": true,
"FieldMaps": []
}
Metadata
topSchema
This is the JSON schema that defines the structure and validation rules for this configuration.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://devopsmigration.io/schema/schema.tools.fieldmappingtool.json",
"title": "FieldMappingTool",
"description": "Tool for applying field mapping transformations to work items during migration, supporting various field mapping strategies like direct mapping, regex transformations, and value lookups.",
"type": "object",
"properties": {
"Enabled": {
"description": "If set to `true` then the tool will run. Set to `false` and the processor will not run.",
"type": "boolean",
"default": "true"
},
"FieldMaps": {
"description": "Gets or sets the list of field mapping configurations to apply.",
"type": "array",
"prefixItems": [
{
"anyOf": [
{
"title": "FieldCalculationMap",
"description": "Performs mathematical calculations on numeric fields using NCalc expressions during migration.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"expression": {
"description": "Gets or sets the NCalc expression to evaluate. Variables in the expression should be enclosed in square brackets (e.g., \"[x]*2\").",
"type": "string",
"default": "null"
},
"parameters": {
"description": "Gets or sets a dictionary mapping variable names used in the expression to source field reference names.",
"type": "object",
"default": "{}",
"additionalProperties": {
"type": "string"
}
},
"targetField": {
"description": "Gets or sets the target field reference name where the calculated result will be stored.",
"type": "string",
"default": "null"
}
}
},
{
"title": "FieldClearMap",
"description": "Clears a target field by setting its value to null, useful for removing data from specific fields during migration.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"targetField": {
"description": "Gets or sets the name of the target field to be cleared/set to null during work item migration.",
"type": "string"
}
}
},
{
"title": "FieldLiteralMap",
"description": "Maps a literal (static) value to a target field, useful for setting constant values across all migrated work items.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"targetField": {
"description": "Gets or sets the name of the target field that will be set to the specified literal value.",
"type": "string"
},
"value": {
"description": "Gets or sets the literal value that will be assigned to the target field during migration.",
"type": "string"
}
}
},
{
"title": "FieldMergeMap",
"description": "Merges values from multiple source fields into a single target field using a specified format template.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"formatExpression": {
"description": "missing XML code comments",
"type": "string"
},
"sourceFields": {
"description": "missing XML code comments",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"targetField": {
"description": "missing XML code comments",
"type": "string"
}
}
},
{
"title": "FieldSkipMap",
"description": "Skips field mapping for a specific target field, effectively leaving the field unchanged during migration.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"targetField": {
"description": "Gets or sets the name of the target field that should be skipped during migration, resetting it to its original value.",
"type": "string"
}
}
},
{
"title": "FieldToFieldMap",
"description": "Maps the value from a source field to a target field directly, with optional default value substitution for empty or null values.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"defaultValue": {
"description": "Gets or sets the default value to use when the source field is empty or null.",
"type": "string"
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"fieldMapMode": {
"description": "Gets or sets the mode of field mapping to be applied during migration. SourceToTarget will get data from the source system and apply it to the target. TargetToTarget will move data between the target fields.",
"type": "string",
"default": "SourceToTarget"
},
"sourceField": {
"description": "Gets or sets the name of the source field to copy data from during migration.",
"type": "string"
},
"targetField": {
"description": "Gets or sets the name of the target field to copy data to during migration.",
"type": "string"
}
}
},
{
"title": "FieldToFieldMultiMap",
"description": "missing XML code comments",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"SourceToTargetMappings": {
"description": "missing XML code comments",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
{
"title": "FieldToTagFieldMap",
"description": "missing XML code comments",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"formatExpression": {
"description": "missing XML code comments",
"type": "string"
},
"sourceField": {
"description": "missing XML code comments",
"type": "string"
}
}
},
{
"title": "FieldValueMap",
"description": "Maps field values based on a lookup table, allowing specific source values to be translated to different target values.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"defaultValue": {
"description": "Gets or sets the default value to use when no mapping is found for the source field value.",
"type": "string"
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"sourceField": {
"description": "Gets or sets the name of the source field to read values from during migration.",
"type": "string"
},
"targetField": {
"description": "Gets or sets the name of the target field to write mapped values to during migration.",
"type": "string"
},
"valueMapping": {
"description": "Gets or sets the dictionary that maps source field values to target field values. Key is the source value, value is the target value.",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
{
"title": "MultiValueConditionalMap",
"description": "missing XML code comments",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"sourceFieldsAndValues": {
"description": "missing XML code comments",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"targetFieldsAndValues": {
"description": "missing XML code comments",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
{
"title": "RegexFieldMap",
"description": "Applies regular expression transformations to map values from a source field to a target field using pattern matching and replacement.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"pattern": {
"description": "Gets or sets the regular expression pattern to match against the source field value.",
"type": "string"
},
"replacement": {
"description": "Gets or sets the replacement pattern that defines how matched groups should be used to construct the target value.",
"type": "string"
},
"sourceField": {
"description": "Gets or sets the name of the source field to read data from and apply regex pattern matching.",
"type": "string"
},
"targetField": {
"description": "Gets or sets the name of the target field to write the regex-transformed data to.",
"type": "string"
}
}
},
{
"title": "TreeToTagFieldMap",
"description": "Maps work item area path or iteration path hierarchies to tags, allowing tree structures to be represented as flat tag collections.",
"type": "object",
"properties": {
"ApplyTo": {
"description": "A list of Work Item Types that this Field Map will apply to. If the list is empty it will apply to all Work Item Types. You can use \"*\" to apply to all Work Item Types.",
"type": "array",
"prefixItems": [
{
"type": "string"
}
]
},
"Enabled": {
"description": "If set to `true` then the Fieldmap will run. Set to `false` and the processor will not run.",
"type": "boolean"
},
"timeTravel": {
"description": "Gets or sets the number of months to travel back in time when looking up historical area path values. Use 0 for current values.",
"type": "integer"
},
"toSkip": {
"description": "Gets or sets the number of levels to skip from the root when converting area path hierarchy to tags. For example, if set to 2, \"ProjectName\\Level1\\Level2\\Level3\" would skip \"ProjectName\\Level1\" and start from \"Level2\".",
"type": "integer"
}
}
}
]
}
]
}
}
}
In this article
Project Information
Azure DevOps Marketplace
Maintainer
Created and maintained by Martin Hinshelwood of nkdagility.com
Getting Support
Community Support
The first place to look for usage, configuration, and general help.
Commercial Support
We provide training, ad-hoc support, and full service migrations through our professional services.
Azure DevOps Migration Services