public async Task <Build> LinkBuildWithPr(Build build) { try { var devopsbuild = await _buildHttpClient.GetBuildAsync(build.Project, int.Parse(build.Id)); if (devopsbuild.Reason != BuildReason.PullRequest) { return(build); } var project = devopsbuild.Project.Name; var repo = devopsbuild.Repository.Name; var prId = devopsbuild.TriggerInfo.FirstOrDefault(k => k.Key == "pr.number").Value; var url = DevOpsUtils.FormatPrUrl(_config.BaseUrl, project, repo, prId); build.PullRequest = new PullRequest { Id = prId, ProjectName = project, RepositoryName = repo, Url = url }; return(build); } catch (VssException ex) when(ex.Message == "VS30063: You are not authorized to access https://dev.azure.com.") { //TODO error handling: PAT expired or missing scope "Build -> Read" throw; } }
public void GivenSpacesInNamesShouldBeUrlEncoded() { var url = "https://dev.azure.com/collabassistorg/CollabAssist%20Project/_git/Collab%20Assist/pullrequest/1337"; var pr = TestUtils.GenerateValidDevOpsPrNotificationWithSpacesInNames(); var formattedUrl = DevOpsUtils.FormatPrUrl(pr); formattedUrl .Should() .Be(url); }
public void GivenInvalidNotificationShouldThrow() { var pr = TestUtils.GenerateValidDevOpsPrNotification(); pr.Resource.Repository.Project = null; Action formatAction = () => DevOpsUtils.FormatPrUrl(pr); formatAction .Should() .Throw <Exception>(); }
public void GivenValidNotificationShouldFormatPrUrl() { var pr = TestUtils.GenerateValidDevOpsPrNotification(); var url = "https://dev.azure.com/collabassistorg/CollabAssistProject/_git/CollabAssist/pullrequest/1337"; var formattedUrl = DevOpsUtils.FormatPrUrl(pr); formattedUrl .Should() .Be(url); }
public PullRequest To() { var pr = new PullRequest { Id = Resource.PullRequestId.ToString(), Title = Resource.Title, CreatedDate = CreatedDate, Url = DevOpsUtils.FormatPrUrl(this), AuthorName = Resource.CreatedBy.DisplayName, AuthorEmail = Resource.CreatedBy.UniqueName, ProjectName = Resource.Repository.Project.Name, RepositoryName = Resource.Repository.Name }; if (Resource.Reviewers != null) { foreach (var devopsReviewer in Resource.Reviewers) { var reviewer = new Incoming.Models.Reviewer(devopsReviewer.DisplayName); switch (devopsReviewer.Vote) { case ReviewerVote.Rejected: reviewer.Vote = Vote.Rejected; break; case ReviewerVote.WaitingForAuthor: reviewer.Vote = Vote.Waiting; break; case ReviewerVote.ApprovedWithSuggestions: reviewer.Vote = Vote.ApprovedWithSuggestions; break; case ReviewerVote.Approved: reviewer.Vote = Vote.Approved; break; default: reviewer.Vote = Vote.Unknown; break; } pr.Reviewers.Add(reviewer); } } if (Resource.Status == "completed") { pr.Status = PullRequestStatus.Completed; } else if (Resource.Status == "abandoned") { pr.Status = PullRequestStatus.Abandoned; } else if (Resource.Status == "active" && pr.Reviewers.Count == 0) { pr.Status = PullRequestStatus.New; } else if (Resource.Status == "active" && pr.Reviewers.Count > 0) { if (pr.Reviewers.TrueForAll(r => r.Vote == Vote.Approved || r.Vote == Vote.ApprovedWithSuggestions)) { pr.Status = PullRequestStatus.ApprovedUncompleted; } else if (pr.Reviewers.Count(r => r.Vote == Vote.Rejected) > 0) { pr.Status = PullRequestStatus.Rejected; } else { pr.Status = PullRequestStatus.WaitingApproval; } } else { pr.Status = PullRequestStatus.Unknown; } return(pr); }