common.psm1 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. $ErrorActionPreference = 'Stop'
  2. function Assert-Git {
  3. if (!(Get-Command git -ErrorAction Ignore)) {
  4. Write-Error 'git is required to execute this script'
  5. exit 1
  6. }
  7. }
  8. function Invoke-Block([scriptblock]$cmd) {
  9. $cmd | Out-String | Write-Verbose
  10. & $cmd
  11. # Need to check both of these cases for errors as they represent different items
  12. # - $?: did the powershell script block throw an error
  13. # - $lastexitcode: did a windows command executed by the script block end in error
  14. if ((-not $?) -or ($lastexitcode -ne 0)) {
  15. if ($error -ne $null)
  16. {
  17. Write-Warning $error[0]
  18. }
  19. throw "Command failed to execute: $cmd"
  20. }
  21. }
  22. function Get-Submodules {
  23. param(
  24. [Parameter(Mandatory = $true)]
  25. [string]$RepoRoot,
  26. [switch]$Shipping
  27. )
  28. $moduleConfigFile = Join-Path $RepoRoot ".gitmodules"
  29. $submodules = @()
  30. [xml] $submoduleConfig = Get-Content "$RepoRoot/build/submodules.props"
  31. $repos = $submoduleConfig.Project.ItemGroup.Repository | % { $_.Include }
  32. Get-ChildItem "$RepoRoot/modules/*" -Directory `
  33. | ? { (-not $Shipping) -or $($repos -contains $($_.Name)) -or $_.Name -eq 'Templating' } `
  34. | % {
  35. Push-Location $_ | Out-Null
  36. Write-Verbose "Attempting to get submodule info for $_"
  37. if (Test-Path 'version.props') {
  38. [xml] $versionXml = Get-Content 'version.props'
  39. $versionPrefix = $versionXml.Project.PropertyGroup.VersionPrefix | select-object -first 1
  40. $versionSuffix = $versionXml.Project.PropertyGroup.VersionSuffix | select-object -first 1
  41. }
  42. else {
  43. $versionPrefix = ''
  44. $versionSuffix = ''
  45. }
  46. try {
  47. $data = [PSCustomObject] @{
  48. path = $_
  49. module = $_.Name
  50. commit = $(git rev-parse HEAD)
  51. newCommit = $null
  52. changed = $false
  53. remote = $(git config remote.origin.url)
  54. branch = $(git config -f $moduleConfigFile --get submodule.modules/$($_.Name).branch )
  55. versionPrefix = $versionPrefix
  56. versionSuffix = $versionSuffix
  57. }
  58. $submodules += $data
  59. }
  60. finally {
  61. Pop-Location | Out-Null
  62. }
  63. }
  64. return $submodules
  65. }
  66. function SaveXml([xml]$xml, [string]$path) {
  67. Write-Verbose "Saving to $path"
  68. $ErrorActionPreference = 'stop'
  69. $settings = New-Object System.XML.XmlWriterSettings
  70. $settings.OmitXmlDeclaration = $true
  71. $settings.Encoding = New-Object System.Text.UTF8Encoding( $true )
  72. $writer = [System.XML.XMLTextWriter]::Create($path, $settings)
  73. $xml.Save($writer)
  74. $writer.Close()
  75. }
  76. function LoadXml([string]$path) {
  77. Write-Verbose "Reading from $path"
  78. $ErrorActionPreference = 'stop'
  79. $obj = new-object xml
  80. $obj.PreserveWhitespace = $true
  81. $obj.Load($path)
  82. return $obj
  83. }
  84. function PackageIdVarName([string]$packageId) {
  85. $canonicalVarName = ''
  86. $upperCaseNext = $true
  87. for ($i = 0; $i -lt $packageId.Length; $i++) {
  88. $ch = $packageId[$i]
  89. if (-not [System.Char]::IsLetterOrDigit(($ch))) {
  90. $upperCaseNext = $true
  91. continue
  92. }
  93. if ($upperCaseNext) {
  94. $ch = [System.Char]::ToUpperInvariant($ch)
  95. $upperCaseNext = $false
  96. }
  97. $canonicalVarName += $ch
  98. }
  99. $canonicalVarName += "PackageVersion"
  100. return $canonicalVarName
  101. }
  102. function Ensure-Hub() {
  103. $tmpDir = "$PSScriptRoot\tmp"
  104. $zipDir = "$tmpDir\Hub"
  105. $hubLocation = "$zipDir\bin\hub.exe"
  106. if (-Not (Test-Path $hubLocation) ) {
  107. $source = "https://github.com/github/hub/releases/download/v2.3.0-pre9/hub-windows-amd64-2.3.0-pre9.zip"
  108. $zipLocation = "$tmpDir\hub.zip"
  109. mkdir -Path $tmpDir -ErrorAction Ignore | Out-Null
  110. Invoke-WebRequest -OutFile $zipLocation -Uri $source
  111. Expand-Archive -Path $zipLocation -DestinationPath $zipDir -Force
  112. if (-Not (Test-Path $hubLocation)) {
  113. throw "Hub couldn't be downloaded"
  114. }
  115. }
  116. return $hubLocation
  117. }
  118. function CreatePR(
  119. [string]$baseFork,
  120. [string]$headFork,
  121. [string]$baseBranch,
  122. [string]$destinationBranch,
  123. [string]$body,
  124. [string]$gitHubToken) {
  125. $hubLocation = Ensure-Hub
  126. Invoke-Block { git push -f https://[email protected]/$headFork/Universe.git $destinationBranch }
  127. & $hubLocation pull-request -f -b "${baseFork}:$baseBranch" -h "${headFork}:$destinationBranch" -m $body
  128. }
  129. function Set-GithubInfo(
  130. [string]$GitHubPassword,
  131. [string]$GitHubUser,
  132. [string]$GitHubEmail)
  133. {
  134. $Env:GITHUB_TOKEN = $GitHubPassword
  135. $Env:GITHUB_USER = $GitHubUser
  136. $Env:GITHUB_EMAIL = $GitHubEmail
  137. }
  138. function CommitUpdatedVersions(
  139. [hashtable]$updatedVars,
  140. [xml]$dependencies,
  141. [string]$depsPath)
  142. {
  143. $count = $updatedVars.Count
  144. if ($count -gt 0) {
  145. & git add build\dependencies.props
  146. $subject = "Updating external dependencies"
  147. $gitConfigArgs = @()
  148. if ($env:GITHUB_USER) {
  149. $gitConfigArgs += '-c',"user.name=$env:GITHUB_USER"
  150. }
  151. if ($env:GITHUB_EMAIL) {
  152. $gitConfigArgs += '-c',"user.email=$env:GITHUB_EMAIL"
  153. }
  154. Invoke-Block { & git @gitConfigArgs commit -m $subject } | Out-Null
  155. $body = "$subject`n`n"
  156. $body += "New versions:`n"
  157. foreach ($var in $updatedVars.GetEnumerator()) {
  158. $body += " $($var.Name)`n"
  159. }
  160. return $body
  161. }
  162. }
  163. function UpdateVersions([hashtable]$variables, [xml]$dependencies, [string]$depsPath) {
  164. $updatedVars = @{}
  165. foreach ($varName in ($variables.Keys | sort)) {
  166. $packageVersions = $variables[$varName]
  167. if ($packageVersions.Length -gt 1) {
  168. Write-Warning "Skipped $varName. Multiple version found. { $($packageVersions -join ', ') }."
  169. continue
  170. }
  171. $packageVersion = $packageVersions | Select-Object -First 1
  172. $depVarNode = $dependencies.SelectSingleNode("//PropertyGroup[`@Label=`"Package Versions: Auto`"]/$varName")
  173. if ($depVarNode -and $depVarNode.InnerText -ne $packageVersion) {
  174. $depVarNode.InnerText = $packageVersion
  175. Write-Host -f DarkGray " Updating $varName to $packageVersion"
  176. $updatedVars[$varName] = $packageVersion
  177. }
  178. elseif ($depVarNode) {
  179. Write-Host -f DarkBlue " Didn't update $varName to $packageVersion because it was $($depVarNode.InnerText)"
  180. }
  181. else {
  182. # This isn't a dependency we use
  183. }
  184. }
  185. if ($updatedVars.Count -gt 0) {
  186. Write-Host -f Cyan "Updating version variables in $depsPath"
  187. SaveXml $dependencies $depsPath
  188. }
  189. else {
  190. Write-Host -f Green "No changes found"
  191. }
  192. return $updatedVars
  193. }