private static void ParseRecord(GetPullRequestsOfRepositoryQueryResponse response, JToken rawPullRequest) { try { var pullRequest = new PullRequestInfo(); pullRequest.Number = rawPullRequest["node"].Value <int>("number"); pullRequest.TotalPullRequestFiles = rawPullRequest["node"]["files"]["totalCount"].Value <int>(); pullRequest.SubmitterLogin = rawPullRequest["node"]["author"].HasValues ? rawPullRequest["node"]["author"]["login"].ToString() : null; pullRequest.MergedDateTime = rawPullRequest["node"].Value <DateTime?>("mergedAt"); pullRequest.MergeCommitSha = rawPullRequest["node"]["mergeCommit"].HasValues ? rawPullRequest["node"]["mergeCommit"]["oid"].ToString() : null; pullRequest.PullRequestReviewers = rawPullRequest["node"]["reviews"]["nodes"].Children().Select(c => new PullRequestReviewer() { Login = c["author"].HasValues ? c["author"]["login"].Value <string>() : null, }).Distinct().ToArray(); pullRequest.PullRequestFiles = rawPullRequest["node"]["files"]["nodes"].Children().Select(c => new PullRequestFile() { Path = c.Value <string>("path"), Additions = c.Value <int>("additions"), Deletions = c.Value <int>("deletions"), }).ToArray(); response.AddPullRequestInfo(pullRequest); rawPullRequest = rawPullRequest.Next; } catch (Exception e) { // TODO } }
public BuildResultEntity( BoundBuildId buildId, DateTimeOffset buildDateTime, TimeSpan duration, string jobKind, string machineName, BuildResultClassification classification, PullRequestInfo prInfo) { JobName = buildId.JobId.Name; JobKind = jobKind; ViewName = AzureUtil.GetViewName(BuildId.JobId); BuildNumber = buildId.Number; HostRaw = buildId.Host.ToString(); ClassificationKindRaw = classification.Kind.ToString(); ClassificationName = classification.Name; BuildDateTime = buildDateTime.UtcDateTime; MachineName = machineName; IsPullRequest = JobUtil.IsPullRequestJobName(buildId.JobId); DurationSeconds = (int)duration.TotalSeconds; if (prInfo != null) { PullRequestId = prInfo.Id; PullRequestAuthor = prInfo.Author; PullRequestAuthorEmail = prInfo.AuthorEmail; PullRequestUrl = prInfo.PullUrl; PullRequestSha1 = prInfo.Sha1; Debug.Assert(HasPullRequestInfo); Debug.Assert(PullRequestInfo != null); } Debug.Assert(BuildDateTime.Kind == DateTimeKind.Utc); }
/// <summary> /// Update the table storage to contain the result of the specified build. /// </summary> private async Task <BuildResultEntity> GetBuildFailureEntity(BuildId id) { var buildInfo = await _client.GetBuildInfoAsync(id); var jobKind = await _client.GetJobKindAsync(id.JobId); PullRequestInfo prInfo = null; if (JobUtil.IsPullRequestJobName(id.JobId.Name)) { try { prInfo = await _client.GetPullRequestInfoAsync(id); } catch (Exception ex) { // TODO: Flow builds don't have the PR directly in the triggered jobs. Have to walk // back up to the parent job. For now swallow this error so we don't trigger false // positives in the error detection. _textWriter.WriteLine($"Error pulling PR info for {id}: {ex.Message}"); } } BuildResultClassification classification; switch (buildInfo.State) { case BuildState.Succeeded: classification = BuildResultClassification.Succeeded; break; case BuildState.Aborted: classification = BuildResultClassification.Aborted; break; case BuildState.Failed: classification = await PopulateFailedBuildResult(buildInfo, jobKind, prInfo); break; case BuildState.Running: classification = BuildResultClassification.Unknown; break; default: throw new Exception($"Invalid enum: {buildInfo.State} for {id.JobName} - {id.Number}"); } return(new BuildResultEntity( buildInfo.Id, buildInfo.Date, buildInfo.Duration, jobKind: jobKind, machineName: buildInfo.MachineName, classification: classification, prInfo: prInfo)); }
public static PullRequest ToPullRequest(this PullRequestInfo pullRequestInfo, long subscriptionId) { return(new PullRequest() { Number = pullRequestInfo.Number, PullRequestAnalyzeStatus = pullRequestInfo.IsMegaPR() ? PullRequestAnalyzeStatus.NotAnalyzedMegaPR : PullRequestAnalyzeStatus.NotAnalyzed, SubscriptionId = subscriptionId, PullRequestInfo = pullRequestInfo, NumberOfFiles = pullRequestInfo.TotalPullRequestFiles }); }
public async Task CreatePullRequest(ICreatePullRequestInfo createPullRequestInfo) { var commitRequest = new CommitInfo { Comment = $"Updating package {createPullRequestInfo.PackageId} to v{createPullRequestInfo.UpdatedVersion}", Content = createPullRequestInfo.Content, FileRelativePath = createPullRequestInfo.Path }; var newBranch = await _azureDevOpsClient.CreateCommitAsync(commitRequest); var request = new PullRequestInfo { Description = "Automatic updates from updater.", Title = $"Updating package {createPullRequestInfo.PackageId} to v{createPullRequestInfo.UpdatedVersion}", SourceBranch = newBranch }; await _azureDevOpsClient.CreatePullRequestAsync(request); }
public void PullRequestInfo() { var buildId = Create("example.com", 42, JobId.ParseName("hello")); var buildDate = DateTimeOffset.UtcNow; var prInfo = new PullRequestInfo("bob", "dog", 42, "cat", "tree"); var entity = new BuildResultEntity( buildId, buildDate, TimeSpan.FromSeconds(1), "kind", "test", BuildResultClassification.Succeeded, prInfo: prInfo); Assert.True(entity.HasPullRequestInfo); Assert.Equal(entity.PullRequestInfo.Author, prInfo.Author); Assert.Equal(entity.PullRequestInfo.AuthorEmail, prInfo.AuthorEmail); Assert.Equal(entity.PullRequestInfo.Id, prInfo.Id); Assert.Equal(entity.PullRequestInfo.PullUrl, prInfo.PullUrl); Assert.Equal(entity.PullRequestSha1, prInfo.Sha1); }
private void BtnCreateClick(object sender, EventArgs e) { var info = new PullRequestInfo { Title = txtTitle.Text, Description = txtDescription.Text, SourceBranch = txtSourceBranch.Text, TargetBranch = txtTargetBranch.Text, SourceRepo = (Repository) ddlRepositorySource.SelectedValue, TargetRepo = (Repository) ddlRepositoryTarget.SelectedValue, Reviewers = _reviewers }; var pullRequest = new CreatePullRequestRequest(_settings, info); var response = pullRequest.Send(); if (response.Success) MessageBox.Show("Success"); else MessageBox.Show(string.Join(Environment.NewLine, response.Messages), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
public BuildFailureEntity(BoundBuildId buildId, string identifier, DateTimeOffset buildDate, BuildFailureKind kind, string jobKind, string machineName, PullRequestInfo prInfo) { JobName = buildId.JobName; JobKind = jobKind; ViewName = AzureUtil.GetViewName(buildId.JobId); BuildNumber = buildId.Number; HostRaw = buildId.Host.ToString(); Identifier = identifier; BuildFailureKindRaw = kind.ToString(); BuildDateTime = buildDate.UtcDateTime; IsPullRequest = JobUtil.IsPullRequestJobName(buildId.JobId); MachineName = machineName; if (prInfo != null) { PullRequestId = prInfo.Id; PullRequestAuthor = prInfo.Author; PullRequestAuthorEmail = prInfo.AuthorEmail; PullRequestUrl = prInfo.PullUrl; PullRequestSha1 = prInfo.Sha1; Debug.Assert(HasPullRequestInfo); Debug.Assert(PullRequestInfo != null); } }
private GetPullRequestQueryResponse ParseGetPullRequestQueryResponse(JsonTextReader reader) { var response = new GetPullRequestQueryResponse(); var serializer = new JsonSerializer(); var rawPullRequest = serializer.Deserialize <JObject>(reader)["data"]["repository"]["pullRequest"]; try { var pullRequest = new PullRequestInfo(); pullRequest.TotalPullRequestFiles = rawPullRequest["files"]["totalCount"].Value <int>(); pullRequest.SubmitterLogin = rawPullRequest["author"].HasValues ? rawPullRequest["author"]["login"].ToString() : null; pullRequest.MergedDateTime = rawPullRequest.Value <DateTime?>("mergedAt"); pullRequest.MergeCommitSha = rawPullRequest["mergeCommit"].HasValues ? rawPullRequest["mergeCommit"]["oid"].ToString():null; pullRequest.Number = rawPullRequest.Value <int>("number"); pullRequest.PullRequestReviewers = rawPullRequest["reviews"]["nodes"].Children().Select(c => new PullRequestReviewer() { Login = c["author"].HasValues ? c["author"]["login"].Value <string>() : null, }).Distinct().ToArray(); pullRequest.PullRequestFiles = rawPullRequest["files"]["nodes"].Children().Select(c => new PullRequestFile() { Path = c.Value <string>("path"), Additions = c.Value <int>("additions"), Deletions = c.Value <int>("deletions"), }).ToArray(); response.PullRequestInfo = pullRequest; return(response); } catch (Exception e) { throw; } }
private async Task <BuildResultClassification> PopulateFailedBuildResult(BuildInfo buildInfo, string jobKind, PullRequestInfo prInfo) { var buildId = buildInfo.Id; BuildResult buildResult; try { buildResult = await _client.GetBuildResultAsync(buildInfo); } catch (Exception ex) { WriteLine(buildId, $"error getting build result {ex.Message}"); throw; } if (buildResult.FailureInfo == null) { return(BuildResultClassification.Unknown); } var classification = BuildResultClassification.Unknown; foreach (var cause in buildResult.FailureInfo.CauseList) { var current = ConvertToClassification(cause); if (classification.Kind == ClassificationKind.Unknown || classification.Kind == ClassificationKind.MergeConflict) { classification = current; } } return(classification); }
private async Task<BuildResultClassification> PopulateFailedBuildResult(BuildInfo buildInfo, string jobKind, PullRequestInfo prInfo) { var buildId = buildInfo.Id; BuildResult buildResult; try { buildResult = await _client.GetBuildResultAsync(buildInfo); } catch (Exception ex) { WriteLine(buildId, $"error getting build result {ex.Message}"); throw; } if (buildResult.FailureInfo == null) { return BuildResultClassification.Unknown; } var classification = BuildResultClassification.Unknown; foreach (var cause in buildResult.FailureInfo.CauseList) { var current = ConvertToClassification(cause); if (classification.Kind == ClassificationKind.Unknown || classification.Kind == ClassificationKind.MergeConflict) { classification = current; } } return classification; }
internal static bool TryParsePullRequestInfo(JArray actions, out PullRequestInfo info) { var container = actions.FirstOrDefault(x => x["parameters"] != null); if (container == null) { info = null; return false; } string sha1 = null; string pullLink = null; int? pullId = null; string pullAuthor = null; string pullAuthorEmail = null; string commitAuthorEmail = null; var parameters = (JArray)container["parameters"]; foreach (var pair in parameters) { switch (pair.Value<string>("name")) { case "ghprbActualCommit": sha1 = pair.Value<string>("value") ?? sha1; break; case "ghprbPullId": pullId = pair.Value<int>("value"); break; case "ghprbPullAuthorLogin": pullAuthor = pair.Value<string>("value") ?? pullAuthor; break; case "ghprbPullAuthorEmail": pullAuthorEmail = pair.Value<string>("value") ?? pullAuthorEmail; break; case "ghprbActualCommitAuthorEmail": commitAuthorEmail = pair.Value<string>("value") ?? commitAuthorEmail; break; case "ghprbPullLink": pullLink = pair.Value<string>("value") ?? pullLink; break; default: break; } } // It's possible for the pull email to be blank if the Github settings for the user // account hides their public email address. In that case fall back to the commit // author. It's generally the same value and serves as a nice backup identifier. if (string.IsNullOrEmpty(pullAuthorEmail)) { pullAuthorEmail = commitAuthorEmail; } if (sha1 == null || pullLink == null || pullId == null || pullAuthorEmail == null) { info = null; return false; } info = new PullRequestInfo( author: pullAuthor, authorEmail: pullAuthorEmail, id: pullId.Value, pullUrl: pullLink, sha1: sha1); return true; }
public void AddPullRequestInfo(PullRequestInfo pullRequestInfo) { _pullRequests.Add(pullRequestInfo); }
private async Task <List <BuildFailureEntity> > GetUnitTestFailures(BuildInfo buildInfo, string jobKind, PullRequestInfo prInfo) { // TODO: Resolve this with CoreCLR. They are producing way too many failures at the moment though // and we need to stop uploading 50,000 rows a day until we can resolve this. if (buildInfo.Id.JobName.Contains("dotnet_coreclr")) { return(new List <BuildFailureEntity>(capacity: 0)); } var buildId = buildInfo.Id; var testCaseNames = await _client.GetFailedTestCasesAsync(buildInfo.BuildId); // Ignore obnoxious long test names. This is a temporary work around due to CoreFX generating giantic test // names and log files. // https://github.com/dotnet/corefx/pull/11905 if (testCaseNames.Any(x => x.Length > 10000)) { return(new List <BuildFailureEntity>(capacity: 0)); } var entityList = testCaseNames .Select(x => BuildFailureEntity.CreateTestCaseFailure(buildInfo.Date, buildId, x, jobKind: jobKind, machineName: buildInfo.MachineName, prInfo: prInfo)) .ToList(); EnsureTestCaseNamesUnique(entityList); return(entityList); }
private async Task PopulateUnitTestFailure(BuildInfo buildInfo, string jobKind, PullRequestInfo prInfo) { // TODO: Resolve this with CoreCLR. They are producing way too many failures at the moment though // and we need to stop uploading 50,000 rows a day until we can resolve this. if (buildInfo.Id.JobName.Contains("dotnet_coreclr")) { return; } var buildId = buildInfo.Id; var testCaseNames = _client.GetFailedTestCases(buildId); var entityList = testCaseNames .Select(x => BuildFailureEntity.CreateTestCaseFailure(buildInfo.Date, buildId, x, jobKind: jobKind, machineName: buildInfo.MachineName, prInfo: prInfo)) .ToList(); EnsureTestCaseNamesUnique(entityList); await AzureUtil.InsertBatchUnordered(_buildFailureExactTable, entityList.Select(x => x.CopyExact())); await AzureUtil.InsertBatchUnordered(_buildFailureDateTable, entityList.Select(x => x.CopyDate())); }
public static BuildFailureEntity CreateTestCaseFailure(DateTimeOffset buildDateTime, BuildId buildId, string testCaseName, string jobKind, string machineName, PullRequestInfo prInfo) { return(new BuildFailureEntity( buildId, testCaseName, buildDateTime, BuildFailureKind.TestCase, jobKind: jobKind, machineName: machineName, prInfo: prInfo)); }
private async Task<List<BuildFailureEntity>> GetUnitTestFailures(BuildInfo buildInfo, string jobKind, PullRequestInfo prInfo) { // TODO: Resolve this with CoreCLR. They are producing way too many failures at the moment though // and we need to stop uploading 50,000 rows a day until we can resolve this. if (buildInfo.Id.JobName.Contains("dotnet_coreclr")) { return new List<BuildFailureEntity>(capacity: 0); } var buildId = buildInfo.Id; var testCaseNames = await _client.GetFailedTestCasesAsync(buildInfo.BuildId); // Ignore obnoxious long test names. This is a temporary work around due to CoreFX generating giantic test // names and log files. // https://github.com/dotnet/corefx/pull/11905 if (testCaseNames.Any(x => x.Length > 10000)) { return new List<BuildFailureEntity>(capacity: 0); } var entityList = testCaseNames .Select(x => BuildFailureEntity.CreateTestCaseFailure(buildInfo.Date, buildId, x, jobKind: jobKind, machineName: buildInfo.MachineName, prInfo: prInfo)) .ToList(); EnsureTestCaseNamesUnique(entityList); return entityList; }
public BuildFailureEntity(BuildId buildId, string identifier, DateTimeOffset buildDate, BuildFailureKind kind, string jobKind, string machineName, PullRequestInfo prInfo) { JobName = buildId.JobName; JobKind = jobKind; ViewName = AzureUtil.GetViewName(buildId.JobId); BuildNumber = buildId.Number; Identifier = identifier; BuildFailureKindRaw = kind.ToString(); BuildDateTime = buildDate.UtcDateTime; IsPullRequest = JobUtil.IsPullRequestJobName(buildId.JobId); MachineName = machineName; if (prInfo != null) { PullRequestId = prInfo.Id; PullRequestAuthor = prInfo.Author; PullRequestAuthorEmail = prInfo.AuthorEmail; PullRequestUrl = prInfo.PullUrl; PullRequestSha1 = prInfo.Sha1; Debug.Assert(HasPullRequestInfo); Debug.Assert(PullRequestInfo != null); } }
private void BtnCreateClick(object sender, EventArgs e) { var info = new PullRequestInfo { Title = txtTitle.Text, Description = txtDescription.Text, SourceBranch = ddlBranchSource.SelectedValue.ToString(), TargetBranch = ddlBranchTarget.SelectedValue.ToString(), SourceRepo = (Repository)ddlRepositorySource.SelectedValue, TargetRepo = (Repository)ddlRepositoryTarget.SelectedValue, Reviewers = _reviewers }; var pullRequest = new CreatePullRequestRequest(_settings, info); var response = pullRequest.Send(); if (response.Success) { MessageBox.Show(_success.Text); StashViewPullRequestFormLoad(null, null); } else MessageBox.Show(string.Join(Environment.NewLine, response.Messages), _error.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); }
public static BuildFailureEntity CreateTestCaseFailure(DateTimeOffset buildDateTime, BoundBuildId buildId, string testCaseName, string jobKind, string machineName, PullRequestInfo prInfo) { return new BuildFailureEntity( buildId, testCaseName, buildDateTime, BuildFailureKind.TestCase, jobKind: jobKind, machineName: machineName, prInfo: prInfo); }