private bool AddThreadProperties( AzureDevOpsPullRequestCommentThread thread, IEnumerable <AzureDevOpsPullRequestIterationChange> changes, IIssue issue, int iterationId, string commentSource) { thread.NotNull(nameof(thread)); changes.NotNull(nameof(changes)); issue.NotNull(nameof(issue)); var properties = new Dictionary <string, object>(); if (issue.AffectedFileRelativePath != null) { if (this.azureDevOpsPullRequest.CodeReviewId > 0) { var changeTrackingId = this.TryGetCodeFlowChangeTrackingId(changes, issue.AffectedFileRelativePath); if (changeTrackingId < 0) { // Don't post comment if we couldn't determine the change. return(false); } AddCodeFlowProperties(issue, iterationId, changeTrackingId, properties); } else { throw new NotSupportedException("Legacy code reviews are not supported."); } } // An Azure DevOps UI extension will recognize this and format the comments differently. properties.Add("CodeAnalysisThreadType", "CodeAnalysisIssue"); thread.Properties = properties; // Add a custom property to be able to distinguish all comments created this way. thread.SetCommentSource(commentSource); // Add custom property for identifying the comment for subsequent runs thread.SetCommentIdentifier(issue.Identifier); // Add a custom property to be able to distinguish all comments by provider type later on thread.SetProviderType(issue.ProviderType); // Add a custom property to be able to return issue message from existing threads, // without any formatting done by this addin, back to Cake.Issues.PullRequests. thread.SetIssueMessage(issue.MessageText); return(true); }