11# !/bin/env pwsh
22# Requires -Version 7
33
4- [CmdletBinding (DefaultParameterSetName = ' none' )]
5- param (
6- [string ] $BuildInfoPath ,
4+ # When calling with BuildInfoPath or PlatformName, we build according to the platform definitions in build_info.json.
5+ # Otherwise, we build based on the custom build parameters.
6+ [CmdletBinding (DefaultParameterSetName = ' CustomPlatform' )]
7+ param (
8+ # Common Parameters
79 [string ] $OutputPath ,
10+ [string ] $ServerName ,
11+
12+ # Common Switches
813 [switch ] $SelfContained ,
914 [switch ] $SingleFile ,
1015 [switch ] $ReadyToRun ,
11- [switch ] $Trimmed ,
1216 [switch ] $ReleaseBuild ,
1317 [switch ] $CleanBuild ,
14- [switch ] $Native ,
15- [string ] $ServerName ,
1618
17- [Parameter (Mandatory , ParameterSetName = ' SpecificPlatform' )]
18- [Alias (' OS' )]
19- [ValidateSet (' windows' , ' linux' , ' macos' )]
20- [string []] $OperatingSystem ,
21-
22- [Parameter (Mandatory , ParameterSetName = ' SpecificPlatform' )]
23- [ValidateSet (' x64' , ' arm64' )]
24- [string []] $Architecture ,
19+ # build_info.json based parameters
20+ [Parameter (ParameterSetName = ' BuildInfoPlatform' )]
21+ [string ] $BuildInfoPath ,
22+ [Parameter (ParameterSetName = ' BuildInfoPlatform' )]
23+ [string ] $PlatformName ,
2524
26- [Parameter (ParameterSetName = ' AllPlatforms' )]
27- [switch ] $AllPlatforms
25+ # Custom build parameters
26+ [Parameter (ParameterSetName = ' CustomPlatform' )]
27+ [Alias (' OS' )]
28+ [string []] $OperatingSystems ,
29+ [Parameter (ParameterSetName = ' CustomPlatform' )]
30+ [string []] $Architectures ,
31+ [Parameter (ParameterSetName = ' CustomPlatform' )]
32+ [switch ] $Trimmed ,
33+ [Parameter (ParameterSetName = ' CustomPlatform' )]
34+ [switch ] $Native
2835)
2936
3037$ErrorActionPreference = ' Stop'
3138. " $PSScriptRoot /../common/scripts/common.ps1"
39+ . " $PSScriptRoot /helpers/BuildHelpers.ps1"
40+
3241$RepoRoot = $RepoRoot.Path.Replace (' \' , ' /' )
3342
3443$exitCode = 0
@@ -37,129 +46,174 @@ if (!$OutputPath) {
3746 $OutputPath = " $RepoRoot /.work/build"
3847}
3948
40- if ( ! $BuildInfoPath ) {
41- $BuildInfoPath = " $RepoRoot /.work/build_info.json "
42- }
49+ function BuildServer ( $server ) {
50+ $serverName = $server .name
51+ $projectPath = $server .path
4352
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- }
53+ if (! (Test-Path $projectPath )) {
54+ LogError " No project file found for $serverName "
55+ $script :exitCode = 1
56+ return
57+ }
4858
49- # normalize OperatingSystem and Architecture
50- $runtime = [System.Runtime.InteropServices.RuntimeInformation ]::RuntimeIdentifier.Split(' -' )
59+ $version = $server.version
5160
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- }
61+ if ($PlatformName ) {
62+ $platforms = $server.platforms | Where-Object { $_.name -eq $PlatformName }
5863
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
64+ if ($platforms.Count -eq 0 ) {
65+ LogError " No build configuration found for $serverName with platform name $PlatformName "
66+ $script :exitCode = 1
67+ return
7168 }
69+ } else {
70+ $platforms = $server.platforms
7271 }
73- }
7472
75- if ( $Architecture ) {
76- $Architecture = $Architecture | Select-Object - Unique
77- } else {
78- $Architecture = $AllPlatforms ? @ ( ' x64 ' , ' arm64 ' ) : @ ( $runtime [ 1 ])
79- }
73+ foreach ( $platform in $platforms ) {
74+ $dotnetOs = $platform .dotnetOs
75+ $arch = $platform .architecture
76+ $configuration = if ( $ReleaseBuild ) { ' Release ' } else { ' Debug ' }
77+ $runtime = " $dotnetOs - $arch "
8078
81- # Exit early if there were parameter errors
82- if ($exitCode -ne 0 ) {
83- exit $exitCode
84- }
79+ $outputDir = " $OutputPath /$ ( $platform.artifactPath ) "
80+ Write-Host " Building $configuration $runtime , version $version in $outputDir " - ForegroundColor Green
8581
86- $buildInfo = Get-Content $BuildInfoPath - Raw | ConvertFrom-Json - AsHashtable
82+ # Clear and recreate the package output directory
83+ Remove-Item - Path $outputDir - Recurse - Force - ErrorAction SilentlyContinue - ProgressAction SilentlyContinue
84+ New-Item - Path $outputDir - ItemType Directory - Force | Out-Null
8785
88- function BuildServer ($server ) {
89- $serverName = $server.name
86+ $command = " dotnet publish '$projectPath ' --runtime '$runtime ' --output '$outputDir ' /p:Version=$version /p:Configuration=$configuration "
9087
91- if (! (Test-Path $server.path )) {
92- LogError " No project file found for $serverName "
93- $script :exitCode = 1
94- return
95- }
88+ if ($SelfContained -or $platform.trimmed ) {
89+ $command += " --self-contained"
90+ }
9691
97- $projectPath = $server.path
98- $version = $server.version
92+ if ($platform.trimmed ) {
93+ $command += " /p:PublishTrimmed=true"
94+ }
9995
100- $serverOutputDirectory = " $OutputPath /$ ( $server.artifactPath ) "
101-
102- New-Item - Path $serverOutputDirectory - ItemType Directory - Force | Out-Null
103-
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 ) })
112-
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- }
96+ if ($platform.native ) {
97+ $command += " /p:BuildNative=true"
98+ }
12299
123- $platform = $filteredPlatforms [0 ]
100+ if ($ReadyToRun ) {
101+ $command += " /p:PublishReadyToRun=true"
102+ }
124103
125- $dotnetOs = $platform .dotnetOs
126- $runtime = " $dotnetOs - $arch "
127- $configuration = if ( $ReleaseBuild ) { ' Release ' } else { ' Debug ' }
104+ if ( $SingleFile ) {
105+ $command + = " /p:PublishSingleFile=true "
106+ }
128107
129- $outputDir = " $OutputPath / $ ( $platform .artifactPath ) "
130- Write-Host " Building $configuration $runtime , version $version in $outputDir " - ForegroundColor Green
108+ Invoke-LoggedMsBuildCommand $command - GroupOutput
109+ }
131110
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
111+ Write-Host " `n Build completed successfully!" - ForegroundColor Green
112+ }
135113
136- $command = " dotnet publish '$projectPath ' --runtime '$runtime ' --output '$outputDir ' /p:Version=$version /p:Configuration=$configuration "
114+ function CreateServersWithPlatforms {
115+ if (! $OperatingSystems ) {
116+ if ($IsWindows ) {
117+ $OperatingSystems = @ (' windows' )
118+ } elseif ($IsLinux ) {
119+ $OperatingSystems = @ (' linux' )
120+ } elseif ($IsMacOS ) {
121+ $OperatingSystems = @ (' macos' )
122+ } else {
123+ LogError " Unsupported OS detected. Supported OS are Windows, Linux and macOS."
124+ exit 1
125+ }
126+ }
137127
138- if ($SelfContained ) {
139- $command += " --self-contained"
140- }
128+ if (! $Architectures ) {
129+ $currentArch = [System.Runtime.InteropServices.RuntimeInformation ]::RuntimeIdentifier.Split(' -' )[1 ]
130+ $Architectures = @ ($currentArch )
131+ }
141132
142- if ($ReadyToRun ) {
143- $command += " /p:PublishReadyToRun=true"
144- }
133+ $OperatingSystems = $OperatingSystems | Sort-Object - Unique
134+ $Architectures = $Architectures | Sort-Object - Unique
135+ $osDetails = Get-OperatingSystems
136+
137+ $serverDirectories = Get-ChildItem " $RepoRoot /servers" - Directory
138+ $serverProjects = $serverDirectories | Get-ChildItem - Filter " src/*.csproj"
139+ if ($ServerName ) {
140+ $serverProjects = $serverProjects | Where-Object { $_.BaseName -eq $ServerName }
141+ if ($serverProjects.Count -eq 0 ) {
142+ LogError " No server project found with name '$ServerName '."
143+ exit 1
144+ }
145+ }
145146
146- if ($Trimmed ) {
147- $command += " /p:PublishTrimmed=true"
148- }
147+ $serverProjects | ForEach-Object {
148+ $serverName = $_.BaseName
149+ $projectPath = $_.FullName
150+ $properties = . " $PSScriptRoot /Get-ProjectProperties.ps1" - Path $projectPath
151+
152+ $platforms = @ ($OperatingSystems | ForEach-Object {
153+ $os = $osDetails | Where-Object name -eq $_
149154
150- if ($Native ) {
151- $command += " /p:BuildNative=true"
155+ if (-not $os ) {
156+ LogError " Unsupported operating system specified: '$_ '. Supported OS are: $ ( $osDetails.name -join ' , ' ) "
157+ exit 1
152158 }
153159
154- if ($SingleFile ) {
155- $command += " /p:PublishSingleFile=true"
160+ $Architectures | ForEach-Object {
161+ $platform = " $ ( $os.name ) -$_ "
162+ [ordered ]@ {
163+ name = $platform
164+ dotnetOs = $os.dotnetName
165+ architecture = $_
166+ artifactPath = " $serverName /$platform "
167+ native = $Native
168+ trimmed = $Trimmed
169+ }
156170 }
171+ })
172+
173+ [ordered ]@ {
174+ name = $serverName
175+ path = $projectPath.Replace (' \' , ' /' )
176+ version = $properties.Version
177+ platforms = $platforms
178+ }
179+ }
180+ }
157181
158- Invoke-LoggedMsBuildCommand $command - GroupOutput
182+ function GetServersFromBuildInfo {
183+ if (! $BuildInfoPath ) {
184+ $BuildInfoPath = " $RepoRoot /.work/build_info.json"
185+ }
186+
187+ if (! (Test-Path $BuildInfoPath )) {
188+ LogError " Build info file not found at path '$BuildInfoPath '. Please provide a valid path using -BuildInfoPath."
189+ exit 1
190+ } else {
191+ $buildInfo = Get-Content $BuildInfoPath - Raw | ConvertFrom-Json - AsHashtable
192+ $servers = $buildInfo.servers
193+ }
159194
160- Write-Host " `n Build completed successfully!" - ForegroundColor Green
195+ if ($ServerName ) {
196+ $servers = $servers | Where-Object { $_.name -eq $ServerName }
197+ if ($servers.Count -eq 0 ) {
198+ LogError " No build configuration found for server named '$ServerName ' in build info file."
199+ exit 1
161200 }
162201 }
202+
203+ return $servers
204+ }
205+
206+ $servers = @ ()
207+
208+ if ($PSCmdlet.ParameterSetName -eq ' CustomPlatform' ) {
209+ $servers = CreateServersWithPlatforms
210+ } else {
211+ $servers = GetServersFromBuildInfo
212+ }
213+
214+ # Exit early if there were parameter errors
215+ if ($exitCode -ne 0 ) {
216+ exit $exitCode
163217}
164218
165219Push-Location $RepoRoot
@@ -170,7 +224,7 @@ try {
170224 Remove-Item * - Recurse - Include ' obj' , ' bin' - Force - ProgressAction SilentlyContinue
171225 }
172226
173- foreach ($server in $buildInfo . servers ) {
227+ foreach ($server in $servers ) {
174228 BuildServer $server
175229
176230 if ($LastExitCode -ne 0 ) {
0 commit comments