132 lines
5.6 KiB
PowerShell
132 lines
5.6 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[switch] $SkipRestore,
|
|
[switch] $CollectCoverage
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$repositoryRoot = Split-Path -Parent $PSScriptRoot
|
|
$testResultsPath = Join-Path $repositoryRoot 'TestResults\Validation'
|
|
$dotnetHome = Join-Path (Split-Path -Parent $repositoryRoot) '.dotnet-cli-validation'
|
|
$nugetPackagesPath = if ($env:NUGET_PACKAGES) { $env:NUGET_PACKAGES } else { Join-Path $env:USERPROFILE '.nuget\packages' }
|
|
|
|
$env:DOTNET_CLI_HOME = $dotnetHome
|
|
$env:DOTNET_GENERATE_ASPNET_CERTIFICATE = 'false'
|
|
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1'
|
|
$env:DOTNET_CLI_TELEMETRY_OPTOUT = '1'
|
|
$env:DOTNET_NOLOGO = '1'
|
|
$env:NUGET_PACKAGES = $nugetPackagesPath
|
|
|
|
function Invoke-External
|
|
{
|
|
param(
|
|
[Parameter(Mandatory)] [string] $FilePath,
|
|
[Parameter(Mandatory)] [string[]] $ArgumentList
|
|
)
|
|
|
|
& $FilePath @ArgumentList
|
|
if ($LASTEXITCODE -ne 0)
|
|
{
|
|
throw "Command failed with exit code ${LASTEXITCODE}: $FilePath $($ArgumentList -join ' ')"
|
|
}
|
|
}
|
|
|
|
function Test-LineEndings
|
|
{
|
|
$crlfExtensions = @('.cs', '.csproj', '.sln', '.props', '.targets', '.config', '.json', '.xml', '.md', '.txt', '.ps1', '.cmd', '.bat')
|
|
$lfExtensions = @('.svg', '.html', '.css', '.js', '.sh', '.yml', '.yaml')
|
|
$invalidFiles = [System.Collections.Generic.List[string]]::new()
|
|
$files = @(& git -C $repositoryRoot diff --name-only --diff-filter=ACMRT)
|
|
if ($LASTEXITCODE -ne 0) { throw 'Unable to enumerate modified repository files.' }
|
|
$files += @(& git -C $repositoryRoot diff --cached --name-only --diff-filter=ACMRT)
|
|
if ($LASTEXITCODE -ne 0) { throw 'Unable to enumerate staged repository files.' }
|
|
$files += @(& git -C $repositoryRoot ls-files --others --exclude-standard)
|
|
if ($LASTEXITCODE -ne 0) { throw 'Unable to enumerate untracked repository files.' }
|
|
$files = $files | Sort-Object -Unique
|
|
|
|
foreach ($relativePath in $files)
|
|
{
|
|
$extension = [System.IO.Path]::GetExtension($relativePath).ToLowerInvariant()
|
|
if (($extension -notin $crlfExtensions) -and ($extension -notin $lfExtensions)) { continue }
|
|
|
|
$fullPath = Join-Path $repositoryRoot $relativePath
|
|
if (-not (Test-Path -LiteralPath $fullPath -PathType Leaf)) { continue }
|
|
$bytes = [System.IO.File]::ReadAllBytes($fullPath)
|
|
for ($index = 0; $index -lt $bytes.Length; $index++)
|
|
{
|
|
if (($extension -in $crlfExtensions) -and ($bytes[$index] -eq 10) -and (($index -eq 0) -or ($bytes[$index - 1] -ne 13)))
|
|
{
|
|
$invalidFiles.Add($relativePath)
|
|
break
|
|
}
|
|
if (($extension -in $lfExtensions) -and ($bytes[$index] -eq 13))
|
|
{
|
|
$invalidFiles.Add($relativePath)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($invalidFiles.Count -gt 0)
|
|
{
|
|
throw "Files with incorrect line endings:
|
|
$($invalidFiles -join "
|
|
")"
|
|
}
|
|
}
|
|
|
|
function Test-CoverageReport
|
|
{
|
|
param([Parameter(Mandatory)] [string] $ResultsPath)
|
|
|
|
$report = Get-ChildItem -LiteralPath $ResultsPath -Filter 'coverage.cobertura.xml' -Recurse | Select-Object -First 1
|
|
if (($null -eq $report) -or ($report.Length -eq 0))
|
|
{
|
|
throw "A non-empty Cobertura coverage report was not found under $ResultsPath"
|
|
}
|
|
|
|
[xml] $coverage = Get-Content -LiteralPath $report.FullName -Raw
|
|
if ($coverage.DocumentElement.Name -ne 'coverage')
|
|
{
|
|
throw "The coverage report at $($report.FullName) is not valid Cobertura XML."
|
|
}
|
|
}
|
|
|
|
Push-Location $repositoryRoot
|
|
try
|
|
{
|
|
Write-Host 'Validating BusinessMgr workspace...'
|
|
if (-not $SkipRestore)
|
|
{
|
|
Invoke-External dotnet @('restore', 'BusinessMgr.sln', '--disable-build-servers', '--verbosity', 'minimal')
|
|
}
|
|
|
|
Invoke-External dotnet @('build', 'BusinessMgr.sln', '--configuration', 'Debug', '--no-restore', '--disable-build-servers', '--verbosity', 'minimal', '--maxcpucount:1')
|
|
Invoke-External dotnet @('test', 'SaBusMgrTest_Control\SaBusMgrTest_Control.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--results-directory', $testResultsPath, '--verbosity', 'minimal')
|
|
Invoke-External dotnet @('test', 'SaBusMgrTest_Portal\SaBusMgrTest_Portal.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--results-directory', $testResultsPath, '--verbosity', 'minimal')
|
|
if ($CollectCoverage)
|
|
{
|
|
$coverageRunPath = Join-Path $testResultsPath "Coverage\$([guid]::NewGuid())"
|
|
$controlCoveragePath = Join-Path $coverageRunPath 'Control'
|
|
$portalCoveragePath = Join-Path $coverageRunPath 'Portal'
|
|
|
|
Invoke-External dotnet @('test', 'SaBusMgrTest_Control\SaBusMgrTest_Control.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--collect', 'XPlat Code Coverage', '--results-directory', $controlCoveragePath, '--verbosity', 'minimal')
|
|
Test-CoverageReport $controlCoveragePath
|
|
Invoke-External dotnet @('test', 'SaBusMgrTest_Portal\SaBusMgrTest_Portal.csproj', '--configuration', 'Debug', '--no-build', '--no-restore', '--collect', 'XPlat Code Coverage', '--results-directory', $portalCoveragePath, '--verbosity', 'minimal')
|
|
Test-CoverageReport $portalCoveragePath
|
|
}
|
|
Invoke-External dotnet @('list', 'SaBusMgrStandardBase\SaBusMgrStandardBase.csproj', 'package', '--vulnerable', '--include-transitive')
|
|
Invoke-External dotnet @('list', 'SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj', 'package', '--vulnerable', '--include-transitive')
|
|
Invoke-External dotnet @('list', 'SaBusMgrCoreWeb\SaBusMgrCoreWeb.csproj', 'package', '--vulnerable', '--include-transitive')
|
|
Invoke-External dotnet @('list', 'SaBusinessMgrCoreWebControl\SaBusinessMgrCoreWebControl.csproj', 'package', '--vulnerable', '--include-transitive')
|
|
Invoke-External dotnet @('list', 'SaBusinessMgrCoreWebPortal\SaBusinessMgrCoreWebPortal.csproj', 'package', '--vulnerable', '--include-transitive')
|
|
Invoke-External git @('diff', '--check')
|
|
Test-LineEndings
|
|
|
|
Write-Host 'BusinessMgr validation passed.' -ForegroundColor Green
|
|
}
|
|
finally
|
|
{
|
|
Pop-Location
|
|
}
|