eng/common/scripts/Detect-Api-Changes.ps1 (145 lines of code) (raw):
# cSpell:ignore PULLREQUEST
# cSpell:ignore TARGETBRANCH
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True)]
[string] $ArtifactPath,
[Parameter(Mandatory=$True)]
[string] $PullRequestNumber,
[Parameter(Mandatory=$True)]
[string] $BuildId,
[Parameter(Mandatory=$True)]
[string] $CommitSha,
[string] $APIViewUri,
[string] $RepoFullName = "",
[string] $ArtifactName = "packages",
[string] $TargetBranch = ("origin/${env:SYSTEM_PULLREQUEST_TARGETBRANCH}" -replace "refs/heads/"),
[string] $DevopsProject = "internal"
)
. (Join-Path $PSScriptRoot common.ps1)
$configFileDir = Join-Path -Path $ArtifactPath "PackageInfo"
# Submit API review request and return status whether current revision is approved or pending or failed to create review
function Submit-Request($filePath, $packageName)
{
$repoName = $RepoFullName
if (!$repoName) {
$repoName = "azure/azure-sdk-for-$LanguageShort"
}
$reviewFileName = "$($packageName)_$($LanguageShort).json"
$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)
$query.Add('packageName', $packageName)
$query.Add('language', $LanguageShort)
$query.Add('project', $DevopsProject)
$reviewFileFullName = Join-Path -Path $ArtifactPath $packageName $reviewFileName
# If CI generates token file then it passes both token file name and original file (filePath) to APIView
# If both files are passed then APIView downloads the parent directory as a zip
# If code file is not passed(for e.g. .NET or Java) then APIView needs full path to original file to download only that file.
if (Test-Path $reviewFileFullName)
{
$query.Add('codeFile', $reviewFileName)
# Pass only relative path in package artifact directory when code file is also present
$query.Add('filePath', (Split-Path -Leaf $filePath))
}
else
{
$query.Add('filePath', $filePath)
}
$uri = [System.UriBuilder]$APIViewUri
$uri.query = $query.toString()
LogInfo "Request URI: $($uri.Uri.OriginalString)"
try
{
$Response = Invoke-WebRequest -Method 'GET' -Uri $uri.Uri -MaximumRetryCount 3
$StatusCode = $Response.StatusCode
}
catch
{
LogError "Error $StatusCode - Exception details: $($_.Exception.Response)"
$StatusCode = $_.Exception.Response.StatusCode
}
return $StatusCode
}
function Should-Process-Package($pkgPath, $packageName)
{
$pkg = Split-Path -Leaf $pkgPath
$pkgPropPath = Join-Path -Path $configFileDir "$packageName.json"
if (!(Test-Path $pkgPropPath))
{
LogWarning "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
$packagePath = $pkgInfo.DirectoryPath
$modifiedFiles = @(Get-ChangedFiles -DiffPath "$packagePath/*" -DiffFilterType '')
$filteredFileCount = $modifiedFiles.Count
LogInfo "Number of modified files for package: $filteredFileCount"
return ($filteredFileCount -gt 0 -and $pkgInfo.IsNewSdk)
}
function Log-Input-Params()
{
LogGroupStart "Input Parameters for $($ArtifactName)"
LogInfo "Artifact Path: $($ArtifactPath)"
LogInfo "Artifact Name: $($ArtifactName)"
LogInfo "PullRequest Number: $($PullRequestNumber)"
LogInfo "BuildId: $($BuildId)"
LogInfo "Language: $($Language)"
LogInfo "Commit SHA: $($CommitSha)"
LogInfo "Repo Name: $($RepoFullName)"
LogInfo "Project: $($DevopsProject)"
LogGroupEnd
}
Log-Input-Params
if (!($FindArtifactForApiReviewFn -and (Test-Path "Function:$FindArtifactForApiReviewFn")))
{
LogError "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 = @{}
LogInfo "Processing PackageInfo at $configFileDir"
$packageProperties = Get-ChildItem -Recurse -Force "$configFileDir" `
| Where-Object {
$_.Extension -eq '.json' -and ($_.FullName.Substring($configFileDir.Length + 1) -notmatch '^_.*?[\\\/]')
}
foreach ($packagePropFile in $packageProperties)
{
$packageMetadata = Get-Content $packagePropFile | ConvertFrom-Json
$pkgArtifactName = $packageMetadata.ArtifactName ?? $packageMetadata.Name
LogInfo "Processing $($pkgArtifactName)"
$packages = &$FindArtifactForApiReviewFn $ArtifactPath $pkgArtifactName
if ($packages)
{
$pkgPath = $packages.Values[0]
$isRequired = Should-Process-Package -pkgPath $pkgPath -packageName $pkgArtifactName
LogInfo "Is API change detect required for $($pkgArtifactName):$($isRequired)"
if ($isRequired -eq $True)
{
$filePath = $pkgPath.Replace($ArtifactPath , "").Replace("\", "/")
$respCode = Submit-Request -filePath $filePath -packageName $pkgArtifactName
if ($respCode -ne '200')
{
$responses[$pkgArtifactName] = $respCode
}
}
else
{
LogInfo "Pull request does not have any change for $($pkgArtifactName)). Skipping API change detect."
}
}
else
{
LogInfo "No package is found in artifact path to find API changes for $($pkgArtifactName)"
}
}
foreach($pkg in $responses.keys)
{
LogInfo "API detection request status for $($pkg) : $($responses[$pkg])"
}