private void IssueUpdated(Issue issue, Card card, BoardMapping boardMapping) { Log.Info("Issue [{0}] updated, comparing to corresponding card...", issue.Id); long boardId = boardMapping.Identity.LeanKit; // sync and save those items that are different (of title, description, priority) bool saveCard = false; if (issue.Title != card.Title) { card.Title = issue.Title; saveCard = true; } if (issue.Body.SanitizeCardDescription() != card.Description) { card.Description = issue.Body.SanitizeCardDescription(); saveCard = true; } var priority = issue.LeanKitPriority(); if (priority != card.Priority) { card.Priority = priority; saveCard = true; } if (issue.Labels != null && issue.Labels.Count > 0) { var tags = string.Join(",", issue.Labels.Select(x => x.Name)); if (card.Tags != tags) { card.Tags = tags; saveCard = true; } } else if (!string.IsNullOrEmpty(card.Tags)) { card.Tags = ""; saveCard = true; } if (issue.Milestone != null && issue.Milestone.Due_On != null) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; var dueDateString = issue.Milestone.Due_On.Value.ToString(dateFormat); if (card.DueDate != dueDateString) { card.DueDate = dueDateString; saveCard = true; } } } else if (!string.IsNullOrEmpty(card.DueDate)) { card.DueDate = ""; saveCard = true; } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && boardMapping.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } saveCard = true; } var lanes = boardMapping.LanesFromState(issue.State); if (lanes.Count > 0 && lanes.All(x => x != card.LaneId)) { card.LaneId = lanes.First(); saveCard = true; } if (saveCard) { Log.Info("Updating card [{0}]", card.Id); LeanKit.UpdateCard(boardId, card); } }
private void CreateCardFromItem(BoardMapping project, Issue issue) { if (issue == null) { return; } if (!project.CreateCards) { Log.Debug("CreateCards is disabled, skipping card creation."); return; } var boardId = project.Identity.LeanKit; var mappedCardType = issue.LeanKitCardType(project); var laneId = project.LanesFromState(issue.State).First(); var card = new Card { Active = true, Title = issue.Title, Description = issue.Body.SanitizeCardDescription(), Priority = issue.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = issue.Id + "|" + issue.Number, ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, project.Identity.Target, issue.Number), Index = 9999 }; var assignedUserId = issue.LeanKitAssignedUserId(boardId, LeanKit); if (assignedUserId != null) { card.AssignedUserIds = new[] { assignedUserId.Value } } ; if (issue.Milestone != null && issue.Milestone.Due_On != null) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = issue.Milestone.Due_On.Value.ToString(dateFormat); } } if (issue.Labels != null && issue.Labels.Any()) { card.Tags = string.Join(",", issue.Labels.Select(x => x.Name).ToList()); } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } } Log.Info("Creating a card of type [{0}] for Issue [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, issue.Number, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for issue [{0}] attempt number [{1}]", issue.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From GitHub Issue"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for Issue [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, issue.Number, boardId, laneId); }
private void CreateCardFromWorkItem(BoardMapping project, WorkItem workItem) { if (workItem == null) return; var boardId = project.Identity.LeanKit; var mappedCardType = workItem.LeanKitCardType(project); var laneId = project.LanesFromState(workItem.State).First(); var card = new Card { Active = true, Title = workItem.Title, Description = workItem.LeanKitDescription(GetTfsVersion()), Priority = workItem.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = workItem.Id.ToString(CultureInfo.InvariantCulture), ExternalSystemName = ServiceName }; if (workItem.Fields.Contains("Tags") && workItem.Fields["Tags"] != null && workItem.Fields["Tags"].Value != null) { card.Tags = workItem.Fields["Tags"].Value.ToString().Replace(";", ","); } if (project.TagCardsWithTargetSystemName && (card.Tags == null || !card.Tags.Contains(ServiceName))) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; } if (_projectHyperlinkService != null) { card.ExternalSystemUrl = _projectHyperlinkService.GetWorkItemEditorUrl(workItem.Id).ToString(); } if (workItem.Fields != null && workItem.Fields.Contains("Assigned To")) { if (workItem.Fields["Assigned To"] != null && workItem.Fields["Assigned To"].Value != null) { var assignedUserId = CalculateAssignedUserId(boardId, workItem.Fields["Assigned To"].Value.ToString()); if (assignedUserId != null) card.AssignedUserIds = new[] {assignedUserId.Value}; } } if (workItem.Fields != null && workItem.Fields.Contains("Due Date")) { if (workItem.Fields["Due Date"] != null && workItem.Fields["Due Date"].Value != null) { DateTime tfsDueDate; var isDate = DateTime.TryParse(workItem.Fields["Due Date"].Value.ToString(), out tfsDueDate); if (isDate) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = tfsDueDate.ToString(dateFormat); } } } } if (workItem.Fields != null && (workItem.Fields.Contains("Original Estimate") || workItem.Fields.Contains("Story Points"))) { if (workItem.Fields.Contains("Original Estimate") && workItem.Fields["Original Estimate"] != null && workItem.Fields["Original Estimate"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Original Estimate"].Value.ToString(), out cardSize); if (isNumber) card.Size = (int)cardSize; } else if (workItem.Fields.Contains("Story Points") && workItem.Fields["Story Points"] != null && workItem.Fields["Story Points"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Story Points"].Value.ToString(), out cardSize); if (isNumber) card.Size = (int) cardSize; } } Log.Info("Creating a card of type [{0}] for work item [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, workItem.Id, boardId, laneId); CardAddResult cardAddResult = null; var tries = 0; var success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Warn(String.Format("Attempting to create card for work item [{0}] attempt number [{1}]", workItem.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From TFS Work Item"); success = true; } catch (Exception ex) { Log.Error(ex, string.Format("An error occurred creating a new card for work item [{0}]", workItem.Id)); } tries++; } card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for work item [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, workItem.Id, boardId, laneId); }
private void WorkItemUpdated(WorkItem workItem, Card card, BoardMapping project) { Log.Info("WorkItem [{0}] updated, comparing to corresponding card...", workItem.Id); var boardId = project.Identity.LeanKit; // sync and save those items that are different (of title, description, priority) var saveCard = false; if (workItem.Title != card.Title) { card.Title = workItem.Title; saveCard = true; } var description = workItem.LeanKitDescription(GetTfsVersion()); if (description != card.Description) { card.Description = description; saveCard = true; } var priority = workItem.LeanKitPriority(); if(priority!= card.Priority) { card.Priority = priority; saveCard = true; } if(workItem.Fields!=null && workItem.Fields.Contains("Tags") && workItem.Fields["Tags"] != null && workItem.Fields["Tags"].Value.ToString() != card.Tags) { var tfsTags = workItem.Fields["Tags"].Value.ToString(); // since we cannot set the tags in TFS we cannot blindly overwrite the LK tags // with what is in TFS. Instead we can only add TFS tags to LK if (!string.IsNullOrEmpty(tfsTags)) { var tfsTagsArr = tfsTags.Contains(',') ? tfsTags.Split(',') : tfsTags.Split(';'); foreach (var tag in tfsTagsArr) { if (card.Tags != null && card.Tags.ToLowerInvariant().Contains(tag.ToLowerInvariant())) continue; if (string.IsNullOrEmpty(card.Tags)) card.Tags = tag; else card.Tags += "," + tag; saveCard = true; } } } if (workItem.Fields != null && (workItem.Fields.Contains("Original Estimate") || workItem.Fields.Contains("Story Points"))) { if (workItem.Fields.Contains("Original Estimate") && workItem.Fields["Original Estimate"] != null && workItem.Fields["Original Estimate"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Original Estimate"].Value.ToString(), out cardSize); if (isNumber) { var size = (int) cardSize; if (card.Size != size) { card.Size = size; saveCard = true; } } } else if (workItem.Fields.Contains("Story Points") && workItem.Fields["Story Points"] != null && workItem.Fields["Story Points"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Story Points"].Value.ToString(), out cardSize); if (isNumber) { var size = (int)cardSize; if (card.Size != size) { card.Size = size; saveCard = true; } } } } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; saveCard = true; } if(saveCard) { Log.Info("Updating card [{0}]", card.Id); LeanKit.UpdateCard(boardId, card); } // check the state of the work item // if we have the state mapped to a lane then check to see if the card is in that lane // if it is not in that lane then move it to that lane if (!project.UpdateCardLanes || string.IsNullOrEmpty(workItem.State)) return; // if card is already in archive lane then we do not want to move it to the end lane // because it is effectively the same thing with respect to integrating with TFS if (card.LaneId == project.ArchiveLaneId) { return; } var laneIds = project.LanesFromState(workItem.State); if (laneIds.Any()) { if (!laneIds.Contains(card.LaneId)) { // first let's see if any of the lanes are sibling lanes, if so then // we should be using one of them. So we'll limit the results to just siblings if (project.ValidLanes != null) { var siblingLaneIds = (from siblingLaneId in laneIds let parentLane = project.ValidLanes.FirstOrDefault(x => x.HasChildLanes && x.ChildLaneIds.Contains(siblingLaneId) && x.ChildLaneIds.Contains(card.LaneId)) where parentLane != null select siblingLaneId).ToList(); if (siblingLaneIds.Any()) laneIds = siblingLaneIds; } LeanKit.MoveCard(project.Identity.LeanKit, card.Id, laneIds.First(), 0, "Moved Lane From TFS Work Item"); } } }
private void IssueUpdated(Issue issue, Card card, BoardMapping boardMapping) { Log.Info("Issue [{0}] updated, comparing to corresponding card...", issue.Key); long boardId = boardMapping.Identity.LeanKit; // sync and save those items that are different (of title, description, priority) bool saveCard = false; if (issue.Fields != null) { if (issue.Fields.Summary != null && issue.Fields.Summary != card.Title) { card.Title = issue.Fields.Summary; saveCard = true; } if (issue.Fields.Description != null && issue.Fields.Description.SanitizeCardDescription().JiraPlainTextToLeanKitHtml() != card.Description) { card.Description = issue.Fields.Description.SanitizeCardDescription().JiraPlainTextToLeanKitHtml(); saveCard = true; } var priority = issue.LeanKitPriority(); if (priority != card.Priority) { card.Priority = priority; saveCard = true; } if (issue.Fields.Labels != null && issue.Fields.Labels.Count > 0) { var tags = string.Join(",", issue.Fields.Labels.Select(x => x)); if (card.Tags != tags) { card.Tags = tags; saveCard = true; } } else if (!string.IsNullOrEmpty(card.Tags)) { card.Tags = ""; saveCard = true; } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && boardMapping.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; saveCard = true; } if (issue.Fields.DueDate != null && CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; var dueDateString = issue.Fields.DueDate.Value.ToString(dateFormat, CultureInfo.InvariantCulture); if (card.DueDate != dueDateString) { card.DueDate = dueDateString; saveCard = true; } } else if (!string.IsNullOrEmpty(card.DueDate)) { card.DueDate = ""; saveCard = true; } } if (saveCard) { Log.Info("Updating card [{0}]", card.Id); LeanKit.UpdateCard(boardId, card); } // check the state of the work item // if we have the state mapped to a lane then check to see if the card is in that lane // if it is not in that lane then move it to that lane if (boardMapping.UpdateCardLanes && issue.Fields != null && issue.Fields.Status != null && !string.IsNullOrEmpty(issue.Fields.Status.Name)) { var laneIds = boardMapping.LanesFromState(issue.Fields.Status.Name); if (laneIds.Any()) { if (!laneIds.Contains(card.LaneId)) { // first let's see if any of the lanes are sibling lanes, if so then // we should be using one of them. So we'll limit the results to just siblings if (boardMapping.ValidLanes != null) { var siblingLaneIds = (from siblingLaneId in laneIds let parentLane = boardMapping.ValidLanes.FirstOrDefault(x => x.HasChildLanes && x.ChildLaneIds.Contains(siblingLaneId) && x.ChildLaneIds.Contains(card.LaneId)) where parentLane != null select siblingLaneId).ToList(); if (siblingLaneIds.Any()) laneIds = siblingLaneIds; } LeanKit.MoveCard(boardMapping.Identity.LeanKit, card.Id, laneIds.First(), 0, "Moved Lane From Jira Issue"); } } } }
private void CreateCardFromItem(BoardMapping project, Issue issue) { if (issue == null) return; var boardId = project.Identity.LeanKit; var mappedCardType = issue.LeanKitCardType(project); var validLanes = project.LanesFromState(issue.Fields.Status.Name); var laneId = validLanes.Any() ? validLanes.First() : project.DefaultCardCreationLaneId; var card = new Card { Active = true, Title = issue.Fields.Summary, Description = issue.Fields.Description.SanitizeCardDescription().JiraPlainTextToLeanKitHtml(), Priority = issue.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = issue.Key, ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, issue.Key) }; var assignedUserId = issue.LeanKitAssignedUserId(boardId, LeanKit); if (assignedUserId != null) card.AssignedUserIds = new[] {assignedUserId.Value}; if (issue.Fields != null && issue.Fields.DueDate != null && CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = issue.Fields.DueDate.Value.ToString(dateFormat, CultureInfo.InvariantCulture); } if (issue.Fields != null && issue.Fields.Labels != null && issue.Fields.Labels.Any()) { card.Tags = string.Join(",", issue.Fields.Labels); } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; } // TODO: Add size from the custom story points field. Log.Info("Creating a card of type [{0}] for issue [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, issue.Key, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for work item [{0}] attempt number [{1}]", issue.Key, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From Jira Issue"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for work item [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, issue.Key, boardId, laneId); }
private void IssueUpdated(Issue issue, Card card, BoardMapping boardMapping) { Log.Info("Issue [{0}] updated, comparing to corresponding card...", issue.Key); long boardId = boardMapping.Identity.LeanKit; // sync and save those items that are different (of title, description, priority) bool saveCard = false; if (issue.Fields != null) { if (issue.Fields.Summary != null && issue.Fields.Summary != card.Title) { card.Title = issue.Fields.Summary; saveCard = true; } if (issue.Fields.Description != null && issue.Fields.Description.SanitizeCardDescription() != card.Description) { card.Description = issue.Fields.Description.SanitizeCardDescription(); saveCard = true; } var priority = issue.LeanKitPriority(); if (priority != card.Priority) { card.Priority = priority; saveCard = true; } if (issue.Fields.Labels != null && issue.Fields.Labels.Count > 0) { var tags = string.Join(",", issue.Fields.Labels.Select(x => x)); if (card.Tags != tags) { card.Tags = tags; saveCard = true; } } else if (!string.IsNullOrEmpty(card.Tags)) { card.Tags = ""; saveCard = true; } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && boardMapping.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } saveCard = true; } if (issue.Fields.DueDate != null && CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; var dueDateString = issue.Fields.DueDate.Value.ToString(dateFormat, CultureInfo.InvariantCulture); if (card.DueDate != dueDateString) { card.DueDate = dueDateString; saveCard = true; } } else if (!string.IsNullOrEmpty(card.DueDate)) { card.DueDate = ""; saveCard = true; } } if (saveCard) { Log.Info("Updating card [{0}]", card.Id); LeanKit.UpdateCard(boardId, card); } // check the state of the work item // if we have the state mapped to a lane then check to see if the card is in that lane // if it is not in that lane then move it to that lane if (boardMapping.UpdateCardLanes && issue.Fields != null && issue.Fields.Status != null && !string.IsNullOrEmpty(issue.Fields.Status.Name)) { // if card is already in archive lane then we do not want to move it to the end lane // because it is effectively the same thing with respect to integrating with TFS if (card.LaneId == boardMapping.ArchiveLaneId) { return; } var laneIds = boardMapping.LanesFromState(issue.Fields.Status.Name); if (laneIds.Any()) { if (!laneIds.Contains(card.LaneId)) { // first let's see if any of the lanes are sibling lanes, if so then // we should be using one of them. So we'll limit the results to just siblings if (boardMapping.ValidLanes != null) { var siblingLaneIds = (from siblingLaneId in laneIds let parentLane = boardMapping.ValidLanes.FirstOrDefault(x => x.HasChildLanes && x.ChildLaneIds.Contains(siblingLaneId) && x.ChildLaneIds.Contains(card.LaneId)) where parentLane != null select siblingLaneId).ToList(); if (siblingLaneIds.Any()) { laneIds = siblingLaneIds; } } LeanKit.MoveCard(boardMapping.Identity.LeanKit, card.Id, laneIds.First(), 0, "Moved Lane From Jira Issue"); } } } }
private void CreateCardFromItem(BoardMapping project, Issue issue) { if (issue == null) { return; } var boardId = project.Identity.LeanKit; var mappedCardType = issue.LeanKitCardType(project); var validLanes = project.LanesFromState(issue.Fields.Status.Name); var laneId = validLanes.Any() ? validLanes.First() : project.DefaultCardCreationLaneId; var card = new Card { Active = true, Title = issue.Fields.Summary, Description = issue.Fields.Description.SanitizeCardDescription(), Priority = issue.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = issue.Key, ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, issue.Key) }; var assignedUserId = issue.LeanKitAssignedUserId(boardId, LeanKit); if (assignedUserId != null) { card.AssignedUserIds = new[] { assignedUserId.Value } } ; if (issue.Fields != null && issue.Fields.DueDate != null && CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = issue.Fields.DueDate.Value.ToString(dateFormat, CultureInfo.InvariantCulture); } if (issue.Fields != null && issue.Fields.Labels != null && issue.Fields.Labels.Any()) { card.Tags = string.Join(",", issue.Fields.Labels); } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } } // TODO: Add size from the custom story points field. Log.Info("Creating a card of type [{0}] for issue [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, issue.Key, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for work item [{0}] attempt number [{1}]", issue.Key, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From Jira Issue"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for work item [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, issue.Key, boardId, laneId); }
private void IssueUpdated(Issue issue, Card card, BoardMapping boardMapping) { Log.Info("Issue [{0}] updated, comparing to corresponding card...", issue.Id); long boardId = boardMapping.Identity.LeanKit; // sync and save those items that are different (of title, description, priority) bool saveCard = false; if (issue.Title != card.Title) { card.Title = issue.Title; saveCard = true; } if (issue.Body.SanitizeCardDescription() != card.Description) { card.Description = issue.Body.SanitizeCardDescription(); saveCard = true; } var priority = issue.LeanKitPriority(); if (priority != card.Priority) { card.Priority = priority; saveCard = true; } if (issue.Labels != null && issue.Labels.Count > 0) { var tags = string.Join(",", issue.Labels.Select(x => x.Name)); if (card.Tags != tags) { card.Tags = tags; saveCard = true; } } else if (!string.IsNullOrEmpty(card.Tags)) { card.Tags = ""; saveCard = true; } if (issue.Milestone != null && issue.Milestone.Due_On != null) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; var dueDateString = issue.Milestone.Due_On.Value.ToString(dateFormat); if (card.DueDate != dueDateString) { card.DueDate = dueDateString; saveCard = true; } } } else if (!string.IsNullOrEmpty(card.DueDate)) { card.DueDate = ""; saveCard = true; } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && boardMapping.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; saveCard = true; } var lanes = boardMapping.LanesFromState(issue.State); if (lanes.Count > 0 && lanes.All(x => x != card.LaneId)) { card.LaneId = lanes.First(); saveCard = true; } if (saveCard) { Log.Info("Updating card [{0}]", card.Id); LeanKit.UpdateCard(boardId, card); } }
private void CreateCardFromItem(BoardMapping project, Issue issue) { if (issue == null) return; var boardId = project.Identity.LeanKit; var mappedCardType = issue.LeanKitCardType(project); var laneId = project.LanesFromState(issue.State).First(); var card = new Card { Active = true, Title = issue.Title, Description = issue.Body.SanitizeCardDescription(), Priority = issue.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = issue.Id + "|" + issue.Number, ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, project.Identity.Target, issue.Number) }; var assignedUserId = issue.LeanKitAssignedUserId(boardId, LeanKit); if (assignedUserId != null) card.AssignedUserIds = new[] { assignedUserId.Value }; if (issue.Milestone != null && issue.Milestone.Due_On != null) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = issue.Milestone.Due_On.Value.ToString(dateFormat); } } if (issue.Labels != null && issue.Labels.Any()) { card.Tags = string.Join(",", issue.Labels.Select(x => x.Name).ToList()); } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; } Log.Info("Creating a card of type [{0}] for Issue [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, issue.Number, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for issue [{0}] attempt number [{1}]", issue.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From GitHub Issue"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for Issue [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, issue.Number, boardId, laneId); }
private void CreateCardFromItem(BoardMapping project, Pull pull) { if (pull == null) return; var boardId = project.Identity.LeanKit; var mappedCardType = pull.LeanKitCardType(project); var laneId = project.LanesFromState(pull.State).First(); var card = new Card { Active = true, Title = pull.Title, Description = pull.Body.SanitizeCardDescription(), Priority = pull.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = pull.Id.ToString() + "|" + pull.Number.ToString(), ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, project.Identity.Target, pull.Number) }; var assignedUserId = pull.LeanKitAssignedUser(boardId, LeanKit); if (assignedUserId != null) card.AssignedUserIds = new[] { assignedUserId.Value }; if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) card.Tags = ServiceName; else card.Tags += "," + ServiceName; } Log.Info("Creating a card of type [{0}] for Pull Request [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, pull.Number, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for Pull Request [{0}] attempt number [{1}]", pull.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From GitHub Pull Request"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } if (cardAddResult != null) card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for Pull Request [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, pull.Number, boardId, laneId); }
private void CreateCardFromItem(BoardMapping project, Pull pull) { if (pull == null) { return; } var boardId = project.Identity.LeanKit; var mappedCardType = pull.LeanKitCardType(project); var laneId = project.LanesFromState(pull.State).First(); var card = new Card { Active = true, Title = pull.Title, Description = pull.Body.SanitizeCardDescription(), Priority = pull.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = pull.Id.ToString() + "|" + pull.Number.ToString(), ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, project.Identity.Target, pull.Number) }; var assignedUserId = pull.LeanKitAssignedUser(boardId, LeanKit); if (assignedUserId != null) { card.AssignedUserIds = new[] { assignedUserId.Value } } ; if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } } Log.Info("Creating a card of type [{0}] for Pull Request [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, pull.Number, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for Pull Request [{0}] attempt number [{1}]", pull.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From GitHub Pull Request"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } if (cardAddResult != null) { card.Id = cardAddResult.CardId; } Log.Info("Created a card [{0}] of type [{1}] for Pull Request [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, pull.Number, boardId, laneId); }
private void CreateCardFromItem(BoardMapping project, Ticket ticket) { if (ticket == null) { return; } var boardId = project.Identity.LeanKit; var mappedCardType = ticket.LeanKitCardType(project); var laneId = project.LanesFromState(ticket.Status).First(); var card = new Card { Active = true, Title = ticket.Summary, Description = ticket.Description.SanitizeCardDescription(), Priority = ticket.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = ticket.Id.ToString(), ExternalSystemName = ServiceName, ExternalSystemUrl = string.Format(_externalUrlTemplate, ticket.Id, project.Identity.Target) }; var assignedUserId = CalculateAssignedUserId(boardId, ticket); if (assignedUserId != null) { card.AssignedUserIds = new[] { assignedUserId.Value } } ; if (ticket.Due_On != null) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = ticket.Due_On.Value.ToString(dateFormat); } } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } } Log.Info("Creating a card of type [{0}] for ticket [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, ticket.Id, boardId, laneId); CardAddResult cardAddResult = null; int tries = 0; bool success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Error(string.Format("Attempting to create card for ticket [{0}] attempt number [{1}]", ticket.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From Unfuddle Ticket"); success = true; } catch (Exception ex) { Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace)); } tries++; } if (cardAddResult != null) { card.Id = cardAddResult.CardId; } Log.Info("Created a card [{0}] of type [{1}] for ticket [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, ticket.Id, boardId, laneId); }
private void WorkItemUpdated(WorkItem workItem, Card card, BoardMapping project) { Log.Info("WorkItem [{0}] updated, comparing to corresponding card...", workItem.Id); var boardId = project.Identity.LeanKit; // sync and save those items that are different (of title, description, priority) var saveCard = false; if (workItem.Title != card.Title) { card.Title = workItem.Title; saveCard = true; } var description = workItem.LeanKitDescription(GetTfsVersion()); if (description != card.Description) { card.Description = description; saveCard = true; } var priority = workItem.LeanKitPriority(); if (priority != card.Priority) { card.Priority = priority; saveCard = true; } if (workItem.Fields != null && workItem.Fields.Contains("Tags") && workItem.Fields["Tags"] != null && workItem.Fields["Tags"].Value.ToString() != card.Tags) { var tfsTags = workItem.Fields["Tags"].Value.ToString(); // since we cannot set the tags in TFS we cannot blindly overwrite the LK tags // with what is in TFS. Instead we can only add TFS tags to LK if (!string.IsNullOrEmpty(tfsTags)) { var tfsTagsArr = tfsTags.Split(','); foreach (var tag in tfsTagsArr) { if (card.Tags.ToLowerInvariant().Contains(tag.ToLowerInvariant())) { continue; } if (card.Tags == string.Empty) { card.Tags = tag; } else { card.Tags += "," + tag; } saveCard = true; } } } if (workItem.Fields != null && (workItem.Fields.Contains("Original Estimate") || workItem.Fields.Contains("Story Points"))) { if (workItem.Fields.Contains("Original Estimate") && workItem.Fields["Original Estimate"] != null && workItem.Fields["Original Estimate"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Original Estimate"].Value.ToString(), out cardSize); if (isNumber) { var size = (int)cardSize; if (card.Size != size) { card.Size = size; saveCard = true; } } } else if (workItem.Fields.Contains("Story Points") && workItem.Fields["Story Points"] != null && workItem.Fields["Story Points"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Story Points"].Value.ToString(), out cardSize); if (isNumber) { var size = (int)cardSize; if (card.Size != size) { card.Size = size; saveCard = true; } } } } if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } saveCard = true; } if (saveCard) { Log.Info("Updating card [{0}]", card.Id); LeanKit.UpdateCard(boardId, card); } // check the state of the work item // if we have the state mapped to a lane then check to see if the card is in that lane // if it is not in that lane then move it to that lane if (!project.UpdateCardLanes || string.IsNullOrEmpty(workItem.State)) { return; } // if card is already in archive lane then we do not want to move it to the end lane // because it is effectively the same thing with respect to integrating with TFS if (card.LaneId == project.ArchiveLaneId) { return; } var laneIds = project.LanesFromState(workItem.State); if (laneIds.Any()) { if (!laneIds.Contains(card.LaneId)) { // first let's see if any of the lanes are sibling lanes, if so then // we should be using one of them. So we'll limit the results to just siblings if (project.ValidLanes != null) { var siblingLaneIds = (from siblingLaneId in laneIds let parentLane = project.ValidLanes.FirstOrDefault(x => x.HasChildLanes && x.ChildLaneIds.Contains(siblingLaneId) && x.ChildLaneIds.Contains(card.LaneId)) where parentLane != null select siblingLaneId).ToList(); if (siblingLaneIds.Any()) { laneIds = siblingLaneIds; } } LeanKit.MoveCard(project.Identity.LeanKit, card.Id, laneIds.First(), 0, "Moved Lane From TFS Work Item"); } } }
private void CreateCardFromWorkItem(BoardMapping project, WorkItem workItem) { if (workItem == null) { return; } var boardId = project.Identity.LeanKit; var mappedCardType = workItem.LeanKitCardType(project); var laneId = project.LanesFromState(workItem.State).First(); var card = new Card { Active = true, Title = workItem.Title, Description = workItem.LeanKitDescription(GetTfsVersion()), Priority = workItem.LeanKitPriority(), TypeId = mappedCardType.Id, TypeName = mappedCardType.Name, LaneId = laneId, ExternalCardID = workItem.Id.ToString(CultureInfo.InvariantCulture), ExternalSystemName = ServiceName }; if (workItem.Fields.Contains("Tags") && workItem.Fields["Tags"] != null && workItem.Fields["Tags"].Value != null) { card.Tags = workItem.Fields["Tags"].Value.ToString(); } if (project.TagCardsWithTargetSystemName && (card.Tags == null || !card.Tags.Contains(ServiceName))) { if (string.IsNullOrEmpty(card.Tags)) { card.Tags = ServiceName; } else { card.Tags += "," + ServiceName; } } if (_projectHyperlinkService != null) { card.ExternalSystemUrl = _projectHyperlinkService.GetWorkItemEditorUrl(workItem.Id).ToString(); } if (workItem.Fields != null && workItem.Fields.Contains("Assigned To")) { if (workItem.Fields["Assigned To"] != null && workItem.Fields["Assigned To"].Value != null) { var assignedUserId = CalculateAssignedUserId(boardId, workItem.Fields["Assigned To"].Value.ToString()); if (assignedUserId != null) { card.AssignedUserIds = new[] { assignedUserId.Value } } ; } } if (workItem.Fields != null && workItem.Fields.Contains("Due Date")) { if (workItem.Fields["Due Date"] != null && workItem.Fields["Due Date"].Value != null) { DateTime tfsDueDate; var isDate = DateTime.TryParse(workItem.Fields["Due Date"].Value.ToString(), out tfsDueDate); if (isDate) { if (CurrentUser != null) { var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy"; card.DueDate = tfsDueDate.ToString(dateFormat); } } } } if (workItem.Fields != null && (workItem.Fields.Contains("Original Estimate") || workItem.Fields.Contains("Story Points"))) { if (workItem.Fields.Contains("Original Estimate") && workItem.Fields["Original Estimate"] != null && workItem.Fields["Original Estimate"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Original Estimate"].Value.ToString(), out cardSize); if (isNumber) { card.Size = (int)cardSize; } } else if (workItem.Fields.Contains("Story Points") && workItem.Fields["Story Points"] != null && workItem.Fields["Story Points"].Value != null) { double cardSize; var isNumber = Double.TryParse(workItem.Fields["Story Points"].Value.ToString(), out cardSize); if (isNumber) { card.Size = (int)cardSize; } } } Log.Info("Creating a card of type [{0}] for work item [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name, workItem.Id, boardId, laneId); CardAddResult cardAddResult = null; var tries = 0; var success = false; while (tries < 10 && !success) { if (tries > 0) { Log.Warn(String.Format("Attempting to create card for work item [{0}] attempt number [{1}]", workItem.Id, tries)); // wait 5 seconds before trying again Thread.Sleep(new TimeSpan(0, 0, 5)); } try { cardAddResult = LeanKit.AddCard(boardId, card, "New Card From TFS Work Item"); success = true; } catch (Exception ex) { Log.Error(ex, string.Format("An error occurred creating a new card for work item [{0}]", workItem.Id)); } tries++; } card.Id = cardAddResult.CardId; Log.Info("Created a card [{0}] of type [{1}] for work item [{2}] on Board [{3}] on Lane [{4}]", card.Id, mappedCardType.Name, workItem.Id, boardId, laneId); }