build: make release restore reproducible
This commit is contained in:
parent
b459e0cf0c
commit
c38f6b8852
129 changed files with 16810 additions and 188 deletions
|
|
@ -3,12 +3,14 @@
|
|||
Runs the complete portable Release gate with bounded child processes.
|
||||
|
||||
.DESCRIPTION
|
||||
Discovers every test project under tests/ that declares itself through
|
||||
Microsoft.NET.Test.Sdk or IsTestProject, verifies that AcDream.slnx owns it,
|
||||
restores and builds the solution, and then runs each test assembly in a
|
||||
fresh process. Every process has an outer hard timeout. Test processes also
|
||||
use VSTest blame-hang collection, so a stuck test host is terminated with a
|
||||
mini dump before the outer watchdog is allowed to kill the process tree.
|
||||
Verifies that AcDream.slnx owns every project under src/, tests/, and tools/;
|
||||
performs a locked restore; builds that complete supported graph; discovers
|
||||
every test project under tests/ that declares itself through
|
||||
Microsoft.NET.Test.Sdk or IsTestProject; and then runs each test assembly in
|
||||
a fresh process. Every process has an outer hard timeout. Test processes
|
||||
also use VSTest blame-hang collection, so a stuck test host is terminated
|
||||
with a mini dump before the outer watchdog is allowed to kill the process
|
||||
tree.
|
||||
|
||||
The evidence directory contains process logs, one TRX per test assembly,
|
||||
any blame sequence/dump files, an environment report, an aggregate JSON
|
||||
|
|
@ -171,6 +173,48 @@ function Invoke-BoundedDotnet {
|
|||
return $result
|
||||
}
|
||||
|
||||
function Get-SolutionProjects {
|
||||
[xml]$solution = Get-Content -LiteralPath $solutionPath
|
||||
$projectPaths = @(
|
||||
$solution.SelectNodes('//Project') |
|
||||
ForEach-Object { [string]$_.Path } |
|
||||
Sort-Object -Unique
|
||||
)
|
||||
if ($projectPaths.Count -eq 0) {
|
||||
throw 'AcDream.slnx contains no projects.'
|
||||
}
|
||||
|
||||
$projects = @(
|
||||
foreach ($relativePath in $projectPaths) {
|
||||
$fullPath = [IO.Path]::GetFullPath((Join-Path $repoRoot $relativePath))
|
||||
if (-not (Test-Path -LiteralPath $fullPath -PathType Leaf)) {
|
||||
throw "Solution project '$relativePath' does not exist."
|
||||
}
|
||||
Get-Item -LiteralPath $fullPath
|
||||
}
|
||||
)
|
||||
|
||||
$maintainedProjects = @(
|
||||
foreach ($directoryName in @('src', 'tests', 'tools')) {
|
||||
Get-ChildItem -LiteralPath (Join-Path $repoRoot $directoryName) -Recurse -Filter '*.csproj' -File
|
||||
}
|
||||
)
|
||||
$solutionSet = [Collections.Generic.HashSet[string]]::new(
|
||||
[StringComparer]::OrdinalIgnoreCase)
|
||||
foreach ($project in $projects) {
|
||||
[void]$solutionSet.Add($project.FullName)
|
||||
}
|
||||
$missing = @($maintainedProjects | Where-Object { -not $solutionSet.Contains($_.FullName) })
|
||||
if ($missing.Count -gt 0) {
|
||||
$missingText = $missing |
|
||||
ForEach-Object { [IO.Path]::GetRelativePath($repoRoot, $_.FullName).Replace('\', '/') } |
|
||||
Sort-Object
|
||||
throw "Maintained projects missing from AcDream.slnx: $($missingText -join ', ')"
|
||||
}
|
||||
|
||||
return $projects
|
||||
}
|
||||
|
||||
function Get-TestProjects {
|
||||
$solutionText = Get-Content -LiteralPath $solutionPath -Raw
|
||||
$projects = @(
|
||||
|
|
@ -240,6 +284,7 @@ function Write-ArtifactHashes {
|
|||
Push-Location $repoRoot
|
||||
try {
|
||||
$gateStartedUtc = [DateTimeOffset]::UtcNow
|
||||
$solutionProjects = @(Get-SolutionProjects)
|
||||
$testProjects = @(Get-TestProjects)
|
||||
$processes = [Collections.Generic.List[object]]::new()
|
||||
$testReports = [Collections.Generic.List[object]]::new()
|
||||
|
|
@ -263,6 +308,29 @@ try {
|
|||
(dotnet nuget list source | Out-String)
|
||||
'--- worktree status at gate start ---'
|
||||
($worktreeStatus -join [Environment]::NewLine)
|
||||
'--- supported solution projects ---'
|
||||
($solutionProjects | ForEach-Object {
|
||||
[IO.Path]::GetRelativePath($repoRoot, $_.FullName).Replace('\', '/')
|
||||
})
|
||||
'--- package lock files ---'
|
||||
($solutionProjects | ForEach-Object {
|
||||
$relativeProject = [IO.Path]::GetRelativePath($repoRoot, $_.FullName).Replace('\', '/')
|
||||
$lockNames = [Collections.Generic.List[string]]::new()
|
||||
$lockNames.Add('packages.neutral.lock.json')
|
||||
if ($relativeProject.StartsWith('src/', [StringComparison]::OrdinalIgnoreCase)) {
|
||||
$lockNames.Add('packages.win-x64.lock.json')
|
||||
$lockNames.Add('packages.linux-x64.lock.json')
|
||||
}
|
||||
foreach ($lockName in $lockNames) {
|
||||
$lockPath = Join-Path $_.DirectoryName $lockName
|
||||
if (-not (Test-Path -LiteralPath $lockPath -PathType Leaf)) {
|
||||
throw "Supported project '$($_.FullName)' has no $lockName."
|
||||
}
|
||||
$relative = [IO.Path]::GetRelativePath($repoRoot, $lockPath).Replace('\', '/')
|
||||
$hash = (Get-FileHash -LiteralPath $lockPath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
"$hash $relative"
|
||||
}
|
||||
})
|
||||
'--- discovered test projects ---'
|
||||
($testProjects | ForEach-Object {
|
||||
[IO.Path]::GetRelativePath($repoRoot, $_.FullName).Replace('\', '/')
|
||||
|
|
@ -272,7 +340,7 @@ try {
|
|||
|
||||
if (-not $SkipRestore) {
|
||||
$restore = Invoke-BoundedDotnet -Label 'restore' -TimeoutSeconds $RestoreTimeoutSeconds -Arguments @(
|
||||
'restore', $solutionPath, '--nologo'
|
||||
'restore', $solutionPath, '--locked-mode', '--force-evaluate', '--nologo'
|
||||
)
|
||||
$processes.Add($restore)
|
||||
if ($restore.ExitCode -ne 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue