Pipelines/Install-BcContainerHelper.ps1

function Install-BcContainerHelper {
    Param(
        [string] $bcContainerHelperVersion = "",
        [string] $genericImageName = ""
    )

    function Expand-7zipArchive {
        Param (
            [Parameter(Mandatory = $true)]
            [string] $Path,
            [string] $DestinationPath
        )

        $7zipPath = "$env:ProgramFiles\7-Zip\7z.exe"

        $use7zip = $false
        if (Test-Path -Path $7zipPath -PathType Leaf) {
            try {
                $use7zip = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($7zipPath).FileMajorPart -ge 19
            }
            catch {
                $use7zip = $false
            }
        }

        if ($use7zip) {
            OutputDebug -message "Using 7zip"
            Set-Alias -Name 7z -Value $7zipPath
            $command = '7z x "{0}" -o"{1}" -aoa -r' -f $Path, $DestinationPath
            Invoke-Expression -Command $command | Out-Null
        }
        else {
            OutputDebug -message "Using Expand-Archive"
            Expand-Archive -Path $Path -DestinationPath "$DestinationPath" -Force
        }
    }

    function OutputError {
        Param(
            [string] $message
        )

        if ($runningLocal) {
            throw $message
        }
        else {
            Write-Host "::Error::$($message.Replace("`r",'').Replace("`n",' '))"
            $host.SetShouldExit(1)
        }
    }

    function OutputWarning {
        Param(
            [string] $message
        )

        if ($runningLocal) {
            Write-Host -ForegroundColor Yellow "WARNING: $message"
        }
        else {
            Write-Host "::Warning::$message"
        }
    }

    function OutputNotice {
        Param(
            [string] $message
        )

        if ($runningLocal) {
            Write-Host $message
        }
        else {
            Write-Host "::Notice::$message"
        }
    }

    function OutputDebug {
        Param(
            [string] $message
        )

        if ($runningLocal) {
            Write-Host $message
        }
        else {
            Write-Host "::Debug::$message"
        }
    }

    function GetBcContainerHelperPath([string] $bcContainerHelperVersion) {
        if ("$env:BcContainerHelperPath" -and (Test-Path -Path $env:BcContainerHelperPath -PathType Leaf)) {
            return $env:BcContainerHelperPath
        }

        if ($bcContainerHelperVersion -eq 'None') {
            $module = Get-Module BcContainerHelper
            if (-not $module) {
                OutputError "When setting BcContainerHelperVersion to none, you need to ensure that BcContainerHelper is installed on the build agent"
            }
            $bcContainerHelperPath = Join-Path (Split-Path $module.Path -parent) "BcContainerHelper.ps1" -Resolve
        }
        else {
            $bcContainerHelperRootFolder = 'C:\ProgramData\BcContainerHelper'
            if (!(Test-Path $bcContainerHelperRootFolder)) {
                New-Item -Path $bcContainerHelperRootFolder -ItemType Directory | Out-Null
            }

            $webclient = New-Object System.Net.WebClient
            $tempName = Join-Path $bcContainerHelperRootFolder ([Guid]::NewGuid().ToString())
            if ($bcContainerHelperVersion -eq "dev") {
                # For backwards compatibility, use preview when dev is specified
                $bcContainerHelperVersion = 'preview'
            }
            Write-Host "Downloading BcContainerHelper $bcContainerHelperVersion version from Blob Storage"
            $webclient.DownloadFile("https://bccontainerhelper.blob.core.windows.net/public/$($bcContainerHelperVersion).zip", "$tempName.zip")

            Expand-7zipArchive -Path "$tempName.zip" -DestinationPath $tempName
            $bcContainerHelperPath = (Get-Item -Path (Join-Path $tempName "*\BcContainerHelper.ps1")).FullName
            Remove-Item -Path "$tempName.zip" -ErrorAction SilentlyContinue

            # Check whether the version is already available in the cache
            $version = ([System.IO.File]::ReadAllText((Join-Path $tempName 'BcContainerHelper/Version.txt'), [System.Text.Encoding]::UTF8)).Trim()
            $cacheFolder = Join-Path $bcContainerHelperRootFolder $version
            # To avoid two agents on the same machine downloading the same version at the same time, use a mutex
            $buildMutexName = "DownloadAndImportBcContainerHelper"
            $buildMutex = New-Object System.Threading.Mutex($false, $buildMutexName)
            try {
                try {
                    if (!$buildMutex.WaitOne(1000)) {
                        Write-Host "Waiting for other process loading BcContainerHelper"
                        $buildMutex.WaitOne() | Out-Null
                        Write-Host "Other process completed loading BcContainerHelper"
                    }
                }
                catch [System.Threading.AbandonedMutexException] {
                    Write-Host "Other process terminated abnormally"
                }
                if (Test-Path $cacheFolder) {
                    Remove-Item $tempName -Recurse -Force
                }
                else {
                    Rename-Item -Path $tempName -NewName $version
                }
            }
            finally {
                $buildMutex.ReleaseMutex()
            }
            $bcContainerHelperPath = Join-Path $cacheFolder "BcContainerHelper/BcContainerHelper.ps1"
        }
        $env:BcContainerHelperPath = $bcContainerHelperPath
        if ($ENV:GITHUB_ENV) {
            Add-Content -Encoding UTF8 -Path $ENV:GITHUB_ENV "BcContainerHelperPath=$bcContainerHelperPath"
        }
        return $bcContainerHelperPath
    }

    Write-Host "Installing BcContainerHelper version $bcContainerHelperVersion"

    if ($bcContainerHelperVersion -eq '') {
        $bcContainerHelperVersion = "latest"
    }

    $bcContainerHelperPath = GetBcContainerHelperPath -bcContainerHelperVersion $bcContainerHelperVersion
    $params = @{ "ExportTelemetryFunctions" = $true }

    Write-Host "Import from $bcContainerHelperPath"
    . $bcContainerHelperPath @params

    # if (Get-Module -ListAvailable -Name BcContainerHelper) {
    # $installedVersion = (Get-InstalledModule -Name BcContainerHelper).Version
    # if ($bcContainerHelperVersion -eq "latest") {
    # $latestVersion = (Find-Module -Name BcContainerHelper).Version
    # if ($installedVersion -eq $latestVersion) {
    # Write-Host "The latest version ($latestVersion) of BcContainerHelper module is already installed"
    # } else {
    # Write-Host "Installing the latest version of BcContainerHelper"
    # Install-Module -Name BcContainerHelper -Force
    # }
    # } elseif ($installedVersion -eq $bcContainerHelperVersion) {
    # Write-Host "Version $bcContainerHelperVersion of BcContainerHelper module is already installed"
    # } else {
    # Write-Host "Installing BcContainerHelper version $bcContainerHelperVersion"
    # Install-Module -Name BcContainerHelper -RequiredVersion $bcContainerHelperVersion -Force
    # Import-Module -Name BcContainerHelper -RequiredVersion $bcContainerHelperVersion
    # }
    # } else {
    # Write-Host "BcContainerHelper module is not installed"
    # if ($bcContainerHelperVersion -eq "latest") {
    # Write-Host "Installing the latest version of BcContainerHelper"
    # Install-Module -Name BcContainerHelper -Force
    # } else {
    # Write-Host "Installing BcContainerHelper version $bcContainerHelperVersion"
    # Install-Module -Name BcContainerHelper -RequiredVersion $bcContainerHelperVersion -Force
    # }
    # }

    if ($genericImageName) {
        $bcContainerHelperConfig.genericImageName = $genericImageName
    }
}