mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
514 lines
16 KiB
PowerShell
514 lines
16 KiB
PowerShell
##
|
|
## Azure DevOps CI build tools
|
|
## [Add appropriate copyright]
|
|
##
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$repoRoot = Get-RepositoryRoot
|
|
$script:messageFile = join-path $repoRoot.FullName "BuildMessage.log"
|
|
|
|
function Write-BuildMessage
|
|
{
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string] $Message,
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
[string] $Category = "Information"
|
|
)
|
|
|
|
# Write message to verbose stream.
|
|
Write-Verbose -Verbose -Message "$Category--$Message"
|
|
|
|
# Write it to the log file, if present.
|
|
if (-not ([string]::IsNullOrEmpty($script:messageFile)))
|
|
{
|
|
Add-Content -Path $script:messageFile -Value "$Category--$Message"
|
|
}
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Implements the AzDO build package step
|
|
#>
|
|
function Invoke-AzDOBuild
|
|
{
|
|
Start-OpenSSHBuild -Configuration Release -NativeHostArch x64 -Verbose
|
|
Start-OpenSSHBuild -Configuration Release -NativeHostArch x86 -Verbose
|
|
Write-BuildMessage -Message "OpenSSH binaries build success!" -Category Information
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Deploy all required files to a location and install the binaries
|
|
#>
|
|
function Install-OpenSSH
|
|
{
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$SourceDir,
|
|
|
|
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
|
|
)
|
|
|
|
UnInstall-OpenSSH -OpenSSHDir $OpenSSHDir
|
|
|
|
if (! (Test-Path -Path $OpenSSHDir)) {
|
|
$null = New-Item -Path $OpenSSHDir -ItemType Directory -Force
|
|
}
|
|
|
|
Copy-Item -Path "$SourceDir/*" -Destination $OpenSSHDir -Recurse -Force -Verbose
|
|
|
|
Push-Location $OpenSSHDir
|
|
|
|
try
|
|
{
|
|
& "$OpenSSHDir\install-sshd.ps1"
|
|
|
|
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
|
|
$newMachineEnvironmentPath = $machinePath
|
|
if (-not ($machinePath.ToLower().Contains($OpenSSHDir.ToLower())))
|
|
{
|
|
$newMachineEnvironmentPath = "$OpenSSHDir;$newMachineEnvironmentPath"
|
|
$env:Path = "$OpenSSHDir;$env:Path"
|
|
}
|
|
|
|
# Update machine environment path
|
|
if ($newMachineEnvironmentPath -ne $machinePath)
|
|
{
|
|
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
|
|
}
|
|
|
|
Start-Service -Name sshd
|
|
Start-Service -Name ssh-agent
|
|
}
|
|
finally
|
|
{
|
|
Pop-Location
|
|
}
|
|
|
|
Write-BuildMessage -Message "OpenSSH installed!" -Category Information
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Uninstalled sshd
|
|
#>
|
|
function UnInstall-OpenSSH
|
|
{
|
|
[CmdletBinding()]
|
|
param (
|
|
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
|
|
)
|
|
|
|
if (-not (Test-Path $OpenSSHDir -PathType Container))
|
|
{
|
|
return
|
|
}
|
|
|
|
Push-Location $OpenSSHDir
|
|
|
|
try
|
|
{
|
|
if ((Get-Service ssh-agent -ErrorAction SilentlyContinue) -ne $null) {
|
|
Stop-Service ssh-agent -Force
|
|
}
|
|
& "$OpenSSHDir\uninstall-sshd.ps1"
|
|
|
|
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
|
|
$newMachineEnvironmentPath = $machinePath
|
|
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
|
|
{
|
|
$newMachineEnvironmentPath = $newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
|
|
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
|
|
}
|
|
|
|
if ($newMachineEnvironmentPath -ne $machinePath)
|
|
{
|
|
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Pop-Location
|
|
}
|
|
|
|
Remove-Item -Path $OpenSSHDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
#
|
|
# Install CygWin from Chocolatey and fix up install directory if needed.
|
|
#
|
|
function Install-CygWin
|
|
{
|
|
param (
|
|
[string] $InstallLocation
|
|
)
|
|
|
|
Write-Verbose -Verbose -Message "Installing CygWin from Chocolately to location: ${InstallLocation} ..."
|
|
choco install cygwin -y --force --params "/InstallDir:${InstallLocation} /NoStartMenu"
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Runs the tests for this repo
|
|
#>
|
|
function Invoke-OpenSSHTests
|
|
{
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $OpenSSHBinPath
|
|
)
|
|
|
|
Set-BasicTestInfo -OpenSSHBinPath $OpenSSHBinPath -Confirm:$false
|
|
|
|
Write-Verbose -Verbose -Message "Running OpenSSH Set up Tests..."
|
|
|
|
$AllTestsPassed = $true
|
|
|
|
Invoke-OpenSSHSetupTest
|
|
|
|
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["SetupTestResultsFile"])))
|
|
{
|
|
Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["SetupTestResultsFile"] not found after tests." -Category Error
|
|
$AllTestsPassed = $false
|
|
Write-Warning "Stop running further tests!"
|
|
return
|
|
}
|
|
|
|
$xml = [xml](Get-Content $OpenSSHTestInfo["SetupTestResultsFile"] | out-string)
|
|
if ([int]$xml.'test-results'.failures -gt 0)
|
|
{
|
|
$errorMessage = "$($xml.'test-results'.failures) Setup Tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["SetupTestResultsFile"])."
|
|
Write-BuildMessage -Message $errorMessage -Category Error
|
|
$AllTestsPassed = $False
|
|
Write-Warning "Stop running further tests!"
|
|
return
|
|
}
|
|
|
|
Write-BuildMessage -Message "All Setup tests passed!" -Category Information
|
|
$AllTestsPassed = $true
|
|
|
|
# Unit test directories are installed in the same directory as Open SSH binaries.
|
|
# OpenSSH Directory
|
|
# unittest-bitmap
|
|
# unittest-hostkeys
|
|
# ...
|
|
# FixHostFilePermissions.ps1
|
|
# ...
|
|
Write-Verbose -Verbose -Message "Running Unit Tests..."
|
|
Write-Verbose -Verbose -Message "Unit test directory is: ${OpenSSHBinPath}"
|
|
|
|
$unitTestFailed = Invoke-OpenSSHUnitTest -UnitTestDirectory $OpenSSHBinPath
|
|
|
|
if($unitTestFailed)
|
|
{
|
|
Write-BuildMessage "At least one of the unit tests failed!" -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
else
|
|
{
|
|
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
|
|
}
|
|
|
|
# Run all E2E tests.
|
|
Write-Verbose -Verbose -Message "Running E2E Tests..."
|
|
Set-OpenSSHTestEnvironment -Confirm:$false
|
|
Invoke-OpenSSHE2ETest
|
|
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["E2ETestResultsFile"])))
|
|
{
|
|
Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["E2ETestResultsFile"] not found after tests." -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
else
|
|
{
|
|
$xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string)
|
|
if ([int]$xml.'test-results'.failures -gt 0)
|
|
{
|
|
$errorMessage = "$($xml.'test-results'.failures) E2E tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["E2ETestResultsFile"])."
|
|
Write-BuildMessage -Message $errorMessage -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
else
|
|
{
|
|
Write-BuildMessage -Message "All E2E tests passed!" -Category Information
|
|
}
|
|
}
|
|
|
|
# Bash tests.
|
|
Write-Verbose -Verbose -Message "Running Bash Tests..."
|
|
|
|
# Ensure CygWin is installed, and install from Chocolatey if needed.
|
|
$cygwinInstalled = $true
|
|
$cygwinInstallLocation = "$env:SystemDrive/cygwin"
|
|
if (! (Test-Path -Path "$cygwinInstallLocation/bin/sh.exe"))
|
|
{
|
|
Write-Verbose -Verbose -Message "CygWin not found"
|
|
Install-CygWin -InstallLocation $cygwinInstallLocation
|
|
|
|
# Hack to fix up mangled CygWin directory, if needed.
|
|
$expectedCygWinPath = "$env:SystemDrive/cygwin/bin/sh.exe"
|
|
if (! (Test-Path -Path $expectedCygWinPath))
|
|
{
|
|
Write-Verbose -Verbose -Message "CygWin did not install correctly, missing expected path: ${expectedCygWinPath}"
|
|
|
|
$cygWinDirs = Get-Item -Path "$env:SystemDrive/cygwin*"
|
|
if ($cygWinDirs.Count -gt 1)
|
|
{
|
|
Write-Verbose -Verbose -Message "CygWin install failed with mangled folder locations: ${cygWinDirs}"
|
|
Write-Verbose -Verbose -Message 'TODO: Add hack to fix up CygWin folder.'
|
|
}
|
|
|
|
Write-BuildMessage -Message "All bash tests failed because CygWin install failed" -Category Error
|
|
$AllTestsPassed = $false
|
|
$cygwinInstalled = $false
|
|
}
|
|
}
|
|
|
|
# Run UNIX bash tests.
|
|
if ($cygwinInstalled)
|
|
{
|
|
Write-Verbose -Verbose -Message "Starting Bash Tests..."
|
|
Invoke-OpenSSHBashTests
|
|
if (-not $Global:bash_tests_summary)
|
|
{
|
|
$errorMessage = "Failed to start OpenSSH bash tests"
|
|
Write-BuildMessage -Message $errorMessage -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
else
|
|
{
|
|
if ($Global:bash_tests_summary["TotalBashTestsFailed"] -ne 0)
|
|
{
|
|
$total_bash_failed_tests = $Global:bash_tests_summary["TotalBashTestsFailed"]
|
|
$total_bash_tests = $Global:bash_tests_summary["TotalBashTests"]
|
|
$errorMessage = "At least one of the bash tests failed. [$total_bash_failed_tests of $total_bash_tests]"
|
|
Write-BuildMessage -Message $errorMessage -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
|
|
$OpenSSHTestInfo["BashTestSummaryFile"] = $Global:bash_tests_summary["BashTestSummaryFile"]
|
|
$OpenSSHTestInfo["BashTestLogFile"] = $Global:bash_tests_summary["BashTestLogFile"]
|
|
}
|
|
}
|
|
|
|
# OpenSSH Uninstall Tests
|
|
Invoke-OpenSSHUninstallTest
|
|
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["UninstallTestResultsFile"])))
|
|
{
|
|
Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["UninstallTestResultsFile"] not found after tests." -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
else
|
|
{
|
|
$xml = [xml](Get-Content $OpenSSHTestInfo["UninstallTestResultsFile"] | out-string)
|
|
if ([int]$xml.'test-results'.failures -gt 0)
|
|
{
|
|
$errorMessage = "$($xml.'test-results'.failures) uninstall tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["UninstallTestResultsFile"])."
|
|
Write-BuildMessage -Message $errorMessage -Category Error
|
|
$AllTestsPassed = $false
|
|
}
|
|
}
|
|
|
|
# Save OpenSSHTestInfo for later test results uploading.
|
|
$OpenSSHTestInfo | Export-Clixml -Path "$repoRoot/OpenSSHTestInfo.xml" -Depth 10
|
|
|
|
# Writing out warning when the $Error.Count is non-zero. Tests Should clean $Error after success.
|
|
if ($Error.Count -gt 0)
|
|
{
|
|
Write-BuildMessage -Message "Tests Should always clean $Error variable after success." -Category Warning
|
|
}
|
|
|
|
if ($AllTestsPassed)
|
|
{
|
|
Write-BuildMessage -Message "All OpenSSH validation tests have passed!" -Category Information
|
|
}
|
|
else
|
|
{
|
|
Write-BuildMessage -Message "Some OpenSSH validation tests have failed." -Category Error
|
|
throw "OpenSSH validation tests failed!"
|
|
}
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Collect OpenSSH pester test results into one directory
|
|
#>
|
|
function Copy-OpenSSHTestResults
|
|
{
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $ResultsPath
|
|
)
|
|
|
|
if (Test-Path -Path $ResultsPath)
|
|
{
|
|
Remove-Item -Path $ResultsPath -Force -Recurse -ErrorAction Ignore
|
|
}
|
|
|
|
Write-Verbose -Verbose "Creating test results directory for artifacts upload: $ResultsPath"
|
|
$null = New-Item -Path $ResultsPath -ItemType Directory -Force
|
|
|
|
if (! (Test-Path -Path $ResultsPath))
|
|
{
|
|
Write-BuildMessage -Message "Unable to write to test results path for test artifacts upload: $ResultsPath" -Category Error
|
|
return
|
|
}
|
|
|
|
$OpenSSHTestInfo = $null
|
|
$openSSHTestInfoFilePath = "$repoRoot/OpenSSHTestInfo.xml"
|
|
if (Test-Path -Path $openSSHTestInfoFilePath)
|
|
{
|
|
$OpenSSHTestInfo = Import-Clixml -Path $openSSHTestInfoFilePath
|
|
}
|
|
|
|
if (! $OpenSSHTestInfo)
|
|
{
|
|
Write-BuildMessage -Message "Unable to get OpenSSHTestInfo object from: ${openSSHTestInfoFilePath}"
|
|
return
|
|
}
|
|
|
|
try { $setupresultFile = Resolve-Path -Path $OpenSSHTestInfo["SetupTestResultsFile"] -ErrorAction Ignore } catch { }
|
|
if ($setupresultFile)
|
|
{
|
|
Write-Verbose -Verbose -Message "Copying set-up test results file, $setupresultFile, to results directory"
|
|
Copy-Item -Path $setupresultFile -Destination $ResultsPath
|
|
}
|
|
|
|
try { $E2EresultFile = Resolve-Path -Path $OpenSSHTestInfo["E2ETestResultsFile"] -ErrorAction Ignore } catch { }
|
|
if ($E2EresultFile)
|
|
{
|
|
Write-Verbose -Verbose -Message "Copying end-to-end test results file, $E2EresultFile, to results directory"
|
|
Copy-Item -Path $E2EresultFile -Destination $ResultsPath
|
|
}
|
|
|
|
try { $uninstallResultFile = Resolve-Path $OpenSSHTestInfo["UninstallTestResultsFile"] -ErrorAction Ignore } catch { }
|
|
if ($uninstallResultFile)
|
|
{
|
|
Write-Verbose -Verbose -Message "Copying uninstall test results file, $uninstallResultFile, to results directory"
|
|
Copy-Item -Path $uninstallResultFile -Destination $ResultsPath
|
|
}
|
|
|
|
try { $bashTestsSummaryFile = Resolve-Path -Path $OpenSSHTestInfo["BashTestSummaryFile"] -ErrorAction Ignore } catch { }
|
|
if ($bashTestsSummaryFile)
|
|
{
|
|
Write-Verbose -Verbose -Message "Copying bash tests summary file, $bashTestsSummaryFile, to results directory"
|
|
Copy-Item -Path $bashTestsSummaryFile -Destination $ResultsPath
|
|
}
|
|
|
|
try { $bashTestsLogFile = Resolve-Path -Path $OpenSSHTestInfo["BashTestLogFile"] -ErrorAction Ignore } catch { }
|
|
if ($bashTestsLogFile)
|
|
{
|
|
Write-Verbose -Verbose -Message "Copying bash tests log file, $bashTestsLogFile, to results directory"
|
|
Copy-Item -Path $bashTestsLogFile -Destination $ResultsPath
|
|
}
|
|
}
|
|
|
|
function Clear-TestEnvironmentSetup
|
|
{
|
|
Write-Verbose -Verbose -Message "Running OpenSSH test environment cleanup..."
|
|
|
|
try
|
|
{
|
|
$null = Clear-OpenSSHTestEnvironment -ErrorAction Ignore
|
|
$null = UnInstall-OpenSSH -ErrorAction Ignore
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
Write-Verbose -Verbose -Message "OpenSSH test environment cleanup complete."
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Copy build results package to provided destination path.
|
|
#>
|
|
function Copy-BuildResults
|
|
{
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $BuildResultsPath,
|
|
|
|
[ValidateSet('x86', 'x64', 'arm64', 'arm')]
|
|
[string]$NativeHostArch = "x64",
|
|
|
|
[ValidateSet('Debug', 'Release')]
|
|
[string]$Configuration = "Release"
|
|
)
|
|
|
|
# Copy OpenSSH package to results directory
|
|
Start-OpenSSHPackage -DestinationPath $BuildResultsPath -NativeHostArch $NativeHostArch -Configuration $Configuration
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Copy build unit tests to provided destination path.
|
|
#>
|
|
function Copy-UnitTests
|
|
{
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $UnitTestsSrcDir,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $UnitTestsDestDir,
|
|
|
|
[ValidateSet('x86', 'x64', 'arm64', 'arm')]
|
|
[string]$NativeHostArch = "x64",
|
|
|
|
[ValidateSet('Debug', 'Release')]
|
|
[string]$Configuration = "Release"
|
|
)
|
|
|
|
if (! (Test-Path -Path $UnitTestsDestDir))
|
|
{
|
|
Write-Verbose -Verbose -Message "Creating Unit Test directory: $UnitTestsDestDir"
|
|
$null = New-Item -Path $UnitTestsDestDir -ItemType Directory -Force
|
|
}
|
|
|
|
if ($NativeHostArch -eq 'x86')
|
|
{
|
|
$unitTestsSrcPath = Join-Path -Path $UnitTestsSrcDir -ChildPath "Win32/${Configuration}"
|
|
}
|
|
else
|
|
{
|
|
$unitTestsSrcPath = Join-Path -Path $UnitTestsSrcDir -ChildPath "${NativeHostArch}/${Configuration}"
|
|
}
|
|
|
|
$unitTestsDestPath = Join-Path -Path $UnitTestsDestDir -ChildPath "${NativeHostArch}/${Configuration}"
|
|
|
|
if (! (Test-Path -Path $unitTestsDestPath))
|
|
{
|
|
Write-Verbose -Verbose -Message "Creating Unit Test directory: $unitTestsDestPath"
|
|
$null = New-Item -Path $unitTestsDestPath -ItemType Directory -Force
|
|
}
|
|
|
|
Write-Verbose -Verbose -Message "Copying unit tests from: ${unitTestsSrcPath} to: ${unitTestsDestPath}"
|
|
Copy-Item -Path "$unitTestsSrcPath/unittest-*" -Destination $unitTestsDestPath -Recurse -Force
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Install unit tests to provided destination.
|
|
#>
|
|
function Install-UnitTests
|
|
{
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$SourceDir,
|
|
|
|
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
|
|
)
|
|
|
|
if (! (Test-Path -Path $OpenSSHDir)) {
|
|
$null = New-Item -Path $OpenSSHDir -ItemType Directory -Force
|
|
}
|
|
|
|
Copy-Item -Path "$SourceDir/*" -Destination $OpenSSHDir -Recurse -Force
|
|
}
|