private void MigrateSharedSteps(WorkItemData wiSourceL, WorkItemData wiTargetL, IWorkItemMigrationClient sourceStore, IWorkItemMigrationClient targetStore, bool save) { const string microsoftVstsTcmSteps = "Microsoft.VSTS.TCM.Steps"; var oldSteps = wiTargetL.ToWorkItem().Fields[microsoftVstsTcmSteps].Value.ToString(); var newSteps = oldSteps; var sourceSharedStepLinks = wiSourceL.ToWorkItem().Links.OfType <RelatedLink>() .Where(x => x.LinkTypeEnd.Name == "Shared Steps").ToList(); var sourceSharedSteps = sourceSharedStepLinks.Select(x => sourceStore.GetWorkItem(x.RelatedWorkItemId.ToString())); foreach (WorkItemData sourceSharedStep in sourceSharedSteps) { WorkItemData matchingTargetSharedStep = targetStore.FindReflectedWorkItemByReflectedWorkItemId(sourceSharedStep); if (matchingTargetSharedStep != null) { newSteps = newSteps.Replace($"ref=\"{sourceSharedStep.Id}\"", $"ref=\"{matchingTargetSharedStep.Id}\""); wiTargetL.ToWorkItem().Fields[microsoftVstsTcmSteps].Value = newSteps; } } if (wiTargetL.ToWorkItem().IsDirty&& save) { wiTargetL.ToWorkItem().Fields["System.ChangedBy"].Value = "Migration"; wiTargetL.ToWorkItem().Save(); } }
private void CreateRelatedLink(WorkItemData wiSourceL, RelatedLink item, WorkItemData wiTargetL, IWorkItemMigrationClient sourceStore, IWorkItemMigrationClient targetStore, bool save, string sourceReflectedWIIdField) { RelatedLink rl = (RelatedLink)item; WorkItemData wiSourceR = null; WorkItemData wiTargetR = null; try { wiSourceR = sourceStore.GetWorkItem(rl.RelatedWorkItemId.ToString()); } catch (Exception ex) { Log.Error(ex, " [FIND-FAIL] Adding Link of type {0} where wiSourceL={1}, wiTargetL={2} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiTargetL.Id); return; } try { wiTargetR = GetRightHandSideTargetWi(wiSourceL, wiSourceR, wiTargetL, targetStore, sourceStore, sourceReflectedWIIdField); } catch (Exception ex) { Log.Error(ex, " [FIND-FAIL] Adding Link of type {0} where wiSourceL={1}, wiTargetL={2} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiTargetL.Id); return; } if (wiTargetR != null) { bool IsExisting = false; try { var exist = ( from Link l in wiTargetL.ToWorkItem().Links where l is RelatedLink && ((RelatedLink)l).RelatedWorkItemId.ToString() == wiTargetR.Id && ((RelatedLink)l).LinkTypeEnd.ImmutableName == item.LinkTypeEnd.ImmutableName select(RelatedLink) l).SingleOrDefault(); IsExisting = (exist != null); } catch (Exception ex) { Log.Error(ex, " [SKIP] Unable to migrate links where wiSourceL={0}, wiSourceR={1}, wiTargetL={2}", ((wiSourceL != null) ? wiSourceL.Id.ToString() : "NotFound"), ((wiSourceR != null) ? wiSourceR.Id.ToString() : "NotFound"), ((wiTargetL != null) ? wiTargetL.Id.ToString() : "NotFound")); return; } if (!IsExisting && !wiTargetR.ToWorkItem().IsAccessDenied) { if (wiSourceR.Id != wiTargetR.Id) { Log.Information(" [CREATE-START] Adding Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); WorkItemLinkTypeEnd linkTypeEnd = ((WorkItemMigrationClient)targetStore).Store.WorkItemLinkTypes.LinkTypeEnds[rl.LinkTypeEnd.ImmutableName]; RelatedLink newRl = new RelatedLink(linkTypeEnd, int.Parse(wiTargetR.Id)); if (linkTypeEnd.ImmutableName == "System.LinkTypes.Hierarchy-Forward") { var potentialParentConflictLink = ( // TF201036: You cannot add a Child link between work items xxx and xxx because a work item can have only one Parent link. from Link l in wiTargetR.ToWorkItem().Links where l is RelatedLink && ((RelatedLink)l).LinkTypeEnd.ImmutableName == "System.LinkTypes.Hierarchy-Reverse" select(RelatedLink) l).SingleOrDefault(); if (potentialParentConflictLink != null) { wiTargetR.ToWorkItem().Links.Remove(potentialParentConflictLink); } linkTypeEnd = ((WorkItemMigrationClient)targetStore).Store.WorkItemLinkTypes.LinkTypeEnds["System.LinkTypes.Hierarchy-Reverse"]; RelatedLink newLl = new RelatedLink(linkTypeEnd, int.Parse(wiTargetL.Id)); wiTargetR.ToWorkItem().Links.Add(newLl); wiTargetR.ToWorkItem().Fields["System.ChangedBy"].Value = "Migration"; wiTargetR.ToWorkItem().Save(); } else { if (linkTypeEnd.ImmutableName == "System.LinkTypes.Hierarchy-Reverse") { var potentialParentConflictLink = ( // TF201065: You can not add a Parent link to this work item because a work item can have only one link of this type. from Link l in wiTargetL.ToWorkItem().Links where l is RelatedLink && ((RelatedLink)l).LinkTypeEnd.ImmutableName == "System.LinkTypes.Hierarchy-Reverse" select(RelatedLink) l).SingleOrDefault(); if (potentialParentConflictLink != null) { wiTargetL.ToWorkItem().Links.Remove(potentialParentConflictLink); } } wiTargetL.ToWorkItem().Links.Add(newRl); if (save) { wiTargetL.ToWorkItem().Fields["System.ChangedBy"].Value = "Migration"; wiTargetL.ToWorkItem().Save(); } } Log.Information( " [CREATE-SUCCESS] Adding Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); } else { Log.Information( " [SKIP] Unable to migrate link where Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} as target WI has not been migrated", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); } } else { if (IsExisting) { Log.Information(" [SKIP] Already Exists a Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); } if (wiTargetR.ToWorkItem().IsAccessDenied) { Log.Information(" [AccessDenied] The Target work item is inaccessable to create a Link of type {0} where wiSourceL={1}, wiSourceR={2}, wiTargetL={3}, wiTargetR={4} ", rl.LinkTypeEnd.ImmutableName, wiSourceL.Id, wiSourceR.Id, wiTargetL.Id, wiTargetR.Id); } } } else { Log.Information(" [SKIP] Cant find wiTargetR where wiSourceL={0}, wiSourceR={1}, wiTargetL={2}", wiSourceL.Id, wiSourceR.Id, wiTargetL.Id); } }