Private/Get-AvmUpdateBranchName.ps1
|
function Get-AvmUpdateBranchName { <# .SYNOPSIS Computes a deterministic branch name for a set of AVM update items. .DESCRIPTION Hashes the sorted list of "<module>@<targetVersion>" pairs so that re-running the updater against the same pending updates always produces the same branch name, instead of a new timestamp-based branch on every run (Renovate/Dependabot-style idempotent PRs). Different pending updates (a different set of modules/versions) hash to a different branch name, which is what allows a stale PR to be detected and left alone while a new one is opened for the new update set. .PARAMETER BranchPrefix Branch name prefix (e.g. 'avm-updates'). .PARAMETER Items Plan items going into this branch. Each item must expose 'module' and 'latestStable' properties. .PARAMETER Suffix Optional extra path segment inserted between the prefix and the hash (e.g. 'low', 'review'), matching the existing '<prefix>/<bucket>/<hash>' branch layout used by github.splitLowFromHigherRisk. .OUTPUTS String branch name: '<prefix>[/<suffix>]/<12-char-hash>'. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [string]$BranchPrefix, [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]]$Items, [Parameter()] [string]$Suffix ) $pairs = @($Items | ForEach-Object { "$($_.module)@$($_.latestStable)" } | Sort-Object) $joined = $pairs -join '|' $sha256 = [System.Security.Cryptography.SHA256]::Create() try { $bytes = [System.Text.Encoding]::UTF8.GetBytes($joined) $hashBytes = $sha256.ComputeHash($bytes) $hash = -join ($hashBytes | ForEach-Object { $_.ToString('x2') }) } finally { $sha256.Dispose() } $shortHash = $hash.Substring(0, 12) if ($Suffix) { return "$BranchPrefix/$Suffix/$shortHash" } return "$BranchPrefix/$shortHash" } |