aspnetcore/scripts/UpdateSubmodules.ps1

117 lines
3.6 KiB
PowerShell
Executable File

#!/usr/bin/env pwsh
<#
.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\.."
$ModuleDirectory = Join-Path $RepoRoot "modules"
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
}
Push-Location $RepoRoot | Out-Null
try {
Assert-Git
Write-Host "Checking that submodules are in a clean state first..."
if (Get-GitChanges $ModuleDirectory) {
Write-Error "$RepoRoot/modules is in an unclean state. Reset submodules first by running ``git submodule update``"
exit 1
}
$submodules = Get-Submodules $RepoRoot -Verbose:$VerbosePreference
foreach ($submodule in $submodules) {
$submodulePath = $submodule.path
Write-Host "Updating $submodulePath"
$vcs_name = "BUILD_VCS_NUMBER_" + $submodule.module
$newCommit = [environment]::GetEnvironmentVariable($vcs_name)
if (-not $newCommit) {
Write-Warning "TeamCity env variable '$vcs_name' not found. Pulling the latest submodule branch instead"
Invoke-Block { & git submodule update --remote $submodulePath }
Push-Location $submodulePath | Out-Null
try {
$newCommit = $(git rev-parse HEAD)
}
finally {
Pop-Location | Out-Null
}
}
else {
Push-Location $submodulePath | Out-Null
try {
Invoke-Block { & git checkout $newCommit }
}
finally {
Pop-Location | Out-Null
}
}
$submodule.newCommit = $newCommit
if ($newCommit -ne $submodule.commit) {
$submodule.changed = $true
Write-Host -ForegroundColor Cyan "`t=> $($submodule.module) updated to $($submodule.newCommit)"
}
else {
Write-Host -ForegroundColor Magenta "`t$($submodule.module) did not change"
}
}
$changes = $submodules `
| ? { $_.changed } `
| % {
Invoke-Block { & git add $_.path }
"$($_.module) => $($_.newCommit)"
}
if ($changes) {
$shortMessage = "Updating submodule(s) `n`n$( $changes -join "`n" )"
# 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
}