internal async Task UpdateReviewAsync(ClaimsPrincipal user, string id) { var review = await GetReviewAsync(user, id); foreach (var revision in review.Revisions) { foreach (var file in revision.Files) { if (!file.HasOriginal) { continue; } var fileOriginal = await _originalsRepository.GetOriginalAsync(file.ReviewFileId); var languageService = GetLanguageService(file.Language); var codeFile = await languageService.GetCodeFileAsync(file.Name, fileOriginal, review.RunAnalysis); await _codeFileRepository.UpsertCodeFileAsync(revision.RevisionId, file.ReviewFileId, codeFile); InitializeFromCodeFile(file, codeFile); } } await _reviewsRepository.UpsertReviewAsync(review); }
public async Task <string> GetApiDiffFromAutomaticReview(CodeFile codeFile, int prNumber, string originalFileName, MemoryStream memoryStream, PullRequestModel pullRequestModel) { // Get automatically generated master review for package or previously cloned review for this pull request var review = await GetBaseLineReview(codeFile.Language, codeFile.PackageName, pullRequestModel); if (review == null) { return(""); } // Check if API surface level matches with any revisions var renderedCodeFile = new RenderedCodeFile(codeFile); if (await IsReviewSame(review, renderedCodeFile)) { return(""); } if (pullRequestModel.ReviewId != null) { // If baseline review was already created and if APIs in current commit doesn't match any of the revisions in generated review then create new baseline using main branch and compare again. // If APIs are still different, find the diff against latest baseline. review = await GetBaseLineReview(codeFile.Language, codeFile.PackageName, pullRequestModel, true); review.ReviewId = pullRequestModel.ReviewId; if (await IsReviewSame(review, renderedCodeFile)) { return(""); } } var newRevision = new ReviewRevisionModel() { Author = review.Author, Label = "Created for PR " + prNumber }; var stringBuilder = new StringBuilder(); var diffUrl = REVIEW_DIFF_URL.Replace("{ReviewId}", review.ReviewId).Replace("{NewRevision}", review.Revisions.Last().RevisionId); stringBuilder.Append($"API changes have been detected in `{codeFile.PackageName}`. You can review API changes [here]({diffUrl})").Append(Environment.NewLine); // If review doesn't match with any revisions then generate formatted diff against last revision of automatic review await GetFormattedDiff(renderedCodeFile, review.Revisions.Last(), stringBuilder); var reviewCodeFileModel = await _reviewManager.CreateReviewCodeFileModel(newRevision.RevisionId, memoryStream, codeFile); reviewCodeFileModel.FileName = originalFileName; newRevision.Files.Add(reviewCodeFileModel); review.Revisions.Add(newRevision); pullRequestModel.ReviewId = review.ReviewId; review.FilterType = ReviewType.PullRequest; await _reviewsRepository.UpsertReviewAsync(review); await _pullRequestsRepository.UpsertPullRequestAsync(pullRequestModel); return(stringBuilder.ToString()); }
private async Task UpdateReviewAsync(ReviewModel review) { foreach (var revision in review.Revisions) { foreach (var file in revision.Files) { if (!file.HasOriginal) { continue; } var fileOriginal = await _originalsRepository.GetOriginalAsync(file.ReviewFileId); var languageService = GetLanguageService(file.Language); // file.Name property has been repurposed to store package name and version string // This is causing issue when updating review using latest parser since it expects Name field as file name // We have added a new property FileName which is only set for new reviews // All older reviews needs to be handled by checking Name field // If name field has no extension and File Name is Emtpy then use review.Name var fileName = file.FileName ?? (Path.HasExtension(file.Name)? file.Name : review.Name); var codeFile = await languageService.GetCodeFileAsync(fileName, fileOriginal, review.RunAnalysis); await _codeFileRepository.UpsertCodeFileAsync(revision.RevisionId, file.ReviewFileId, codeFile); InitializeFromCodeFile(file, codeFile); file.FileName = fileName; } } await _reviewsRepository.UpsertReviewAsync(review); }
public async Task <ReviewModel> CreateReviewAsync(ClaimsPrincipal user, string originalName, Stream fileStream, bool runAnalysis) { ReviewModel review = new ReviewModel(); review.Author = user.GetGitHubLogin(); review.CreationDate = DateTime.UtcNow; review.RunAnalysis = runAnalysis; var revision = new ReviewRevisionModel(); var reviewCodeFileModel = await CreateFileAsync(revision.RevisionId, originalName, fileStream, runAnalysis); revision.Files.Add(reviewCodeFileModel); review.Name = reviewCodeFileModel.Name; review.Revisions.Add(revision); UpdateRevisionNames(review); await _reviewsRepository.UpsertReviewAsync(review); return(review); }
private async Task UpdateReviewAsync(ReviewModel review) { foreach (var revision in review.Revisions.Reverse()) { foreach (var file in revision.Files) { if (!file.HasOriginal) { continue; } try { var fileOriginal = await _originalsRepository.GetOriginalAsync(file.ReviewFileId); var languageService = GetLanguageService(file.Language); // file.Name property has been repurposed to store package name and version string // This is causing issue when updating review using latest parser since it expects Name field as file name // We have added a new property FileName which is only set for new reviews // All older reviews needs to be handled by checking review name field var fileName = file.FileName ?? (Path.HasExtension(review.Name) ? review.Name : file.Name); var codeFile = await languageService.GetCodeFileAsync(fileName, fileOriginal, review.RunAnalysis); await _codeFileRepository.UpsertCodeFileAsync(revision.RevisionId, file.ReviewFileId, codeFile); // update only version string file.VersionString = codeFile.VersionString; } catch (Exception ex) { _telemetryClient.TrackTrace("Failed to update review " + review.ReviewId); _telemetryClient.TrackException(ex); } } } await _reviewsRepository.UpsertReviewAsync(review); }
private async Task CreateTestDataIfNotExistAsync() { var dataBaseResponse = await _cosmosClient.CreateDatabaseIfNotExistsAsync("APIView"); var containerResponse = await dataBaseResponse.Database.CreateContainerIfNotExistsAsync("Reviews", "/id"); if (containerResponse.StatusCode.Equals(HttpStatusCode.Created)) { foreach (int value in Enumerable.Range(1, 2)) { string[] languages = new String[] { "TestLanguageOne", "TestLanguageTwo" }; foreach (string language in languages) { ReviewType[] reviewTypes = new ReviewType[] { ReviewType.Manual, ReviewType.Automatic, ReviewType.PullRequest, ReviewType.All }; foreach (ReviewType reviewType in reviewTypes) { bool[] boolvalues = new bool[] { true, false }; foreach (var boolValue in boolvalues) { foreach (var boolVal in boolvalues) { var container = containerResponse.Container; ReviewModel review = new ReviewModel { Name = $"TestReview{value}_For_{language}_For_{reviewType.ToString()}_For{boolValue}_For{boolVal}", Author = $"TestReviewAuthor{value}", CreationDate = DateTime.Now, IsClosed = boolValue, FilterType = reviewType, ServiceName = $"TestServiceName{value}", PackageDisplayName = $"TestPackageDisplayName{value}" }; var revisions = new ReviewRevisionModelList(review); foreach (int val in Enumerable.Range(1, 2)) { var revision = new ReviewRevisionModel { Name = $"TestRevision{value}_{val}", }; if (boolVal) { revision.Approvers.Add($"TestApprover{value}_{val}"); } foreach (int v in Enumerable.Range(1, 2)) { var file = new ReviewCodeFileModel { Name = $"TestFile{value}_{val}_{v}", Language = language }; revision.Files.Add(file); } revisions.Add(revision); } review.Revisions = revisions; await _cosmosReviewRepository.UpsertReviewAsync(review); } } } } } } }
private async Task CreateRevisionIfRequired(CodeFile codeFile, int prNumber, string originalFileName, MemoryStream memoryStream, PullRequestModel pullRequestModel, CodeFile baselineCodeFile, MemoryStream baseLineStream, string baselineFileName) { var newRevision = new ReviewRevisionModel() { Author = pullRequestModel.Author, Label = $"Created for PR {prNumber}" }; // Get automatically generated master review for package or previously cloned review for this pull request var review = await GetBaseLineReview(codeFile.Language, codeFile.PackageName, pullRequestModel); if (review == null) { // If base line is not available (possible if package is new or request coming from SDK automation) review = CreateNewReview(pullRequestModel); // If request passes code file for baseline if (baselineCodeFile != null) { var baseline = await CreateBaselineRevision(baselineCodeFile, baseLineStream, pullRequestModel, baselineFileName); review.Revisions.Add(baseline); } } else { // Check if API surface level matches with any revisions var renderedCodeFile = new RenderedCodeFile(codeFile); if (await IsReviewSame(review, renderedCodeFile)) { return; } if (pullRequestModel.ReviewId != null) { //Refresh baseline using latest from automatic review var prevRevisionId = review.Revisions.Last().RevisionId; review = await GetBaseLineReview(codeFile.Language, codeFile.PackageName, pullRequestModel, true); review.ReviewId = pullRequestModel.ReviewId; newRevision.RevisionId = prevRevisionId; } } var reviewCodeFileModel = await _reviewManager.CreateReviewCodeFileModel(newRevision.RevisionId, memoryStream, codeFile); reviewCodeFileModel.FileName = originalFileName; newRevision.Files.Add(reviewCodeFileModel); review.Revisions.Add(newRevision); pullRequestModel.ReviewId = review.ReviewId; review.FilterType = ReviewType.PullRequest; await _reviewsRepository.UpsertReviewAsync(review); await _pullRequestsRepository.UpsertPullRequestAsync(pullRequestModel); }