Skip to content

Commit f7b8b3e

Browse files
authored
Make it easier to call Build-Code.ps1 (#1324)
1 parent a79338c commit f7b8b3e

File tree

8 files changed

+236
-133
lines changed

8 files changed

+236
-133
lines changed

eng/pipelines/templates/jobs/build.yml

Lines changed: 4 additions & 7 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 '$(BuildPlatformName)'
7270
-ReleaseBuild:$${{ ne(parameters.PublishTarget, 'none') }}
7371
-SelfContained
74-
-Trimmed:$$(Trimmed)
7572
-SingleFile
7673
7774
- task: Powershell@2
@@ -107,7 +104,7 @@ jobs:
107104
condition: and(succeededOrFailed(), eq(variables['RunUnitTests'], 'true'))
108105
inputs:
109106
testResultsFiles: "$(Build.ArtifactStagingDirectory)/testResults/*.trx"
110-
testRunTitle: "unit-${{ parameters.OSName }}-$(Architecture)"
107+
testRunTitle: "unit_$(System.JobName)"
111108
testResultsFormat: "VSTest"
112109
mergeTestResults: true
113110

@@ -116,7 +113,7 @@ jobs:
116113
condition: and(succeededOrFailed(), eq(variables['RunRecordedTests'], 'true'))
117114
inputs:
118115
testResultsFiles: "$(Build.ArtifactStagingDirectory)/recordedTestResults/*.trx"
119-
testRunTitle: "recorded-${{ parameters.OSName }}-$(Architecture)"
116+
testRunTitle: "recorded_$(System.JobName)"
120117
testResultsFormat: "VSTest"
121118
mergeTestResults: true
122119

eng/scripts/Build-Code.ps1

Lines changed: 165 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,43 @@
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 "`nBuild 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 "`nBuild 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

165219
Push-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

Comments
 (0)