From a01aee7e9c92b64017c71c740668ab688c42a26f Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 25 Oct 2017 11:39:53 -0700 Subject: [PATCH] Add scripts to auto-update build tools and submodules (#618) * Add a script to auto-update submodules * Add VSCode settings * Add script to update the build tools version --- .gitignore | 1 - .vscode/extensions.json | 7 +++ .vscode/launch.json | 11 ++++ build/dependencies.props | 12 +++- korebuild-lock.txt | 2 + korebuild.json | 4 ++ scripts/UpdateBuildTools.ps1 | 90 ++++++++++++++++++++++++++ scripts/UpdateSubmodules.ps1 | 118 +++++++++++++++++++++++++++++++++++ scripts/common.psm1 | 17 +++++ 9 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 korebuild-lock.txt create mode 100644 korebuild.json create mode 100755 scripts/UpdateBuildTools.ps1 create mode 100755 scripts/UpdateSubmodules.ps1 create mode 100644 scripts/common.psm1 diff --git a/.gitignore b/.gitignore index 9efbb61c7e..5e36a0b23c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,4 @@ node_modules .r .deps global.json -korebuild-lock.txt *.binlog diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..a869097c1c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "ms-vscode.csharp", + "ms-vscode.PowerShell", + "EditorConfig.EditorConfig" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..514e3339c0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "PowerShell", + "request": "launch", + "name": "ps: Interactive Session", + "cwd": "${workspaceRoot}" + } + ] +} diff --git a/build/dependencies.props b/build/dependencies.props index 693dbc81aa..c45a4ec612 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,4 +1,4 @@ - + @@ -93,6 +93,16 @@ + + + https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json + + + + + + + https://dotnet.myget.org/F/aspnetcoremodule/api/v3/index.json diff --git a/korebuild-lock.txt b/korebuild-lock.txt new file mode 100644 index 0000000000..4bdce1993f --- /dev/null +++ b/korebuild-lock.txt @@ -0,0 +1,2 @@ +version:2.1.0-preview1-15540 +commithash:f9a4508dd777e091f39ec57a53c4f514eaca8c39 diff --git a/korebuild.json b/korebuild.json new file mode 100644 index 0000000000..bd5d51a51b --- /dev/null +++ b/korebuild.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev" +} diff --git a/scripts/UpdateBuildTools.ps1 b/scripts/UpdateBuildTools.ps1 new file mode 100755 index 0000000000..0c16b148b2 --- /dev/null +++ b/scripts/UpdateBuildTools.ps1 @@ -0,0 +1,90 @@ +#!/usr/bin/env powershell + +<# +.SYNOPSIS + Updates the build tools version and generates a commit message with the list of changes +.PARAMETER RepoRoot + The directory containing the repo +.PARAMETER GitCommitArgs + Additional arguments to pass into git-commit +.PARAMETER NoCommit + Make changes without executing git-commit +.PARAMETER Force + Specified this to make a commit with any changes +#> +[cmdletbinding(SupportsShouldProcess = $true)] +param( + [string]$RepoRoot, + [string[]]$GitCommitArgs = @(), + [switch]$NoCommit, + [switch]$Force +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2 + +if (-not $RepoRoot) { + $RepoRoot = Resolve-Path "$PSScriptRoot\.." +} + +Import-Module "$PSScriptRoot/common.psm1" -Scope Local -Force + +function Get-KoreBuildVersion { + $lockFile = "$RepoRoot/korebuild-lock.txt" + if (!(Test-Path $lockFile)) { + return '' + } + $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 + if (!$version) { + Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'" + } + $version = $version.TrimStart('version:').Trim() + return $version +} + +Push-Location $RepoRoot +try { + Assert-Git + + $oldVersion = Get-KoreBuildVersion + + # Executes a command that no-ops. The only thing we really need is the updated version of korebuild-lock.txt + & "$RepoRoot/run.ps1" -Update --help | Out-Null + + $newVersion = Get-KoreBuildVersion + + if ($oldVersion -eq $newVersion) { + Write-Host -ForegroundColor Magenta 'No changes to build tools' + exit 0 + } + + $deps = Get-Content "$RepoRoot/build/dependencies.props" ` + | % { + if ($_ -like '**') { + " $newVersion" + } else { + $_ + } + } + $deps | Set-Content -Encoding UTF8 "$RepoRoot/build/dependencies.props" + + Invoke-Block { git add "$RepoRoot/korebuild-lock.txt" } + Invoke-Block { git add "$RepoRoot/build/dependencies.props" } + + $shortMessage = "Updating BuildTools from $oldVersion to $newVersion" + # add this to the commit message to make it possible to filter commit triggers based on message + $message = "$shortMessage`n`n[auto-updated: buildtools]" + + if (-not $NoCommit -and ($Force -or ($PSCmdlet.ShouldContinue($shortMessage, 'Create a new commit with these changes?')))) { + Invoke-Block { git commit -m $message @GitCommitArgs } + } + else { + # If composing this script with others, return the message that would have been used + return @{ + message = $message + } + } +} +finally { + Pop-Location +} diff --git a/scripts/UpdateSubmodules.ps1 b/scripts/UpdateSubmodules.ps1 new file mode 100755 index 0000000000..0695f198a0 --- /dev/null +++ b/scripts/UpdateSubmodules.ps1 @@ -0,0 +1,118 @@ +#!/usr/bin/env powershell + +<# +.SYNOPSIS + Updates git submodules and generates a commit message with the list of changes +.PARAMETER GitCommitArgs + Additional arguments to pass into git-commit +.PARAMETER NoCommit + Make changes without executing git-commit +.PARAMETER Force + Specified this to make a commit with any changes +#> +[cmdletbinding(SupportsShouldProcess = $true)] +param( + [string[]]$GitCommitArgs = @(), + [switch]$NoCommit, + [switch]$Force +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2 + +$RepoRoot = Resolve-Path "$PSScriptRoot\.." + +Import-Module "$PSScriptRoot/common.psm1" -Scope Local -Force + +function Get-GitChanges([string]$Path) { + Write-Verbose "git diff --cached --quiet $Path" + & git diff --cached --quiet $Path | Out-Null + if ($LastExitCode -ne 0) { + return $true + } + Write-Verbose "git diff --quiet $Path" + & git diff --quiet $Path | Out-Null + return $LastExitCode -ne 0 +} + +try { + Assert-Git + + if (Get-GitChanges "$RepoRoot/modules") { + Write-Error "$RepoRoot/modules is in an unclean state. Reset submodules first by running ``git submodule update``" + exit 1 + } + + Invoke-Block { & git submodule update --init } + + $submodules = @() + + Get-ChildItem "$RepoRoot/modules/*" -Directory | % { + Push-Location $_ + try { + $data = @{ + path = $_ + module = $_.Name + commit = $(git rev-parse HEAD) + newCommit = $null + changed = $false + } + Write-Verbose "$($data.module) is at $($data.commit)" + $submodules += $data + } + finally { + Pop-Location + } + } + + Write-Verbose "git submodule update --remote" + Invoke-Block { & git submodule update --remote } + + $changes = $submodules ` + | % { + Push-Location $_.path + try { + $newCommit = $(git rev-parse HEAD) + $_.newCommit = $newCommit + if ($newCommit -ne $_.commit) { + $_.changed = $true + Write-Verbose "$($_.module) updated to $($_.newCommit)" + } + else { + Write-Verbose "$($_.module) did not change" + } + return $_ + } + finally { + Pop-Location + } + } ` + | ? { $_.changed } ` + | % { "$($_.module) to $($_.newCommit.Substring(0, 8))" } + + $submodules ` + | ? { $_.changed } ` + | % { + Invoke-Block { & git add $_.path } + } + + if ($changes) { + $shortMessage = "Updating submodule(s) $( $changes -join ' ,' )" + # add this to the commit message to make it possible to filter commit triggers based on message + $message = "$shortMessage`n`n[auto-updated: submodules]" + if (-not $NoCommit -and ($Force -or ($PSCmdlet.ShouldContinue($shortMessage, 'Create a new commit with these changes?')))) { + Invoke-Block { & git commit -m $message @GitCommitArgs } + } else { + # If composing this script with others, return the message that would have been used + return @{ + message = $message + } + } + } + else { + Write-Host -ForegroundColor Magenta 'No changes detected in git submodules' + } +} +finally { + Pop-Location +} diff --git a/scripts/common.psm1 b/scripts/common.psm1 new file mode 100644 index 0000000000..9606f327a2 --- /dev/null +++ b/scripts/common.psm1 @@ -0,0 +1,17 @@ +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) { + & $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)) { + throw "Command failed to execute: $cmd" + } +}