Skip to content

Commit e9302b1

Browse files
committed
Allow arbitrary platform settings to Build-Code.ps1
1 parent 51ee74f commit e9302b1

File tree

37 files changed

+223
-179
lines changed

37 files changed

+223
-179
lines changed

core/Azure.Mcp.Core/tests/test-resources-post.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ param(
99
$ErrorActionPreference = "Stop"
1010

1111
. "$PSScriptRoot/../../../eng/common/scripts/common.ps1"
12-
. "$PSScriptRoot/../../../eng/scripts/helpers/TestResourcesHelpers.ps1"
12+
. "$PSScriptRoot/../../../eng/scripts/helpers.ps1"
1313

1414
$testSettings = New-TestSettings @PSBoundParameters -OutputPath $PSScriptRoot
1515

eng/pipelines/templates/jobs/build.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,12 @@ jobs:
6363
pwsh: true
6464
filePath: $(Build.SourcesDirectory)/eng/scripts/Build-Code.ps1
6565
arguments: >
66-
-ServerName '${{ parameters.ServerName }}'
6766
-BuildInfoPath '$(Pipeline.Workspace)/build_info/build_info.json'
6867
-OutputPath '$(Build.ArtifactStagingDirectory)'
69-
-OperatingSystem '${{ parameters.OSName }}'
70-
-Architecture '$(Architecture)'
71-
-Native:$$(Native)
68+
-ServerName '${{ parameters.ServerName }}'
69+
-PlatformName '$(PlatformName)'
7270
-ReleaseBuild:$${{ ne(parameters.PublishTarget, 'none') }}
7371
-SelfContained
74-
-Trimmed:$$(Trimmed)
7572
-SingleFile
7673
7774
- task: Powershell@2

eng/scripts/Build-Code.ps1

Lines changed: 147 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,39 @@
11
#!/bin/env pwsh
22
#Requires -Version 7
33

4-
[CmdletBinding(DefaultParameterSetName='none')]
4+
[CmdletBinding(DefaultParameterSetName='SpecificPlatform')]
55
param(
6-
[string] $BuildInfoPath,
76
[string] $OutputPath,
7+
[string] $ServerName,
8+
89
[switch] $SelfContained,
910
[switch] $SingleFile,
1011
[switch] $ReadyToRun,
11-
[switch] $Trimmed,
1212
[switch] $ReleaseBuild,
1313
[switch] $CleanBuild,
14-
[switch] $Native,
15-
[string] $ServerName,
1614

17-
[Parameter(Mandatory, ParameterSetName='SpecificPlatform')]
15+
[Parameter(ParameterSetName='SpecificPlatform')]
1816
[Alias('OS')]
19-
[ValidateSet('windows','linux','macos')]
20-
[string[]] $OperatingSystem,
21-
22-
[Parameter(Mandatory, ParameterSetName='SpecificPlatform')]
23-
[ValidateSet('x64','arm64')]
24-
[string[]] $Architecture,
17+
[string[]] $OperatingSystems,
18+
[Parameter(ParameterSetName='SpecificPlatform')]
19+
[string[]] $Architectures,
20+
[Parameter(ParameterSetName='SpecificPlatform')]
21+
[switch] $Trimmed,
22+
[Parameter(ParameterSetName='SpecificPlatform')]
23+
[switch] $Native,
2524

26-
[Parameter(ParameterSetName='AllPlatforms')]
27-
[switch] $AllPlatforms
25+
[Parameter(ParameterSetName='BuildInfoPlatform')]
26+
[string] $BuildInfoPath,
27+
[Parameter(ParameterSetName='BuildInfoPlatform')]
28+
[switch] $AllPlatforms,
29+
[Parameter(Mandatory = {!$AllPlatforms}, ParameterSetName='BuildInfoPlatform')]
30+
[string] $PlatformName
2831
)
2932

3033
$ErrorActionPreference = 'Stop'
3134
. "$PSScriptRoot/../common/scripts/common.ps1"
35+
. "$PSScriptRoot/helpers.ps1"
36+
3237
$RepoRoot = $RepoRoot.Path.Replace('\', '/')
3338

3439
$exitCode = 0
@@ -37,131 +42,167 @@ if (!$OutputPath) {
3742
$OutputPath = "$RepoRoot/.work/build"
3843
}
3944

40-
if(!$BuildInfoPath) {
41-
$BuildInfoPath = "$RepoRoot/.work/build_info.json"
42-
}
45+
function BuildServer($server) {
46+
$serverName = $server.name
47+
$projectPath = $server.path
4348

44-
if (!(Test-Path $BuildInfoPath)) {
45-
LogError "Build info file $BuildInfoPath does not exist. Run eng/scripts/New-BuildInfo.ps1 to create it."
46-
$exitCode = 1
47-
}
49+
if(!(Test-Path $projectPath)) {
50+
LogError "No project file found for $serverName"
51+
$script:exitCode = 1
52+
return
53+
}
4854

49-
# normalize OperatingSystem and Architecture
50-
$runtime = [System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier.Split('-')
55+
$version = $server.version
5156

52-
if($OperatingSystem) {
53-
$OperatingSystem = $OperatingSystem | Select-Object -Unique
54-
} else {
55-
if($AllPlatforms -and $Native) {
56-
LogWarning "Native Builds do not support Cross OS builds. Only building for the current OS."
57-
}
57+
if($PlatformName) {
58+
$platforms = $server.platforms | Where-Object { $_.name -eq $PlatformName }
5859

59-
if ($AllPlatforms -and !$Native) {
60-
$OperatingSystem = @('windows', 'linux', 'macOS')
61-
} else {
62-
if ($IsWindows) {
63-
$OperatingSystem = @('windows')
64-
} elseif ($IsLinux) {
65-
$OperatingSystem = @('linux')
66-
} elseif ($IsMacOS) {
67-
$OperatingSystem = @('macOS')
68-
} else {
69-
LogError "Unsupported OS detected. Supported OS are Windows, Linux and macOS."
70-
$exitCode = 1
60+
if ($platforms.Count -eq 0) {
61+
LogError "No build configuration found for $serverName on $os-$arch with Native=$Native and Trimmed=$Trimmed"
62+
$script:exitCode = 1
63+
continue
7164
}
65+
} else {
66+
$platforms = $server.platforms
7267
}
73-
}
7468

75-
if($Architecture) {
76-
$Architecture = $Architecture | Select-Object -Unique
77-
} else {
78-
$Architecture = $AllPlatforms ? @('x64', 'arm64') : @($runtime[1])
79-
}
69+
foreach($platform in $platforms) {
70+
$dotnetOs = $platform.dotnetOs
71+
$arch = $platform.architecture
72+
$configuration = if ($ReleaseBuild) { 'Release' } else { 'Debug' }
73+
$runtime = "$dotnetOs-$arch"
8074

81-
# Exit early if there were parameter errors
82-
if($exitCode -ne 0) {
83-
exit $exitCode
84-
}
75+
$outputDir = "$OutputPath/$($platform.artifactPath)"
76+
Write-Host "Building $configuration $runtime, version $version in $outputDir" -ForegroundColor Green
8577

86-
$buildInfo = Get-Content $BuildInfoPath -Raw | ConvertFrom-Json -AsHashtable
78+
# Clear and recreate the package output directory
79+
Remove-Item -Path $outputDir -Recurse -Force -ErrorAction SilentlyContinue -ProgressAction SilentlyContinue
80+
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
8781

88-
function BuildServer($server) {
89-
$serverName = $server.name
82+
$command = "dotnet publish '$projectPath' --runtime '$runtime' --output '$outputDir' /p:Version=$version /p:Configuration=$configuration"
9083

91-
if(!(Test-Path $server.path)) {
92-
LogError "No project file found for $serverName"
93-
$script:exitCode = 1
94-
return
95-
}
84+
if($SelfContained -or $platform.trimmed) {
85+
$command += " --self-contained"
86+
}
9687

97-
$projectPath = $server.path
98-
$version = $server.version
88+
if($platform.trimmed) {
89+
$command += " /p:PublishTrimmed=true"
90+
}
9991

100-
$serverOutputDirectory = "$OutputPath/$($server.artifactPath)"
92+
if($platform.native) {
93+
$command += " /p:BuildNative=true"
94+
}
10195

102-
New-Item -Path $serverOutputDirectory -ItemType Directory -Force | Out-Null
96+
if($ReadyToRun) {
97+
$command += " /p:PublishReadyToRun=true"
98+
}
10399

104-
foreach ($os in $OperatingSystem) {
105-
foreach ($arch in $Architecture) {
106-
$filteredPlatforms = @($server.platforms
107-
| Where-Object {
108-
($_.operatingSystem -eq $os) -and
109-
($_.architecture -eq $arch) -and
110-
($_.native -eq $Native) -and
111-
($_.trimmed -eq $Trimmed) })
100+
if($SingleFile) {
101+
$command += " /p:PublishSingleFile=true"
102+
}
112103

113-
if ($filteredPlatforms.Count -eq 0) {
114-
LogError "No build configuration found for $serverName on $os-$arch with Native=$Native and Trimmed=$Trimmed"
115-
$script:exitCode = 1
116-
continue
117-
} elseif ($filteredPlatforms.Count -gt 1) {
118-
LogError "Multiple build configurations found for $serverName on $os-$arch with Native=$Native"
119-
$script:exitCode = 1
120-
continue
121-
}
104+
Invoke-LoggedMsBuildCommand $command -GroupOutput
105+
}
122106

123-
$platform = $filteredPlatforms[0]
107+
Write-Host "`nBuild completed successfully!" -ForegroundColor Green
108+
}
124109

125-
$dotnetOs = $platform.dotnetOs
126-
$runtime = "$dotnetOs-$arch"
127-
$configuration = if ($ReleaseBuild) { 'Release' } else { 'Debug' }
110+
function CreateServersWithPlatforms {
111+
if(!$OperatingSystems) {
112+
if ($IsWindows) {
113+
$OperatingSystems = @('windows')
114+
} elseif ($IsLinux) {
115+
$OperatingSystems = @('linux')
116+
} elseif ($IsMacOS) {
117+
$OperatingSystems = @('macos')
118+
} else {
119+
LogError "Unsupported OS detected. Supported OS are Windows, Linux and macOS."
120+
$exitCode = 1
121+
}
122+
}
128123

129-
$outputDir = "$OutputPath/$($platform.artifactPath)"
130-
Write-Host "Building $configuration $runtime, version $version in $outputDir" -ForegroundColor Green
124+
if(!$Architectures) {
125+
$currentArch = [System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier.Split('-')[1]
126+
$Architectures = @($currentArch)
127+
}
131128

132-
# Clear and recreate the package output directory
133-
Remove-Item -Path $outputDir -Recurse -Force -ErrorAction SilentlyContinue -ProgressAction SilentlyContinue
134-
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
129+
$OperatingSystems = $OperatingSystems | Sort-Object -Unique
130+
$Architectures = $Architectures | Sort-Object -Unique
131+
$osDetails = Get-OperatingSystems
135132

136-
$command = "dotnet publish '$projectPath' --runtime '$runtime' --output '$outputDir' /p:Version=$version /p:Configuration=$configuration"
133+
$serverDirectories = Get-ChildItem "$RepoRoot/servers" -Directory
134+
$serverProjects = $serverDirectories | Get-ChildItem -Filter "src/*.csproj"
135+
if ($ServerName) {
136+
$serverProjects = $serverProjects | Where-Object { $_.BaseName -eq $ServerName }
137+
if ($serverProjects.Count -eq 0) {
138+
LogError "No server project found with name '$ServerName'."
139+
$exitCode = 1
140+
}
141+
}
137142

138-
if($SelfContained) {
139-
$command += " --self-contained"
140-
}
143+
$serverProjects | ForEach-Object {
144+
$serverName = $_.BaseName
145+
$projectPath = $_.FullName
146+
$properties = . "$PsScriptRoot/Get-ProjectProperties.ps1" -Path $projectPath
141147

142-
if($ReadyToRun) {
143-
$command += " /p:PublishReadyToRun=true"
144-
}
148+
$platforms = @($OperatingSystems | ForEach-Object {
149+
$os = $osDetails | Where-Object Name -eq -value $_
145150

146-
if($Trimmed) {
147-
$command += " /p:PublishTrimmed=true"
151+
if(-not $os) {
152+
LogError "Unsupported operating system specified: '$_'. Supported OS are: $($osDetails.Name -join ', ')"
153+
$script:exitCode = 1
154+
return
148155
}
149156

150-
if($Native) {
151-
$command += " /p:BuildNative=true"
157+
$Architectures | ForEach-Object {
158+
$platform = "$($os.Name)-$_"
159+
[ordered]@{
160+
name = $platform
161+
dotnetOs = $os.DotNetName
162+
architecture = $_
163+
artifactPath = "$serverName/$platform"
164+
native = $Native
165+
trimmed = $Trimmed
166+
}
152167
}
168+
})
153169

154-
if($SingleFile) {
155-
$command += " /p:PublishSingleFile=true"
156-
}
170+
[ordered]@{
171+
name = $serverName
172+
path = $projectPath.Replace('\', '/')
173+
version = $properties.Version
174+
platforms = $platforms
175+
}
176+
}
177+
}
157178

158-
Invoke-LoggedMsBuildCommand $command -GroupOutput
179+
$servers = @()
159180

160-
Write-Host "`nBuild completed successfully!" -ForegroundColor Green
181+
if($PSCmdlet.ParameterSetName -eq 'SpecificPlatform') {
182+
$servers = CreateServersWithPlatforms
183+
} else {
184+
if(!$BuildInfoPath) {
185+
$BuildInfoPath = "$RepoRoot/.work/build_info.json"
186+
}
187+
188+
$buildInfo = Get-Content $BuildInfoPath -Raw | ConvertFrom-Json -AsHashtable
189+
190+
$servers = $buildInfo.servers
191+
192+
if ($ServerName) {
193+
$servers = $servers | Where-Object { $_.name -eq $ServerName }
194+
if ($servers.Count -eq 0) {
195+
LogError "No build configuration found for server named '$ServerName' in build info file."
196+
$exitCode = 1
161197
}
162198
}
163199
}
164200

201+
# Exit early if there were parameter errors
202+
if($exitCode -ne 0) {
203+
exit $exitCode
204+
}
205+
165206
Push-Location $RepoRoot
166207
try {
167208
if ($CleanBuild) {
@@ -170,7 +211,7 @@ try {
170211
Remove-Item * -Recurse -Include 'obj', 'bin' -Force -ProgressAction SilentlyContinue
171212
}
172213

173-
foreach ($server in $buildInfo.servers) {
214+
foreach ($server in $servers) {
174215
BuildServer $server
175216

176217
if ($LastExitCode -ne 0) {

eng/scripts/New-BuildInfo.ps1

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ param(
1313
)
1414

1515
. "$PSScriptRoot/../common/scripts/common.ps1"
16-
. "$PSScriptRoot/helpers/PathHelpers.ps1"
16+
. "$PSScriptRoot/helpers.ps1"
17+
1718
$RepoRoot = $RepoRoot.Path.Replace('\', '/')
1819
$isPipelineRun = $CI -or $env:TF_BUILD -eq 'true'
1920
$isPullRequestBuild = $env:BUILD_REASON -eq 'PullRequest'
@@ -62,14 +63,9 @@ $serverDirectories = Get-ChildItem "$RepoRoot/servers" -Directory
6263
$toolDirectories = Get-ChildItem "$RepoRoot/tools" -Directory
6364
$coreDirectories = Get-ChildItem "$RepoRoot/core" -Directory
6465

66+
$operatingSystems = Get-OperatingSystems
6567
$architectures = @('x64', 'arm64')
6668

67-
$operatingSystems = @(
68-
@{ name = 'linux'; nodeName = 'linux'; dotnetName = 'linux'; extension = '' }
69-
@{ name = 'macos'; nodeName = 'darwin'; dotnetName = 'osx'; extension = '' }
70-
@{ name = 'windows'; nodeName = 'win32'; dotnetName = 'win'; extension = '.exe' }
71-
)
72-
7369
# Public releases always use the version from the repo without a dynamic prerelease suffix, except for test pipelines
7470
# which always use a dynamic prerelease suffix to allow for multiple releases from the same commit
7571
$dynamicPrereleaseVersion = $PublishTarget -ne 'public' -or $TestPipeline
@@ -562,6 +558,7 @@ function Get-BuildMatrices {
562558
$runRecordedTests = $runUnitTests -and ($pathsToTest | Where-Object { $_.hasRecordedTests } | Measure-Object | Select-Object -ExpandProperty Count) -gt 0
563559

564560
$buildMatrix[$legName] = [ordered]@{
561+
PlatformName = $platform.name
565562
Pool = $pool
566563
OSVmImage = $vmImage
567564
Architecture = $arch

0 commit comments

Comments
 (0)