diff --git a/eng/common/pipelines/templates/steps/detect-api-changes.yml b/eng/common/pipelines/templates/steps/detect-api-changes.yml new file mode 100644 index 000000000000..de4dd5675417 --- /dev/null +++ b/eng/common/pipelines/templates/steps/detect-api-changes.yml @@ -0,0 +1,19 @@ +parameters: + ArtifactPath: $(Build.ArtifactStagingDirectory) + Artifacts: [] + +steps: + - task: Powershell@2 + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/scripts/Detect-Api-Changes.ps1 + arguments: > + -ArtifactList ('${{ convertToJson(parameters.Artifacts) }}' | ConvertFrom-Json | Select-Object Name) + -ArtifactPath ${{parameters.ArtifactPath}} + -CommitSha '$(Build.SourceVersion)' + -BuildId $(Build.BuildId) + -PullRequestNumber $(System.PullRequest.PullRequestNumber) + -RepoFullName $(Build.Repository.Name) + pwsh: true + workingDirectory: $(Pipeline.Workspace) + displayName: Detect API changes + condition: and(succeededOrFailed(), eq(variables['Build.Reason'],'PullRequest')) diff --git a/eng/common/scripts/Detect-Api-Changes.ps1 b/eng/common/scripts/Detect-Api-Changes.ps1 new file mode 100644 index 000000000000..375210171794 --- /dev/null +++ b/eng/common/scripts/Detect-Api-Changes.ps1 @@ -0,0 +1,119 @@ +[CmdletBinding()] +Param ( + [Parameter(Mandatory=$True)] + [string] $ArtifactPath, + [Parameter(Mandatory=$True)] + [string] $PullRequestNumber, + [Parameter(Mandatory=$True)] + [string] $BuildId, + [Parameter(Mandatory=$True)] + [string] $CommitSha, + [Parameter(Mandatory=$True)] + [array] $ArtifactList, + [string] $RepoFullName = "", + [string] $ArtifactName = "packages", + [string] $APIViewUri = "https://apiview.dev/PullRequest/DetectApiChanges" +) + +# Submit API review request and return status whether current revision is approved or pending or failed to create review +function Submit-Request($filePath) +{ + $repoName = $RepoFullName + if (!$repoName) { + $repoName = "azure/azure-sdk-for-$LanguageShort" + } + $query = [System.Web.HttpUtility]::ParseQueryString('') + $query.Add('artifactName', $ArtifactName) + $query.Add('buildId', $BuildId) + $query.Add('filePath', $filePath) + $query.Add('commitSha', $CommitSha) + $query.Add('repoName', $repoName) + $query.Add('pullRequestNumber', $PullRequestNumber) + $uri = [System.UriBuilder]$APIViewUri + $uri.query = $query.toString() + Write-Host "Request URI: $($uri.Uri.OriginalString)" + try + { + $Response = Invoke-WebRequest -Method 'GET' -Uri $uri.Uri -MaximumRetryCount 3 + $StatusCode = $Response.StatusCode + } + catch + { + Write-Host "Error $StatusCode - Exception details: $($_.Exception.Response)" + $StatusCode = $_.Exception.Response.StatusCode + } + + return $StatusCode +} + +function Should-Process-Package($pkgPath, $packageName) +{ + $pkg = Split-Path -Leaf $pkgPath + $configFileDir = Join-Path -Path $ArtifactPath "PackageInfo" + $pkgPropPath = Join-Path -Path $configFileDir "$packageName.json" + if (!(Test-Path $pkgPropPath)) + { + Write-Host " Package property file path $($pkgPropPath) is invalid." + return $False + } + # Get package info from json file created before updating version to daily dev + $pkgInfo = Get-Content $pkgPropPath | ConvertFrom-Json + Write-Host "SDK Type: $($pkgInfo.SdkType)" + return ($pkgInfo.SdkType -eq "client" -and $pkgInfo.IsNewSdk) +} + +function Log-Input-Params() +{ + Write-Host "Artifact Path: $($ArtifactPath)" + Write-Host "Artifact Name: $($ArtifactName)" + Write-Host "PullRequest Number: $($PullRequestNumber)" + Write-Host "BuildId: $($BuildId)" + Write-Host "Language: $($Language)" + Write-Host "Commit SHA: $($CommitSha)" + Write-Host "Repo Name: $($RepoFullName)" +} + +. (Join-Path $PSScriptRoot common.ps1) +Log-Input-Params + +if (!($FindArtifactForApiReviewFn -and (Test-Path "Function:$FindArtifactForApiReviewFn"))) +{ + Write-Host "The function for 'FindArtifactForApiReviewFn' was not found.` + Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.` + See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure" + exit 1 +} + +$responses = @{} +foreach ($artifact in $ArtifactList) +{ + Write-Host "Processing $($artifact.name)" + $packages = &$FindArtifactForApiReviewFn $ArtifactPath $artifact.name + if ($packages) + { + $pkgPath = $packages.Values[0] + if (Should-Process-Package -pkgPath $pkgPath -packageName $artifact.name) + { + $filePath = $pkgPath.Replace($ArtifactPath , "").Replace("\", "/") + $respCode = Submit-Request -filePath $filePath + if ($respCode -ne '200') + { + $responses[$artifact.name] = $respCode + } + } + } + else + { + Write-Host "No package is found in artifact path to find API changes for $($artifact.name)" + } +} + +if ($responses) +{ + # Will update this with a link to wiki on how to resolve + Write-Warning "API change detection failed for following packages. Please check above for package level error details." + foreach($pkg in $responses.keys) + { + Write-Host "$pkg failed with $($responses[$pkg]) code" + } +}