Skip to content

Commit e26ca03

Browse files
azure-sdkraych1
andauthored
Sync eng/common directory with azure-sdk-tools for PR 12467 (Azure#3191)
Sync eng/common directory with azure-sdk-tools for PR Azure/azure-sdk-tools#12467 See [eng/common workflow](https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/README.md#workflow) --------- Co-authored-by: ray chen <[email protected]>
1 parent 24b5ec1 commit e26ca03

File tree

3 files changed

+155
-80
lines changed

3 files changed

+155
-80
lines changed

eng/common/pipelines/templates/steps/create-apireview.yml

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,47 @@
11
parameters:
2-
ArtifactPath: $(Build.ArtifactStagingDirectory)
3-
Artifacts: []
4-
ConfigFileDir: $(Build.ArtifactStagingDirectory)/PackageInfo
5-
MarkPackageAsShipped: false
6-
GenerateApiReviewForManualOnly: false
7-
ArtifactName: 'packages'
8-
PackageName: ''
9-
SourceRootPath: $(Build.SourcesDirectory)
2+
- name: ArtifactPath
3+
type: string
4+
default: $(Build.ArtifactStagingDirectory)
5+
- name: Artifacts
6+
type: object
7+
default: []
8+
- name: ConfigFileDir
9+
type: string
10+
default: $(Build.ArtifactStagingDirectory)/PackageInfo
11+
- name: MarkPackageAsShipped
12+
type: boolean
13+
default: false
14+
- name: GenerateApiReviewForManualOnly
15+
type: boolean
16+
default: false
17+
- name: ArtifactName
18+
type: string
19+
default: 'packages'
20+
- name: PackageName
21+
type: string
22+
default: ''
23+
- name: SourceRootPath
24+
type: string
25+
default: $(Build.SourcesDirectory)
26+
- name: PackageInfoFiles
27+
type: object
28+
default: []
1029

1130
steps:
12-
# ideally this should be done as initial step of a job in caller template
13-
# We can remove this step later once it is added in caller
14-
- template: /eng/common/pipelines/templates/steps/set-default-branch.yml
15-
parameters:
16-
WorkingDirectory: ${{ parameters.SourceRootPath }}
17-
1831
# Automatic API review is generated for a package when pipeline runs irrespective of how pipeline gets triggered.
19-
# Below condition ensures that API review is generated only for manual pipeline runs when flag GenerateApiReviewForManualOnly is set to true.
32+
# Below condition ensures that API review is generated only for manual pipeline runs when flag GenerateApiReviewForManualOnly is set to true.
2033
- ${{ if or(ne(parameters.GenerateApiReviewForManualOnly, true), eq(variables['Build.Reason'], 'Manual')) }}:
34+
# ideally this should be done as initial step of a job in caller template
35+
# We can remove this step later once it is added in caller
36+
- template: /eng/common/pipelines/templates/steps/set-default-branch.yml
37+
parameters:
38+
WorkingDirectory: ${{ parameters.SourceRootPath }}
39+
2140
- task: Powershell@2
2241
inputs:
2342
filePath: ${{ parameters.SourceRootPath }}/eng/common/scripts/Create-APIReview.ps1
2443
arguments: >
44+
-PackageInfoFiles ('${{ convertToJson(parameters.PackageInfoFiles) }}' | ConvertFrom-Json -NoEnumerate)
2545
-ArtifactList ('${{ convertToJson(parameters.Artifacts) }}' | ConvertFrom-Json | Select-Object Name)
2646
-ArtifactPath '${{parameters.ArtifactPath}}'
2747
-ArtifactName ${{ parameters.ArtifactName }}
@@ -31,7 +51,7 @@ steps:
3151
-DefaultBranch '$(DefaultBranch)'
3252
-ConfigFileDir '${{parameters.ConfigFileDir}}'
3353
-BuildId '$(Build.BuildId)'
34-
-RepoName '$(Build.Repository.Name)'
54+
-RepoName '$(Build.Repository.Name)'
3555
-MarkPackageAsShipped $${{parameters.MarkPackageAsShipped}}
3656
pwsh: true
3757
displayName: Create API Review

eng/common/scripts/Create-APIReview.ps1

Lines changed: 116 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[CmdletBinding()]
22
Param (
3-
[Parameter(Mandatory=$True)]
3+
[Parameter(Mandatory=$False)]
44
[array] $ArtifactList,
55
[Parameter(Mandatory=$True)]
6-
[string] $ArtifactPath,
6+
[string] $ArtifactPath,
77
[Parameter(Mandatory=$True)]
8-
[string] $APIKey,
8+
[string] $APIKey,
99
[string] $SourceBranch,
1010
[string] $DefaultBranch,
1111
[string] $RepoName,
@@ -14,7 +14,9 @@ Param (
1414
[string] $ConfigFileDir = "",
1515
[string] $APIViewUri = "https://apiview.dev/AutoReview",
1616
[string] $ArtifactName = "packages",
17-
[bool] $MarkPackageAsShipped = $false
17+
[bool] $MarkPackageAsShipped = $false,
18+
[Parameter(Mandatory=$False)]
19+
[array] $PackageInfoFiles
1820
)
1921

2022
Set-StrictMode -Version 3
@@ -51,7 +53,7 @@ function Upload-SourceArtifact($filePath, $apiLabel, $releaseStatus, $packageVer
5153
$versionContent.Headers.ContentDisposition = $versionParam
5254
$multipartContent.Add($versionContent)
5355
Write-Host "Request param, packageVersion: $packageVersion"
54-
56+
5557
$releaseTagParam = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
5658
$releaseTagParam.Name = "setReleaseTag"
5759
$releaseTagParamContent = [System.Net.Http.StringContent]::new($MarkPackageAsShipped)
@@ -96,7 +98,7 @@ function Upload-ReviewTokenFile($packageName, $apiLabel, $releaseStatus, $review
9698
$fileName = Split-Path -Leaf $filePath
9799
Write-Host "OriginalFile name: $fileName"
98100

99-
$params = "buildId=${BuildId}&artifactName=${ArtifactName}&originalFilePath=${fileName}&reviewFilePath=${reviewFileName}"
101+
$params = "buildId=${BuildId}&artifactName=${ArtifactName}&originalFilePath=${fileName}&reviewFilePath=${reviewFileName}"
100102
$params += "&label=${apiLabel}&repoName=${RepoName}&packageName=${packageName}&project=internal&packageVersion=${packageVersion}"
101103
if($MarkPackageAsShipped) {
102104
$params += "&setReleaseTag=true"
@@ -141,17 +143,16 @@ function Get-APITokenFileName($packageName)
141143
}
142144
}
143145

144-
function Submit-APIReview($packageInfo, $packagePath, $packageArtifactName)
146+
function Submit-APIReview($packageInfo, $packagePath)
145147
{
146-
$packageName = $packageInfo.Name
147148
$apiLabel = "Source Branch:${SourceBranch}"
148149

149150
# Get generated review token file if present
150151
# APIView processes request using different API if token file is already generated
151-
$reviewTokenFileName = Get-APITokenFileName $packageArtifactName
152+
$reviewTokenFileName = Get-APITokenFileName $packageInfo.ArtifactName
152153
if ($reviewTokenFileName) {
153154
Write-Host "Uploading review token file $reviewTokenFileName to APIView."
154-
return Upload-ReviewTokenFile $packageArtifactName $apiLabel $packageInfo.ReleaseStatus $reviewTokenFileName $packageInfo.Version $packagePath
155+
return Upload-ReviewTokenFile $packageInfo.ArtifactName $apiLabel $packageInfo.ReleaseStatus $reviewTokenFileName $packageInfo.Version $packagePath
155156
}
156157
else {
157158
Write-Host "Uploading $packagePath to APIView."
@@ -172,12 +173,32 @@ function IsApiviewStatusCheckRequired($packageInfo)
172173
return $false
173174
}
174175

175-
function ProcessPackage($packageName)
176+
function ProcessPackage($packageInfo)
176177
{
177178
$packages = @{}
178179
if ($FindArtifactForApiReviewFn -and (Test-Path "Function:$FindArtifactForApiReviewFn"))
179180
{
180-
$packages = &$FindArtifactForApiReviewFn $ArtifactPath $packageName
181+
$pkgArtifactName = $packageInfo.ArtifactName ?? $packageInfo.Name
182+
183+
# Check if the function supports the packageInfo parameter
184+
$functionInfo = Get-Command $FindArtifactForApiReviewFn -ErrorAction SilentlyContinue
185+
$supportsPackageInfoParam = $false
186+
187+
if ($functionInfo -and $functionInfo.Parameters) {
188+
# Check if function specifically supports packageInfo parameter
189+
$parameterNames = $functionInfo.Parameters.Keys
190+
$supportsPackageInfoParam = $parameterNames -contains 'packageInfo'
191+
}
192+
193+
# Call function with appropriate parameters
194+
if ($supportsPackageInfoParam) {
195+
LogInfo "Calling $FindArtifactForApiReviewFn with packageInfo parameter"
196+
$packages = &$FindArtifactForApiReviewFn $ArtifactPath $packageInfo
197+
}
198+
else {
199+
LogInfo "Calling $FindArtifactForApiReviewFn with legacy parameters"
200+
$packages = &$FindArtifactForApiReviewFn $ArtifactPath $pkgArtifactName
201+
}
181202
}
182203
else
183204
{
@@ -192,42 +213,34 @@ function ProcessPackage($packageName)
192213
foreach($pkgPath in $packages.Values)
193214
{
194215
$pkg = Split-Path -Leaf $pkgPath
195-
$pkgPropPath = Join-Path -Path $ConfigFileDir "$packageName.json"
196-
if (-Not (Test-Path $pkgPropPath))
197-
{
198-
Write-Host " Package property file path $($pkgPropPath) is invalid."
199-
continue
200-
}
201-
# Get package info from json file created before updating version to daily dev
202-
$pkgInfo = Get-Content $pkgPropPath | ConvertFrom-Json
203-
$version = [AzureEngSemanticVersion]::ParseVersionString($pkgInfo.Version)
204-
if ($version -eq $null)
216+
$version = [AzureEngSemanticVersion]::ParseVersionString($packageInfo.Version)
217+
if ($null -eq $version)
205218
{
206-
Write-Host "Version info is not available for package $packageName, because version '$(pkgInfo.Version)' is invalid. Please check if the version follows Azure SDK package versioning guidelines."
219+
Write-Host "Version info is not available for package $($packageInfo.ArtifactName), because version '$($packageInfo.Version)' is invalid. Please check if the version follows Azure SDK package versioning guidelines."
207220
return 1
208221
}
209-
222+
210223
Write-Host "Version: $($version)"
211-
Write-Host "SDK Type: $($pkgInfo.SdkType)"
212-
Write-Host "Release Status: $($pkgInfo.ReleaseStatus)"
224+
Write-Host "SDK Type: $($packageInfo.SdkType)"
225+
Write-Host "Release Status: $($packageInfo.ReleaseStatus)"
213226

214227
# Run create review step only if build is triggered from main branch or if version is GA.
215228
# This is to avoid invalidating review status by a build triggered from feature branch
216229
if ( ($SourceBranch -eq $DefaultBranch) -or (-not $version.IsPrerelease) -or $MarkPackageAsShipped)
217230
{
218231
Write-Host "Submitting API Review request for package $($pkg), File path: $($pkgPath)"
219-
$respCode = Submit-APIReview $pkgInfo $pkgPath $packageName
232+
$respCode = Submit-APIReview $packageInfo $pkgPath
220233
Write-Host "HTTP Response code: $($respCode)"
221234

222235
# no need to check API review status when marking a package as shipped
223236
if ($MarkPackageAsShipped)
224237
{
225238
if ($respCode -eq '500')
226239
{
227-
Write-Host "Failed to mark package ${packageName} as released. Please reach out to Azure SDK engineering systems on teams channel."
240+
Write-Host "Failed to mark package $($packageInfo.ArtifactName) as released. Please reach out to Azure SDK engineering systems on teams channel."
228241
return 1
229242
}
230-
Write-Host "Package ${packageName} is marked as released."
243+
Write-Host "Package $($packageInfo.ArtifactName) is marked as released."
231244
return 0
232245
}
233246

@@ -239,49 +252,49 @@ function ProcessPackage($packageName)
239252
IsApproved = $false
240253
Details = ""
241254
}
242-
Process-ReviewStatusCode $respCode $packageName $apiStatus $pkgNameStatus
255+
Process-ReviewStatusCode $respCode $packageInfo.ArtifactName $apiStatus $pkgNameStatus
243256

244257
if ($apiStatus.IsApproved) {
245258
Write-Host "API status: $($apiStatus.Details)"
246259
}
247-
elseif (!$pkgInfo.ReleaseStatus -or $pkgInfo.ReleaseStatus -eq "Unreleased") {
260+
elseif (!$packageInfo.ReleaseStatus -or $packageInfo.ReleaseStatus -eq "Unreleased") {
248261
Write-Host "Release date is not set for current version in change log file for package. Ignoring API review approval status since package is not yet ready for release."
249262
}
250263
elseif ($version.IsPrerelease)
251264
{
252265
# Check if package name is approved. Preview version cannot be released without package name approval
253-
if (!$pkgNameStatus.IsApproved)
266+
if (!$pkgNameStatus.IsApproved)
254267
{
255-
if (IsApiviewStatusCheckRequired $pkgInfo)
268+
if (IsApiviewStatusCheckRequired $packageInfo)
256269
{
257270
Write-Error $($pkgNameStatus.Details)
258271
return 1
259272
}
260273
else{
261-
Write-Host "Package name is not approved for package $($packageName), however it is not required for this package type so it can still be released without API review approval."
262-
}
274+
Write-Host "Package name is not approved for package $($packageInfo.ArtifactName), however it is not required for this package type so it can still be released without API review approval."
275+
}
263276
}
264277
# Ignore API review status for prerelease version
265278
Write-Host "Package version is not GA. Ignoring API view approval status"
266-
}
279+
}
267280
else
268281
{
269282
# Return error code if status code is 201 for new data plane package
270283
# Temporarily enable API review for spring SDK types. Ideally this should be done be using 'IsReviewRequired' method in language side
271284
# to override default check of SDK type client
272-
if (IsApiviewStatusCheckRequired $pkgInfo)
285+
if (IsApiviewStatusCheckRequired $packageInfo)
273286
{
274287
if (!$apiStatus.IsApproved)
275288
{
276-
Write-Host "Package version $($version) is GA and automatic API Review is not yet approved for package $($packageName)."
289+
Write-Host "Package version $($version) is GA and automatic API Review is not yet approved for package $($packageInfo.ArtifactName)."
277290
Write-Host "Build and release is not allowed for GA package without API review approval."
278291
Write-Host "You will need to queue another build to proceed further after API review is approved"
279292
Write-Host "You can check http://aka.ms/azsdk/engsys/apireview/faq for more details on API Approval."
280293
}
281294
return 1
282295
}
283296
else {
284-
Write-Host "API review is not approved for package $($packageName), however it is not required for this package type so it can still be released without API review approval."
297+
Write-Host "API review is not approved for package $($packageInfo.ArtifactName), however it is not required for this package type so it can still be released without API review approval."
285298
}
286299
}
287300
}
@@ -296,42 +309,84 @@ function ProcessPackage($packageName)
296309
return 0
297310
}
298311

299-
$responses = @{}
300-
# Check if package config file is present. This file has package version, SDK type etc info.
301-
if (-not $ConfigFileDir)
302-
{
312+
Write-Host "Artifact path: $($ArtifactPath)"
313+
Write-Host "Source branch: $($SourceBranch)"
314+
Write-Host "Package Info Files: $($PackageInfoFiles)"
315+
Write-Host "Artifact List: $($ArtifactList)"
316+
Write-Host "Package Name: $($PackageName)"
317+
318+
# Parameter priority and backward compatibility logic
319+
# Priority order: PackageName > Artifacts > PackageInfoFiles (for backward compatibility)
320+
321+
if (-not $ConfigFileDir) {
303322
$ConfigFileDir = Join-Path -Path $ArtifactPath "PackageInfo"
304323
}
305324

306-
Write-Host "Artifact path: $($ArtifactPath)"
307-
Write-Host "Source branch: $($SourceBranch)"
308325
Write-Host "Config File directory: $($ConfigFileDir)"
309326

310-
# if package name param is not empty then process only that package
311-
if ($PackageName)
312-
{
313-
Write-Host "Processing $($PackageName)"
314-
$result = ProcessPackage -packageName $PackageName
315-
$responses[$PackageName] = $result
327+
# Initialize working variable
328+
$ProcessedPackageInfoFiles = @()
329+
330+
if ($PackageName -and $PackageName -ne "") {
331+
# Highest Priority: Single package mode (existing usage)
332+
Write-Host "Using PackageName parameter: $PackageName"
333+
$pkgPropPath = Join-Path -Path $ConfigFileDir "$PackageName.json"
334+
if (Test-Path $pkgPropPath) {
335+
$ProcessedPackageInfoFiles = @($pkgPropPath)
336+
}
337+
else {
338+
Write-Error "Package property file path $pkgPropPath is invalid."
339+
exit 1
340+
}
316341
}
317-
else
318-
{
319-
# process all packages in the artifact
320-
foreach ($artifact in $ArtifactList)
321-
{
322-
Write-Host "Processing $($artifact.name)"
323-
$result = ProcessPackage -packageName $artifact.name
324-
$responses[$artifact.name] = $result
342+
elseif ($ArtifactList -and $ArtifactList.Count -gt 0) {
343+
# Second Priority: Multiple artifacts mode (existing usage)
344+
Write-Host "Using ArtifactList parameter with $($ArtifactList.Count) artifacts"
345+
foreach ($artifact in $ArtifactList) {
346+
$pkgPropPath = Join-Path -Path $ConfigFileDir "$($artifact.name).json"
347+
if (Test-Path $pkgPropPath) {
348+
$ProcessedPackageInfoFiles += $pkgPropPath
349+
}
350+
else {
351+
Write-Warning "Package property file path $pkgPropPath is invalid."
352+
}
325353
}
326354
}
355+
elseif ($PackageInfoFiles -and $PackageInfoFiles.Count -gt 0) {
356+
# Lowest Priority: Direct PackageInfoFiles (new method)
357+
Write-Host "Using PackageInfoFiles parameter with $($PackageInfoFiles.Count) files"
358+
$ProcessedPackageInfoFiles = $PackageInfoFiles # Use as-is
359+
}
360+
else {
361+
Write-Error "No package information provided. Please provide either 'PackageName', 'ArtifactList', or 'PackageInfoFiles' parameters."
362+
exit 1
363+
}
364+
365+
# Validate that we have package info files to process
366+
if (-not $ProcessedPackageInfoFiles -or $ProcessedPackageInfoFiles.Count -eq 0) {
367+
Write-Error "No package info files found after processing parameters."
368+
exit 1
369+
}
370+
371+
$responses = @{}
372+
Write-Host "Processed Package Info Files: $($ProcessedPackageInfoFiles -join ', ')"
373+
374+
# Process all packages using the processed PackageInfoFiles array
375+
foreach ($packageInfoFile in $ProcessedPackageInfoFiles)
376+
{
377+
$packageInfo = Get-Content $packageInfoFile | ConvertFrom-Json
378+
Write-Host "Processing $($packageInfo.ArtifactName)"
379+
$result = ProcessPackage -packageInfo $packageInfo
380+
$responses[$packageInfo.ArtifactName] = $result
381+
}
327382

328383
$exitCode = 0
329384
foreach($pkg in $responses.keys)
330-
{
385+
{
331386
if ($responses[$pkg] -eq 1)
332387
{
333388
Write-Host "API changes are not approved for $($pkg)"
334389
$exitCode = 1
335390
}
336391
}
337-
exit $exitCode
392+
exit $exitCode

0 commit comments

Comments
 (0)