feat(launcher): complete Campaign LA11 pre-gate support
This commit is contained in:
parent
f881e5b467
commit
134edabed2
19 changed files with 433 additions and 55 deletions
|
|
@ -85,9 +85,11 @@ foreach ($release in @('A', 'B')) {
|
|||
Require-PayloadFile "$release-client-win-x64" 'AcDream.App.exe'
|
||||
Require-PayloadFile "$release-client-win-x64" 'acdream-headless.exe'
|
||||
Require-PayloadFile "$release-launcher-win-x64" 'acdream-launcher.exe'
|
||||
Require-PayloadFile "$release-launcher-win-x64" 'acdream-bake.exe'
|
||||
Require-PayloadFile "$release-client-linux-x64" 'AcDream.App'
|
||||
Require-PayloadFile "$release-client-linux-x64" 'acdream-headless'
|
||||
Require-PayloadFile "$release-launcher-linux-x64" 'acdream-launcher'
|
||||
Require-PayloadFile "$release-launcher-linux-x64" 'acdream-bake'
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $OutputDirectory) {
|
||||
|
|
@ -155,6 +157,7 @@ function New-DeterministicZip(
|
|||
$executable = $relative -ceq 'AcDream.App' -or
|
||||
$relative -ceq 'acdream-headless' -or
|
||||
$relative -ceq 'acdream-launcher' -or
|
||||
$relative -ceq 'acdream-bake' -or
|
||||
$relative.EndsWith('.sh', [StringComparison]::Ordinal)
|
||||
$mode = if ($executable) { 0x81ED } else { 0x81A4 }
|
||||
$entry.ExternalAttributes = $mode -shl 16
|
||||
|
|
@ -239,16 +242,26 @@ $server = @'
|
|||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Root,
|
||||
[Parameter(Mandatory = $true)][int]$Port
|
||||
[Parameter(Mandatory = $true)][int]$Port,
|
||||
[ValidateRange(0, 1000000)][int]$MaximumRequests = 0
|
||||
)
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$expectedRoot = [IO.Path]::TrimEndingDirectorySeparator(
|
||||
[IO.Path]::GetFullPath($PSScriptRoot))
|
||||
$Root = [IO.Path]::TrimEndingDirectorySeparator([IO.Path]::GetFullPath($Root))
|
||||
$pathComparison = if ($IsWindows) {
|
||||
[StringComparison]::OrdinalIgnoreCase
|
||||
} else { [StringComparison]::Ordinal }
|
||||
if (-not [string]::Equals($Root, $expectedRoot, $pathComparison)) {
|
||||
throw '-Root must be the directory containing serve-fixture.ps1.'
|
||||
}
|
||||
$prefix = "http://127.0.0.1:$Port/"
|
||||
$listener = [Net.HttpListener]::new()
|
||||
$listener.Prefixes.Add($prefix)
|
||||
$listener.Start()
|
||||
Write-Host "Campaign LA fixture listening on $prefix"
|
||||
$servedRequests = 0
|
||||
try {
|
||||
while ($listener.IsListening) {
|
||||
$context = $listener.GetContext()
|
||||
|
|
@ -287,7 +300,13 @@ try {
|
|||
$context.Response.StatusCode = 500
|
||||
Write-Error $_
|
||||
}
|
||||
finally { $context.Response.Close() }
|
||||
finally {
|
||||
$context.Response.Close()
|
||||
$servedRequests++
|
||||
}
|
||||
if ($MaximumRequests -gt 0 -and $servedRequests -ge $MaximumRequests) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
finally { $listener.Close() }
|
||||
|
|
@ -301,8 +320,24 @@ param(
|
|||
[string]$Root = $PSScriptRoot
|
||||
)
|
||||
Set-StrictMode -Version Latest
|
||||
$path = Join-Path ([IO.Path]::GetFullPath($Root)) 'active-release.txt'
|
||||
Set-Content -LiteralPath $path -Value $Release -Encoding ascii -NoNewline
|
||||
$expectedRoot = [IO.Path]::TrimEndingDirectorySeparator(
|
||||
[IO.Path]::GetFullPath($PSScriptRoot))
|
||||
$Root = [IO.Path]::TrimEndingDirectorySeparator([IO.Path]::GetFullPath($Root))
|
||||
$pathComparison = if ($IsWindows) {
|
||||
[StringComparison]::OrdinalIgnoreCase
|
||||
} else { [StringComparison]::Ordinal }
|
||||
if (-not [string]::Equals($Root, $expectedRoot, $pathComparison)) {
|
||||
throw '-Root must be the directory containing set-active-release.ps1.'
|
||||
}
|
||||
$path = Join-Path $Root 'active-release.txt'
|
||||
$temporary = "$path.$([Guid]::NewGuid().ToString('N')).tmp"
|
||||
try {
|
||||
[IO.File]::WriteAllText($temporary, $Release, [Text.Encoding]::ASCII)
|
||||
[IO.File]::Move($temporary, $path, $true)
|
||||
}
|
||||
finally {
|
||||
if ([IO.File]::Exists($temporary)) { [IO.File]::Delete($temporary) }
|
||||
}
|
||||
Write-Host "Campaign LA fixture active release: $Release"
|
||||
'@
|
||||
$selector | Set-Content -LiteralPath (Join-Path $OutputDirectory 'set-active-release.ps1') -Encoding utf8NoBOM
|
||||
|
|
|
|||
|
|
@ -68,16 +68,22 @@ $startedUtc = [DateTime]::UtcNow
|
|||
function Protect-Text([string]$Text) {
|
||||
if ($null -eq $Text) { return '' }
|
||||
$protected = $Text
|
||||
foreach ($name in @('ACDREAM_TEST_PASS', 'ACDREAM_LA_GATE_SECRET')) {
|
||||
$value = [Environment]::GetEnvironmentVariable($name)
|
||||
if (-not [string]::IsNullOrEmpty($value)) {
|
||||
$protected = $protected.Replace($value, '<redacted>', [StringComparison]::Ordinal)
|
||||
}
|
||||
}
|
||||
$protected = [Text.RegularExpressions.Regex]::Replace(
|
||||
$protected,
|
||||
'(?i)(--password|-password)(\s+|=)([^\s"'']+)',
|
||||
'$1$2<redacted>')
|
||||
$protected = [Text.RegularExpressions.Regex]::Replace(
|
||||
$protected,
|
||||
'(?i)\b(password|passwd|secret|token|credential|api[_-]?key)(\s*[:=]\s*)([^\s,;]+)',
|
||||
'$1$2<redacted>')
|
||||
$protected = [Text.RegularExpressions.Regex]::Replace(
|
||||
$protected,
|
||||
'(?i)(https?://)[^/\s:@]+:[^@\s/]+@',
|
||||
'$1<redacted>@')
|
||||
$protected = [Text.RegularExpressions.Regex]::Replace(
|
||||
$protected,
|
||||
'(?i)([?&](?:token|secret|password|credential|api[_-]?key)=)[^&\s]+',
|
||||
'$1<redacted>')
|
||||
$protected = [Text.RegularExpressions.Regex]::Replace(
|
||||
$protected,
|
||||
'(?i)("(?:password|credential|secret|token)"\s*:\s*")[^"]*(")',
|
||||
|
|
@ -142,6 +148,11 @@ function Invoke-GateCommand(
|
|||
$startInfo.RedirectStandardOutput = $true
|
||||
$startInfo.RedirectStandardError = $true
|
||||
foreach ($argument in $Arguments) { $startInfo.ArgumentList.Add($argument) }
|
||||
foreach ($key in @($startInfo.Environment.Keys)) {
|
||||
if ($key.StartsWith('ACDREAM_', [StringComparison]::OrdinalIgnoreCase)) {
|
||||
$startInfo.Environment.Remove($key)
|
||||
}
|
||||
}
|
||||
foreach ($entry in $Environment.GetEnumerator()) {
|
||||
$startInfo.Environment[[string]$entry.Key] = [string]$entry.Value
|
||||
}
|
||||
|
|
@ -258,6 +269,34 @@ try {
|
|||
'--', 'RunConfiguration.MaxCpuCount=1')
|
||||
}
|
||||
|
||||
$headlessValidationConfig = Join-Path $OutputDirectory 'headless-k0.json'
|
||||
Add-InternalCheck 'portable-headless-write-empty-config' {
|
||||
[IO.File]::WriteAllText(
|
||||
$headlessValidationConfig,
|
||||
'{"version":1,"sessions":[]}',
|
||||
[Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
Invoke-DotNet 'portable-headless-help-no-connect' @(
|
||||
'run', '--project', 'src/AcDream.Headless/AcDream.Headless.csproj',
|
||||
'-c', 'Release', '--no-build', '--', '--help')
|
||||
Invoke-DotNet 'portable-headless-validate-empty-no-connect' @(
|
||||
'run', '--project', 'src/AcDream.Headless/AcDream.Headless.csproj',
|
||||
'-c', 'Release', '--no-build', '--',
|
||||
'validate', '--config', $headlessValidationConfig)
|
||||
Add-InternalCheck 'portable-headless-native-permission' {
|
||||
if (-not $IsWindows) {
|
||||
$headlessExecutable = Join-Path `
|
||||
$Repository 'src/AcDream.Headless/bin/Release/net10.0/acdream-headless'
|
||||
if (-not (Test-Path -LiteralPath $headlessExecutable -PathType Leaf)) {
|
||||
throw 'The native Headless build output is missing.'
|
||||
}
|
||||
$mode = [IO.File]::GetUnixFileMode($headlessExecutable)
|
||||
if (($mode -band [IO.UnixFileMode]::UserExecute) -eq 0) {
|
||||
throw 'The native Headless build output is not executable.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rid in @('win-x64', 'linux-x64')) {
|
||||
$destination = Join-Path $publishDirectory $rid
|
||||
Invoke-DotNet "publish-launcher-$rid" @(
|
||||
|
|
@ -382,7 +421,8 @@ finally {
|
|||
failures = @($failures)
|
||||
redaction = [ordered]@{
|
||||
applied = $true
|
||||
environmentValuesNeverReported = @('ACDREAM_TEST_PASS', 'ACDREAM_LA_GATE_SECRET')
|
||||
inheritedAcdreamEnvironmentCleared = $true
|
||||
inheritedEnvironmentValuesRead = $false
|
||||
credentialArgumentsAllowed = $false
|
||||
}
|
||||
artifacts = $artifacts
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ for ($lineIndex = 0; $lineIndex -lt $lines.Count; $lineIndex++) {
|
|||
}
|
||||
$eventName = Assert-String $root 'e'
|
||||
if (-not $exactFields.ContainsKey($eventName)) {
|
||||
throw "event '$eventName' is not in the v1 vocabulary"
|
||||
throw 'event name is not in the v1 vocabulary'
|
||||
}
|
||||
$expected = $exactFields[$eventName]
|
||||
if ($names.Count -ne $expected.Count -or
|
||||
|
|
@ -221,7 +221,7 @@ for ($lineIndex = 0; $lineIndex -lt $lines.Count; $lineIndex++) {
|
|||
if ($code -ne 0) { throw "terminal exit code is $code, expected 0" }
|
||||
$expectedReason = if ($Mode -eq 'probe') { 'probe' } else { 'graceful' }
|
||||
if ($reason -cne $expectedReason) {
|
||||
throw "terminal reason is '$reason', expected '$expectedReason'"
|
||||
throw "terminal reason does not match mode '$Mode'"
|
||||
}
|
||||
$terminalSeen = $true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue