Modules/businessdev.ALbuild.Apps/Public/Install-BcAzureSignTool.ps1
|
function Install-BcAzureSignTool { <# .SYNOPSIS Ensures AzureSignTool is installed (as a .NET global tool) and on PATH. .DESCRIPTION Installs the 'AzureSignTool' dotnet global tool so the 'azuresigntool' command is available to Invoke-BcAppSigning on a build agent - reinstating the auto-install behaviour of ALbuild V1. Idempotent: when AzureSignTool is already on PATH it does nothing (unless -Force). Requires the .NET SDK ('dotnet'). After installing it adds the global-tools folder (~/.dotnet/tools) to PATH for the current session so the freshly installed 'azuresigntool' is immediately resolvable. .PARAMETER PackageId The dotnet tool package id. Default 'AzureSignTool'. .PARAMETER Version Optional specific version to pin; otherwise the latest is installed. .PARAMETER Force Reinstall/update even when AzureSignTool is already available. .PARAMETER DotNetExecutable The .NET CLI executable. Default 'dotnet'. .EXAMPLE Install-BcAzureSignTool .OUTPUTS PSCustomObject: Installed (bool), Path, Version. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject])] param( [string] $PackageId = 'AzureSignTool', [string] $Version, [switch] $Force, [string] $DotNetExecutable = 'dotnet' ) # Make the per-user global-tools folder resolvable for this session (it is not always on PATH on # a fresh agent right after install). $toolsDir = if ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet\tools' } else { Join-Path $HOME '.dotnet/tools' } $ensurePath = { if ((Test-Path -LiteralPath $toolsDir) -and (($env:PATH -split [System.IO.Path]::PathSeparator) -notcontains $toolsDir)) { $env:PATH = $toolsDir + [System.IO.Path]::PathSeparator + $env:PATH } } & $ensurePath $existing = Get-Command -Name 'azuresigntool' -ErrorAction SilentlyContinue | Select-Object -First 1 if ($existing -and -not $Force) { Write-ALbuildLog "AzureSignTool already available: $($existing.Source)." return [PSCustomObject]@{ Installed = $false; Path = $existing.Source; Version = $existing.Version } } $dotnet = Get-Command -Name $DotNetExecutable -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $dotnet) { throw "The .NET SDK ('$DotNetExecutable') is required to install AzureSignTool. Install the .NET SDK, or install '$PackageId' manually and pass -SignToolPath to Invoke-BcAppSigning." } if ($PSCmdlet.ShouldProcess($PackageId, 'Install AzureSignTool (dotnet global tool)')) { $verb = if ($Force) { 'update' } else { 'install' } $installArgs = @('tool', $verb, '--global', $PackageId) if ($Version) { $installArgs += @('--version', $Version) } # Exit 1 with "already installed" is benign (the tool exists; we just need it on PATH). $result = Invoke-ALbuildProcess -FilePath $dotnet.Source -Arguments $installArgs -PassThru -SuccessExitCodes @(0, 1) $combined = "$($result.StdOut)`n$($result.StdErr)" if (-not $result.Success -and ($combined -notmatch 'already installed|is up to date')) { throw "Failed to install AzureSignTool ('$PackageId'): $($combined.Trim())" } Write-ALbuildLog -Level Success "AzureSignTool '$PackageId' is installed." } & $ensurePath $tool = Get-Command -Name 'azuresigntool' -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $tool) { throw "AzureSignTool was installed but its command was not found on PATH (expected under '$toolsDir')." } return [PSCustomObject]@{ Installed = $true; Path = $tool.Source; Version = $tool.Version } } |