11param (
2- [Parameter (Mandatory = $true )]
3- [string ]$Area ,
2+ [Parameter (Mandatory = $true , ParameterSetName = ' SingleArea' )]
3+ [string ]$Area , # Deprecated - use -Areas instead
4+
5+ [Parameter (Mandatory = $true , ParameterSetName = ' MultipleAreas' )]
6+ [string []]$Areas ,
7+
8+ [Parameter (Mandatory = $true , ParameterSetName = ' AllAreas' )]
9+ [switch ]$All ,
10+
411 [string ]$SubscriptionId ,
512 [string ]$ResourceGroupName ,
613 [string ]$BaseName ,
@@ -11,6 +18,157 @@ param(
1118$ErrorActionPreference = ' Stop'
1219. " $PSScriptRoot /../common/scripts/common.ps1"
1320
21+ function Get-AvailableAreas {
22+ <#
23+ . SYNOPSIS
24+ Discovers all available areas that have test resources.
25+ #>
26+ $areasWithTestResources = @ ()
27+ $areasDir = " $RepoRoot /areas"
28+
29+ if (Test-Path $areasDir ) {
30+ Get-ChildItem - Path $areasDir - Directory | ForEach-Object {
31+ $areaName = $_.Name.ToLower ()
32+ $testResourcesPath = " $ ( $_.FullName ) /tests/test-resources.bicep"
33+ if (Test-Path $testResourcesPath ) {
34+ $areasWithTestResources += $areaName
35+ }
36+ }
37+ }
38+
39+ return $areasWithTestResources | Sort-Object
40+ }
41+
42+ function Test-AreaExists {
43+ <#
44+ . SYNOPSIS
45+ Validates that the specified area exists and has test resources.
46+ #>
47+ param (
48+ [Parameter (Mandatory = $true )]
49+ [string ]$AreaName
50+ )
51+
52+ $areaPath = " $RepoRoot /areas/$ ( $AreaName.ToLower ()) "
53+ $testResourcesPath = " $areaPath /tests/test-resources.bicep"
54+
55+ if (! (Test-Path $areaPath )) {
56+ Write-Error " Area '$AreaName ' does not exist at path '$areaPath '."
57+ return $false
58+ }
59+
60+ if (! (Test-Path $testResourcesPath )) {
61+ Write-Error " Area '$AreaName ' does not have test resources. Expected bicep template at '$testResourcesPath '."
62+ return $false
63+ }
64+
65+ return $true
66+ }
67+
68+ function Get-AreasToProcess {
69+ <#
70+ . SYNOPSIS
71+ Determines which areas to process based on the provided parameters.
72+ #>
73+ param (
74+ [string ]$Area ,
75+ [string []]$Areas ,
76+ [switch ]$All
77+ )
78+
79+ if ($Area ) {
80+ # Backward compatibility - show deprecation warning
81+ Write-Warning " The -Area parameter is deprecated. Please use -Areas @('$Area ') or -All instead."
82+ return @ ($Area.ToLower ())
83+ }
84+ elseif ($All ) {
85+ $availableAreas = Get-AvailableAreas
86+ if ($availableAreas.Count -eq 0 ) {
87+ Write-Error " No areas with test resources found."
88+ return @ ()
89+ }
90+ Write-Host " Deploying test resources for all available areas: $ ( $availableAreas -join ' , ' ) " - ForegroundColor Cyan
91+ return $availableAreas
92+ }
93+ else {
94+ # Multiple areas specified
95+ $processAreas = @ ()
96+ foreach ($areaName in $Areas ) {
97+ $normalizedArea = $areaName.ToLower ()
98+ if (Test-AreaExists - AreaName $normalizedArea ) {
99+ $processAreas += $normalizedArea
100+ } else {
101+ return @ () # Exit early on validation failure
102+ }
103+ }
104+ return $processAreas
105+ }
106+ }
107+
108+ function Deploy-AreaTestResources {
109+ <#
110+ . SYNOPSIS
111+ Deploys test resources for a specific area.
112+ #>
113+ param (
114+ [Parameter (Mandatory = $true )]
115+ [string ]$AreaName ,
116+ [string ]$SubscriptionId ,
117+ [string ]$ResourceGroupName ,
118+ [string ]$BaseName ,
119+ [int ]$DeleteAfterHours ,
120+ [switch ]$Unique
121+ )
122+
123+ $testResourcesDirectory = Resolve-Path - Path " $RepoRoot /areas/$AreaName /tests" - ErrorAction SilentlyContinue
124+ $bicepPath = " $testResourcesDirectory /test-resources.bicep"
125+
126+ if (! (Test-Path - Path $bicepPath )) {
127+ Write-Error " Test resources bicep template '$bicepPath ' does not exist."
128+ return $false
129+ }
130+
131+ # Base the user hash on the user's account ID, subscription, and area being deployed to
132+ if ($Unique ) {
133+ $hash = [guid ]::NewGuid().ToString()
134+ } else {
135+ $hash = (New-StringHash $account.Id , $SubscriptionId , $AreaName )
136+ }
137+
138+ $suffix = $hash.ToLower ().Substring(0 , 8 )
139+
140+ $areaBaseName = if ($BaseName ) { $BaseName } else { " mcp$ ( $suffix ) " }
141+ $areaResourceGroupName = if ($ResourceGroupName ) { $ResourceGroupName } else { " $username -mcp$ ( $suffix ) " }
142+
143+ Write-Host @"
144+
145+ === Deploying Area: $ ( $AreaName.ToUpper ()) ===
146+ SubscriptionId: '$SubscriptionId '
147+ SubscriptionName: '$subscriptionName '
148+ ResourceGroupName: '$areaResourceGroupName '
149+ BaseName: '$areaBaseName '
150+ DeleteAfterHours: $DeleteAfterHours
151+ TestResourcesDirectory: '$testResourcesDirectory '
152+ "@ - ForegroundColor Green
153+
154+ try {
155+ ./ eng/ common/ TestResources/ New-TestResources.ps1 `
156+ - SubscriptionId $SubscriptionId `
157+ - ResourceGroupName $areaResourceGroupName `
158+ - BaseName $areaBaseName `
159+ - TestResourcesDirectory $testResourcesDirectory `
160+ - DeleteAfterHours $DeleteAfterHours `
161+ - Force
162+
163+ Write-Host " ✅ Successfully deployed test resources for area '$AreaName '" - ForegroundColor Green
164+ return $true
165+ }
166+ catch {
167+ Write-Error " ❌ Failed to deploy test resources for area '$AreaName ': $ ( $_.Exception.Message ) "
168+ return $false
169+ }
170+ }
171+
14172function New-StringHash ([string []]$strings ) {
15173 $string = $strings -join ' '
16174 $hash = [System.Security.Cryptography.SHA1 ]::Create()
@@ -19,13 +177,15 @@ function New-StringHash([string[]]$strings) {
19177 return [BitConverter ]::ToString($hashBytes ) -replace ' -' , ' '
20178}
21179
22- $testResourcesDirectory = Resolve-Path - Path " $RepoRoot /areas/$ ( $Area.ToLower ()) /tests" - ErrorAction SilentlyContinue
23- $bicepPath = " $testResourcesDirectory /test-resources.bicep"
24- if (! (Test-Path - Path $bicepPath )) {
25- Write-Error " Test resources bicep template '$bicepPath ' does not exist."
26- return
180+ # Determine which areas to process
181+ $areasToProcess = Get-AreasToProcess - Area $Area - Areas $Areas - All:$All
182+
183+ if ($areasToProcess.Count -eq 0 ) {
184+ Write-Error " No valid areas to process."
185+ exit 1
27186}
28187
188+ # Set up Azure context
29189if ($SubscriptionId ) {
30190 Select-AzSubscription - Subscription $SubscriptionId | Out-Null
31191 $context = Get-AzContext
@@ -38,42 +198,48 @@ if($SubscriptionId) {
38198$subscriptionName = $context.Subscription.Name
39199$account = $context.Account
40200
41- # Base the user hash on the user's account ID and subscription being deployed to
42- if ($Unique ) {
43- $hash = [guid ]::NewGuid().ToString()
44- } else {
45- $hash = (New-StringHash $account.Id , $SubscriptionId , $Area )
46- }
47-
48- $suffix = $hash.ToLower ().Substring(0 , 8 )
49-
50- if (! $BaseName ) {
51- $BaseName = " mcp$ ( $suffix ) "
52- }
53-
54- if (! $ResourceGroupName ) {
55- $username = $account.Id.Split (' @' )[0 ].ToLower()
56- $ResourceGroupName = " $username -mcp$ ( $suffix ) "
57- }
201+ # Calculate username for default resource group naming
202+ $username = $account.Id.Split (' @' )[0 ].ToLower()
58203
59204Push-Location $RepoRoot
60205try {
61- Write-Host @"
62- Deploying:
63- SubscriptionId: '$SubscriptionId '
64- SubscriptionName: '$subscriptionName '
65- ResourceGroupName: '$ResourceGroupName '
66- BaseName: '$BaseName '
67- DeleteAfterHours: $DeleteAfterHours
68- TestResourcesDirectory: '$testResourcesDirectory '
69- "@
70- ./ eng/ common/ TestResources/ New-TestResources.ps1 `
71- - SubscriptionId $SubscriptionId `
72- - ResourceGroupName $ResourceGroupName `
73- - BaseName $BaseName `
74- - TestResourcesDirectory $testResourcesDirectory `
75- - DeleteAfterHours $DeleteAfterHours `
76- - Force
206+ $successCount = 0
207+ $totalCount = $areasToProcess.Count
208+
209+ Write-Host " `n 🚀 Starting deployment of test resources for $totalCount area(s)" - ForegroundColor Cyan
210+
211+ for ($i = 0 ; $i -lt $areasToProcess.Count ; $i ++ ) {
212+ $currentArea = $areasToProcess [$i ]
213+ $progressPercent = [int ](($i / $totalCount ) * 100 )
214+
215+ Write-Progress - Activity " Deploying Test Resources" - Status " Processing area $ ( $i + 1 ) of ${totalCount} : $currentArea " - PercentComplete $progressPercent
216+
217+ $success = Deploy-AreaTestResources `
218+ - AreaName $currentArea `
219+ - SubscriptionId $SubscriptionId `
220+ - ResourceGroupName $ResourceGroupName `
221+ - BaseName $BaseName `
222+ - DeleteAfterHours $DeleteAfterHours `
223+ - Unique:$Unique
224+
225+ if ($success ) {
226+ $successCount ++
227+ }
228+ }
229+
230+ Write-Progress - Activity " Deploying Test Resources" - Completed
231+
232+ Write-Host " `n 📊 Deployment Summary:" - ForegroundColor Cyan
233+ Write-Host " Total areas processed: $totalCount " - ForegroundColor White
234+ Write-Host " Successful deployments: $successCount " - ForegroundColor Green
235+ Write-Host " Failed deployments: $ ( $totalCount - $successCount ) " - ForegroundColor Red
236+
237+ if ($successCount -eq $totalCount ) {
238+ Write-Host " `n 🎉 All deployments completed successfully!" - ForegroundColor Green
239+ } else {
240+ Write-Host " `n ⚠️ Some deployments failed. Check the output above for details." - ForegroundColor Yellow
241+ exit 1
242+ }
77243}
78244finally {
79245 Pop-Location
0 commit comments