run.ps1 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #!/usr/bin/env powershell
  2. #requires -version 4
  3. <#
  4. .SYNOPSIS
  5. Executes KoreBuild commands.
  6. .DESCRIPTION
  7. Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`.
  8. .PARAMETER Command
  9. The KoreBuild command to run.
  10. .PARAMETER Path
  11. The folder to build. Defaults to the folder containing this script.
  12. .PARAMETER LockFile
  13. The path to the korebuild-lock.txt file. Defaults to $Path/korebuild-lock.txt
  14. .PARAMETER Channel
  15. The channel of KoreBuild to download. Overrides the value from the config file.
  16. .PARAMETER DotNetHome
  17. The directory where .NET Core tools will be stored.
  18. .PARAMETER ToolsSource
  19. The base url where build tools can be downloaded. Overrides the value from the config file.
  20. .PARAMETER Update
  21. Updates KoreBuild to the latest version even if a lock file is present.
  22. .PARAMETER Reinstall
  23. Re-installs KoreBuild
  24. .PARAMETER ConfigFile
  25. The path to the configuration file that stores values. Defaults to korebuild.json.
  26. .PARAMETER CI
  27. Sets up CI specific settings and variables.
  28. .PARAMETER PackageVersionPropsUrl
  29. (optional) the url of the package versions props path containing dependency versions.
  30. .PARAMETER AssetRootUrl
  31. (optional) the base url for acquiring build assets from an orchestrated build
  32. .PARAMETER AccessTokenSuffix
  33. (optional) the query string to append to any blob store access for PackageVersionPropsUrl, if any.
  34. .PARAMETER RestoreSources
  35. (optional) Semi-colon delimited list of additional NuGet feeds to use as part of restore.
  36. .PARAMETER ProductBuildId
  37. (optional) The product build ID for correlation with orchestrated builds.
  38. .PARAMETER MSBuildArguments
  39. Additional MSBuild arguments to be passed through.
  40. .NOTES
  41. This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
  42. When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
  43. The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
  44. in the file are overridden by command line parameters.
  45. .EXAMPLE
  46. Example config file:
  47. ```json
  48. {
  49. "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
  50. "channel": "master",
  51. "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
  52. }
  53. ```
  54. #>
  55. [CmdletBinding(PositionalBinding = $false)]
  56. param(
  57. [Parameter(Mandatory=$true, Position = 0)]
  58. [string]$Command,
  59. [string]$Path = $PSScriptRoot,
  60. [string]$LockFile,
  61. [Alias('c')]
  62. [string]$Channel,
  63. [Alias('d')]
  64. [string]$DotNetHome,
  65. [Alias('s')]
  66. [string]$ToolsSource,
  67. [Alias('u')]
  68. [switch]$Update,
  69. [switch]$Reinstall,
  70. [string]$ConfigFile = $null,
  71. [switch]$CI,
  72. [string]$PackageVersionPropsUrl = $null,
  73. [string]$AccessTokenSuffix = $null,
  74. [string]$RestoreSources = $null,
  75. [string]$AssetRootUrl = $null,
  76. [string]$ProductBuildId = $null,
  77. [Parameter(ValueFromRemainingArguments = $true)]
  78. [string[]]$MSBuildArguments
  79. )
  80. Set-StrictMode -Version 2
  81. $ErrorActionPreference = 'Stop'
  82. #
  83. # Functions
  84. #
  85. function Get-KoreBuild {
  86. if (!(Test-Path $LockFile) -or $Update) {
  87. Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $LockFile
  88. }
  89. $version = Get-Content $LockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
  90. if (!$version) {
  91. Write-Error "Failed to parse version from $LockFile. Expected a line that begins with 'version:'"
  92. }
  93. $version = $version.TrimStart('version:').Trim()
  94. $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
  95. if ($Reinstall -and (Test-Path $korebuildPath)) {
  96. Remove-Item -Force -Recurse $korebuildPath
  97. }
  98. if (!(Test-Path $korebuildPath)) {
  99. Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
  100. New-Item -ItemType Directory -Path $korebuildPath | Out-Null
  101. $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
  102. try {
  103. $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
  104. Get-RemoteFile $remotePath $tmpfile
  105. if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
  106. # Use built-in commands where possible as they are cross-plat compatible
  107. Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
  108. }
  109. else {
  110. # Fallback to old approach for old installations of PowerShell
  111. Add-Type -AssemblyName System.IO.Compression.FileSystem
  112. [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
  113. }
  114. }
  115. catch {
  116. Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
  117. throw
  118. }
  119. finally {
  120. Remove-Item $tmpfile -ErrorAction Ignore
  121. }
  122. }
  123. return $korebuildPath
  124. }
  125. function Join-Paths([string]$path, [string[]]$childPaths) {
  126. $childPaths | ForEach-Object { $path = Join-Path $path $_ }
  127. return $path
  128. }
  129. function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
  130. if ($RemotePath -notlike 'http*') {
  131. Copy-Item $RemotePath $LocalPath
  132. return
  133. }
  134. $retries = 10
  135. while ($retries -gt 0) {
  136. $retries -= 1
  137. try {
  138. Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
  139. return
  140. }
  141. catch {
  142. Write-Verbose "Request failed. $retries retries remaining"
  143. }
  144. }
  145. Write-Error "Download failed: '$RemotePath'."
  146. }
  147. #
  148. # Main
  149. #
  150. # Load configuration or set defaults
  151. $Path = Resolve-Path $Path
  152. if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
  153. if (Test-Path $ConfigFile) {
  154. try {
  155. $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
  156. if ($config) {
  157. if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
  158. if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
  159. }
  160. } catch {
  161. Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
  162. Write-Warning $Error[0]
  163. }
  164. }
  165. if (!$DotNetHome) {
  166. $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
  167. elseif ($CI) { Join-Path $PSScriptRoot '.dotnet' } `
  168. elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
  169. elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
  170. else { Join-Path $PSScriptRoot '.dotnet'}
  171. }
  172. if (!$LockFile) { $LockFile = Join-Path $Path 'korebuild-lock.txt' }
  173. if (!$Channel) { $Channel = 'master' }
  174. if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
  175. if ($PackageVersionPropsUrl) {
  176. $IntermediateDir = Join-Path $PSScriptRoot 'obj'
  177. $PropsFilePath = Join-Path $IntermediateDir 'external-dependencies.props'
  178. New-Item -ItemType Directory $IntermediateDir -ErrorAction Ignore | Out-Null
  179. Get-RemoteFile "${PackageVersionPropsUrl}${AccessTokenSuffix}" $PropsFilePath
  180. $MSBuildArguments += "-p:DotNetPackageVersionPropsPath=$PropsFilePath"
  181. }
  182. if ($RestoreSources) {
  183. $MSBuildArguments += "-p:DotNetAdditionalRestoreSources=$RestoreSources"
  184. }
  185. if ($AssetRootUrl) {
  186. $MSBuildArguments += "-p:DotNetAssetRootUrl=$AssetRootUrl"
  187. }
  188. if ($AccessTokenSuffix) {
  189. $MSBuildArguments += "-p:DotNetAssetRootAccessTokenSuffix=$AccessTokenSuffix"
  190. }
  191. if ($ProductBuildId) {
  192. $MSBuildArguments += "-p:DotNetProductBuildId=$ProductBuildId"
  193. }
  194. # Execute
  195. $korebuildPath = Get-KoreBuild
  196. Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
  197. try {
  198. Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI
  199. Invoke-KoreBuildCommand $Command @MSBuildArguments
  200. }
  201. finally {
  202. Remove-Module 'KoreBuild' -ErrorAction Ignore
  203. }