315 строки
9.1 KiB
PowerShell
315 строки
9.1 KiB
PowerShell
$ErrorActionPreference = 'Stop'
|
|
# Update the default TLS support to 1.2
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
|
|
function Assert-Git {
|
|
if (!(Get-Command git -ErrorAction Ignore)) {
|
|
Write-Error 'git is required to execute this script'
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
function Invoke-Block([scriptblock]$cmd, [string]$WorkingDir = $null) {
|
|
if ($WorkingDir) {
|
|
Push-Location $WorkingDir
|
|
}
|
|
|
|
try {
|
|
|
|
$cmd | Out-String | Write-Verbose
|
|
& $cmd
|
|
|
|
# Need to check both of these cases for errors as they represent different items
|
|
# - $?: did the powershell script block throw an error
|
|
# - $lastexitcode: did a windows command executed by the script block end in error
|
|
if ((-not $?) -or ($lastexitcode -ne 0)) {
|
|
if ($error -ne $null)
|
|
{
|
|
Write-Warning $error[0]
|
|
}
|
|
throw "Command failed to execute: $cmd"
|
|
}
|
|
}
|
|
finally {
|
|
if ($WorkingDir) {
|
|
Pop-Location
|
|
}
|
|
}
|
|
}
|
|
|
|
function Get-Submodules {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$RepoRoot,
|
|
[switch]$Shipping
|
|
)
|
|
|
|
$moduleConfigFile = Join-Path $RepoRoot ".gitmodules"
|
|
$submodules = @()
|
|
|
|
[xml] $submoduleConfig = Get-Content "$RepoRoot/build/submodules.props"
|
|
$repos = $submoduleConfig.Project.ItemGroup.Repository | % { $_.Include }
|
|
|
|
Get-ChildItem "$RepoRoot/modules/*" -Directory `
|
|
| ? { (-not $Shipping) -or $($repos -contains $($_.Name)) -or $_.Name -eq 'Templating' } `
|
|
| % {
|
|
Push-Location $_ | Out-Null
|
|
Write-Verbose "Attempting to get submodule info for $_"
|
|
|
|
if (Test-Path 'version.props') {
|
|
[xml] $versionXml = Get-Content 'version.props'
|
|
$versionPrefix = $versionXml.Project.PropertyGroup.VersionPrefix | select-object -first 1
|
|
$versionSuffix = $versionXml.Project.PropertyGroup.VersionSuffix | select-object -first 1
|
|
}
|
|
else {
|
|
$versionPrefix = ''
|
|
$versionSuffix = ''
|
|
}
|
|
|
|
try {
|
|
$data = [PSCustomObject] @{
|
|
path = $_
|
|
module = $_.Name
|
|
commit = $(git rev-parse HEAD)
|
|
newCommit = $null
|
|
changed = $false
|
|
remote = $(git config remote.origin.url)
|
|
branch = $(git config -f $moduleConfigFile --get submodule.modules/$($_.Name).branch )
|
|
versionPrefix = $versionPrefix
|
|
versionSuffix = $versionSuffix
|
|
}
|
|
|
|
$submodules += $data
|
|
}
|
|
finally {
|
|
Pop-Location | Out-Null
|
|
}
|
|
}
|
|
|
|
return $submodules
|
|
}
|
|
|
|
function SaveXml([xml]$xml, [string]$path) {
|
|
Write-Verbose "Saving to $path"
|
|
$ErrorActionPreference = 'stop'
|
|
|
|
$settings = New-Object System.XML.XmlWriterSettings
|
|
$settings.OmitXmlDeclaration = $true
|
|
$settings.Encoding = New-Object System.Text.UTF8Encoding( $true )
|
|
$writer = [System.XML.XMLTextWriter]::Create($path, $settings)
|
|
$xml.Save($writer)
|
|
$writer.Close()
|
|
}
|
|
|
|
function LoadXml([string]$path) {
|
|
Write-Verbose "Reading from $path"
|
|
|
|
$ErrorActionPreference = 'stop'
|
|
$obj = new-object xml
|
|
$obj.PreserveWhitespace = $true
|
|
$obj.Load($path)
|
|
return $obj
|
|
}
|
|
|
|
function PackageIdVarName([string]$packageId) {
|
|
$canonicalVarName = ''
|
|
$upperCaseNext = $true
|
|
for ($i = 0; $i -lt $packageId.Length; $i++) {
|
|
$ch = $packageId[$i]
|
|
if (-not [System.Char]::IsLetterOrDigit(($ch))) {
|
|
$upperCaseNext = $true
|
|
continue
|
|
}
|
|
if ($upperCaseNext) {
|
|
$ch = [System.Char]::ToUpperInvariant($ch)
|
|
$upperCaseNext = $false
|
|
}
|
|
$canonicalVarName += $ch
|
|
}
|
|
$canonicalVarName += "PackageVersion"
|
|
return $canonicalVarName
|
|
}
|
|
|
|
function Ensure-Hub() {
|
|
$tmpDir = "$PSScriptRoot\tmp"
|
|
$zipDir = "$tmpDir\Hub"
|
|
$hubLocation = "$zipDir\bin\hub.exe"
|
|
|
|
if (-Not (Test-Path $hubLocation) ) {
|
|
$source = "https://github.com/github/hub/releases/download/v2.3.0-pre9/hub-windows-amd64-2.3.0-pre9.zip"
|
|
$zipLocation = "$tmpDir\hub.zip"
|
|
|
|
mkdir -Path $tmpDir -ErrorAction Ignore | Out-Null
|
|
|
|
Invoke-WebRequest -OutFile $zipLocation -Uri $source
|
|
|
|
Expand-Archive -Path $zipLocation -DestinationPath $zipDir -Force
|
|
if (-Not (Test-Path $hubLocation)) {
|
|
throw "Hub couldn't be downloaded"
|
|
}
|
|
}
|
|
|
|
return $hubLocation
|
|
}
|
|
|
|
function CreatePR(
|
|
[string]$baseFork,
|
|
[string]$headFork,
|
|
[string]$baseBranch,
|
|
[string]$destinationBranch,
|
|
[string]$body,
|
|
[string]$gitHubToken) {
|
|
$hubLocation = Ensure-Hub
|
|
|
|
Invoke-Block { git push -f https://$gitHubToken@github.com/$headFork/Universe.git $destinationBranch }
|
|
& $hubLocation pull-request -f -b "${baseFork}:$baseBranch" -h "${headFork}:$destinationBranch" -m $body
|
|
}
|
|
|
|
function Set-GithubInfo(
|
|
[string]$GitHubPassword,
|
|
[string]$GitHubUser,
|
|
[string]$GitHubEmail)
|
|
{
|
|
$Env:GITHUB_TOKEN = $GitHubPassword
|
|
$Env:GITHUB_USER = $GitHubUser
|
|
$Env:GITHUB_EMAIL = $GitHubEmail
|
|
}
|
|
function CommitUpdatedVersions(
|
|
[hashtable]$updatedVars,
|
|
[xml]$dependencies,
|
|
[string]$depsPath,
|
|
[string]$subject = 'Updating external dependencies')
|
|
{
|
|
$count = $updatedVars.Count
|
|
if ($count -gt 0) {
|
|
& git add build\dependencies.props
|
|
|
|
$gitConfigArgs = @()
|
|
if ($env:GITHUB_USER) {
|
|
$gitConfigArgs += '-c',"user.name=$env:GITHUB_USER"
|
|
}
|
|
|
|
if ($env:GITHUB_EMAIL) {
|
|
$gitConfigArgs += '-c',"user.email=$env:GITHUB_EMAIL"
|
|
}
|
|
|
|
Invoke-Block { & git @gitConfigArgs commit -m $subject } | Out-Null
|
|
|
|
$body = "$subject`n`n"
|
|
|
|
$body += "New versions:`n"
|
|
|
|
foreach ($var in $updatedVars.GetEnumerator()) {
|
|
$body += " $($var.Name)`n"
|
|
}
|
|
|
|
return $body
|
|
}
|
|
}
|
|
|
|
function UpdateVersions([hashtable]$variables, [xml]$dependencies, [string]$depsPath) {
|
|
$updatedVars = @{}
|
|
|
|
foreach ($varName in ($variables.Keys | sort)) {
|
|
$packageVersions = $variables[$varName]
|
|
if ($packageVersions.Length -gt 1) {
|
|
Write-Warning "Skipped $varName. Multiple version found. { $($packageVersions -join ', ') }."
|
|
continue
|
|
}
|
|
|
|
$packageVersion = $packageVersions | Select-Object -First 1
|
|
|
|
$depVarNode = $dependencies.SelectSingleNode("//PropertyGroup[`@Label=`"Package Versions: Auto`"]/$varName")
|
|
if ($depVarNode -and $depVarNode.InnerText -ne $packageVersion) {
|
|
$depVarNode.InnerText = $packageVersion
|
|
Write-Host -f DarkGray " Updating $varName to $packageVersion"
|
|
$updatedVars[$varName] = $packageVersion
|
|
}
|
|
elseif ($depVarNode) {
|
|
Write-Host -f DarkBlue " Didn't update $varName to $packageVersion because it was $($depVarNode.InnerText)"
|
|
}
|
|
else {
|
|
# This isn't a dependency we use
|
|
}
|
|
}
|
|
|
|
if ($updatedVars.Count -gt 0) {
|
|
Write-Host -f Cyan "Updating version variables in $depsPath"
|
|
SaveXml $dependencies $depsPath
|
|
}
|
|
else {
|
|
Write-Host -f Green "No changes found"
|
|
}
|
|
|
|
return $updatedVars
|
|
}
|
|
|
|
function Get-MSBuildPath {
|
|
param(
|
|
[switch]$Prerelease,
|
|
[string[]]$Requires
|
|
)
|
|
|
|
$vsInstallDir = $null
|
|
if ($env:VSINSTALLDIR -and (Test-Path $env:VSINSTALLDIR)) {
|
|
$vsInstallDir = $env:VSINSTALLDIR
|
|
Write-Verbose "Using VSINSTALLDIR=$vsInstallDir"
|
|
}
|
|
else {
|
|
$vswhere = "${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe"
|
|
Write-Verbose "Using vswhere.exe from $vswhere"
|
|
|
|
if (-not (Test-Path $vswhere)) {
|
|
Write-Error "Missing prerequisite: could not find vswhere"
|
|
}
|
|
|
|
[string[]] $vswhereArgs = @()
|
|
|
|
if ($Prerelease) {
|
|
$vswhereArgs += '-prerelease'
|
|
}
|
|
|
|
if ($Requires) {
|
|
foreach ($r in $Requires) {
|
|
$vswhereArgs += '-requires', $r
|
|
}
|
|
}
|
|
|
|
$installs = & $vswhere -format json -version '[15.0, 16.0)' -latest -products * @vswhereArgs | ConvertFrom-Json
|
|
if (!$installs) {
|
|
Write-Error "Missing prerequisite: could not find any installations of Visual Studio"
|
|
}
|
|
|
|
$vs = $installs | Select-Object -First 1
|
|
$vsInstallDir = $vs.installationPath
|
|
Write-Host "Using $($vs.displayName)"
|
|
}
|
|
|
|
$msbuild = Join-Path $vsInstallDir 'MSBuild/15.0/bin/msbuild.exe'
|
|
if (!(Test-Path $msbuild)) {
|
|
Write-Error "Missing prerequisite: could not find msbuild.exe"
|
|
}
|
|
return $msbuild
|
|
}
|
|
|
|
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
|
if ($RemotePath -notlike 'http*') {
|
|
Copy-Item $RemotePath $LocalPath
|
|
return
|
|
}
|
|
|
|
$retries = 10
|
|
while ($retries -gt 0) {
|
|
$retries -= 1
|
|
try {
|
|
Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
|
|
return
|
|
}
|
|
catch {
|
|
Write-Verbose "Request failed. $retries retries remaining"
|
|
}
|
|
}
|
|
|
|
Write-Error "Download failed: '$RemotePath'."
|
|
}
|