diff --git a/src/dotnet/APIView/APIViewWeb/Controllers/AutoReviewController.cs b/src/dotnet/APIView/APIViewWeb/Controllers/AutoReviewController.cs index dd2e0a67caa..5feea82b20b 100644 --- a/src/dotnet/APIView/APIViewWeb/Controllers/AutoReviewController.cs +++ b/src/dotnet/APIView/APIViewWeb/Controllers/AutoReviewController.cs @@ -58,22 +58,38 @@ public async Task UploadAutoReview([FromForm] IFormFile file, stri return StatusCode(statusCode: StatusCodes.Status500InternalServerError); } - public async Task GetReviewStatus(string language, string packageName, string reviewId = null, bool? firstReleaseStatusOnly = null) + public async Task GetReviewStatus(string language, string packageName, string reviewId = null, bool? firstReleaseStatusOnly = null, string packageVersion = null) { - // This API is used by prepare release script to check if API review for a package is approved or not. - // This caller script doesn't have artifact to submit and so it can't check using create review API - // So it rely on approval status of latest revision of automatic review for the package - // With new restriction of creating automatic review only from master branch or GA version, this should ensure latest revision - // is infact the version intended to be released. + // This API is used to get approval status of an API review revision. If a package version is passed then it will try to find a revision with exact package version match or revisions with same major and minor version. + // If there is no matching revisions then it will return latest automatic revision details. + // This is used by prepare release script and build pipeline to verify approval status. ReviewListItemModel review = await _reviewManager.GetReviewAsync(packageName: packageName, language: language, isClosed: null); if (review != null) { - APIRevisionListItemModel latestAutomaticApiRevisions = await _apiRevisionsManager.GetLatestAPIRevisionsAsync(reviewId: review.Id, apiRevisionType: APIRevisionType.Automatic); + APIRevisionListItemModel apiRevision = null; + if (!string.IsNullOrEmpty(packageVersion)) + { + var apiRevisions = await _apiRevisionsManager.GetAPIRevisionsAsync(reviewId: review.Id, packageVersion: packageVersion, apiRevisionType: APIRevisionType.Automatic); + if (apiRevisions.Any()) + apiRevision = apiRevisions.FirstOrDefault(); + } + + if (apiRevision == null) + { + apiRevision = await _apiRevisionsManager.GetLatestAPIRevisionsAsync(reviewId: review.Id, apiRevisionType: APIRevisionType.Automatic); + } + + + if(apiRevision == null) + { + return StatusCode(StatusCodes.Status404NotFound, "Review is not found for package " + packageName); + } + // Return 200 OK for approved review and 201 for review in pending status - if (firstReleaseStatusOnly != true && latestAutomaticApiRevisions != null && latestAutomaticApiRevisions.IsApproved) + if (firstReleaseStatusOnly != true && apiRevision != null && apiRevision.IsApproved) { return Ok(); } @@ -87,7 +103,7 @@ public async Task GetReviewStatus(string language, string packageN return StatusCode(statusCode: StatusCodes.Status202Accepted); } } - throw new Exception("Review is not found for package " + packageName); + return StatusCode(StatusCodes.Status404NotFound, "Review is not found for package " + packageName); } [HttpGet] diff --git a/src/dotnet/APIView/APIViewWeb/Managers/APIRevisionsManager.cs b/src/dotnet/APIView/APIViewWeb/Managers/APIRevisionsManager.cs index 8ce9e413490..a9b45e91e03 100644 --- a/src/dotnet/APIView/APIViewWeb/Managers/APIRevisionsManager.cs +++ b/src/dotnet/APIView/APIViewWeb/Managers/APIRevisionsManager.cs @@ -77,10 +77,37 @@ public async Task> GetAPIRevisionsAsync(Page /// Retrieve Revisions for a particular Review from the Revisions container in CosmosDb /// /// The Reviewid for which the revisions are to be retrieved + /// Optional package version param to return a matching revision for the package version + /// optional API revision type filter /// - public async Task> GetAPIRevisionsAsync(string reviewId) + public async Task> GetAPIRevisionsAsync(string reviewId, string packageVersion = "", APIRevisionType apiRevisionType = APIRevisionType.All) { - return await _apiRevisionsRepository.GetAPIRevisionsAsync(reviewId); + var apiRevisions = await _apiRevisionsRepository.GetAPIRevisionsAsync(reviewId); + + if (apiRevisionType != APIRevisionType.All) + apiRevisions = apiRevisions.Where(r => r.APIRevisionType == apiRevisionType); + + if (!string.IsNullOrEmpty(packageVersion)) + { + // Check for exact same package version + // If exact version is not found in revision then search for same major and minor version and return the latest. + var exactMatchRevisions = apiRevisions.Where(r => packageVersion.Equals(r.Files[0].PackageVersion)); + if (exactMatchRevisions.Any()) + { + return exactMatchRevisions.OrderByDescending(r => r.CreatedOn); + } + + // Check for revisions with matching + var versionGroups = packageVersion.Split('.'); + var majorMinor = $"{versionGroups[0]}.{versionGroups[1]}."; + var majorMinorMatchRevisions = apiRevisions.Where(r => !string.IsNullOrEmpty(r.Files[0].PackageVersion) && r.Files[0].PackageVersion.StartsWith(majorMinor)); + if (majorMinorMatchRevisions.Any()) + { + return majorMinorMatchRevisions.OrderByDescending(r => r.CreatedOn); + } + return majorMinorMatchRevisions; + } + return apiRevisions; } /// @@ -829,6 +856,7 @@ private async Task GenerateAPIRevisionInExternalResource(ReviewListItemModel rev return result; } + public async Task UpdateRevisionMetadataAsync(APIRevisionListItemModel revision, string packageVersion, string label) { if (packageVersion != null && !packageVersion.Equals(revision.Files[0].PackageVersion)) diff --git a/src/dotnet/APIView/APIViewWeb/Managers/Interfaces/IAPIRevisionsManager.cs b/src/dotnet/APIView/APIViewWeb/Managers/Interfaces/IAPIRevisionsManager.cs index c61a423d2b0..abb25f5acc7 100644 --- a/src/dotnet/APIView/APIViewWeb/Managers/Interfaces/IAPIRevisionsManager.cs +++ b/src/dotnet/APIView/APIViewWeb/Managers/Interfaces/IAPIRevisionsManager.cs @@ -15,7 +15,7 @@ namespace APIViewWeb.Managers.Interfaces public interface IAPIRevisionsManager { public Task> GetAPIRevisionsAsync(PageParams pageParams, APIRevisionsFilterAndSortParams filterAndSortParams); - public Task> GetAPIRevisionsAsync(string reviewId); + public Task> GetAPIRevisionsAsync(string reviewId, string packageVersion = "", APIRevisionType apiRevisionType = APIRevisionType.All); public Task GetLatestAPIRevisionsAsync(string reviewId = null, IEnumerable apiRevisions = null, APIRevisionType apiRevisionType = APIRevisionType.All); public Task GetAPIRevisionAsync(ClaimsPrincipal user, string apiRevisionId); public Task GetAPIRevisionAsync(string apiRevisionId);