diff options
Diffstat (limited to 'scripts/Publish-Release.ps1')
| -rw-r--r-- | scripts/Publish-Release.ps1 | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/scripts/Publish-Release.ps1 b/scripts/Publish-Release.ps1 index a36c2b4..d794bb5 100644 --- a/scripts/Publish-Release.ps1 +++ b/scripts/Publish-Release.ps1 @@ -15,22 +15,18 @@ $bundleName = "agent-sandbox-mcp-$Version-win-x64" $bundle = Join-Path $outputRootPath $bundleName $zip = Join-Path $outputRootPath "$bundleName.zip" $checksum = "$zip.sha256" +$stagingRoot = Join-Path $outputRootPath (".staging-" + [Guid]::NewGuid().ToString('N')) +$stagingBundle = Join-Path $stagingRoot $bundleName New-Item -ItemType Directory -Force -Path $outputRootPath | Out-Null -if (Test-Path -LiteralPath $bundle) { - $resolvedBundle = (Resolve-Path -LiteralPath $bundle).Path - if (-not $resolvedBundle.StartsWith($outputRootPath + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { - throw 'Existing Release Bundle escaped the validated output root.' - } - Get-ChildItem -LiteralPath $resolvedBundle -Force | Remove-Item -Recurse -Force -} if (Test-Path -LiteralPath $zip) { Remove-Item -LiteralPath $zip -Force } if (Test-Path -LiteralPath $checksum) { Remove-Item -LiteralPath $checksum -Force } +New-Item -ItemType Directory -Path $stagingBundle | Out-Null $appProject = Join-Path $repository 'src\Agent.App\Agent.App.csproj' dotnet restore $appProject -r win-x64 --locked-mode if ($LASTEXITCODE -ne 0) { throw "win-x64 locked restore failed with exit code $LASTEXITCODE" } -dotnet publish $appProject -c Release -r win-x64 --self-contained true --no-restore --output $bundle -p:Version=$Version +dotnet publish $appProject -c Release -r win-x64 --self-contained true --no-restore --output $stagingBundle -p:Version=$Version if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed with exit code $LASTEXITCODE" } $required = @( @@ -38,23 +34,23 @@ $required = @( 'prompts\user-system.md', 'skills', 'README.md' ) foreach ($relative in $required) { - if (-not (Test-Path -LiteralPath (Join-Path $bundle $relative))) { throw "Release Bundle is missing $relative" } + if (-not (Test-Path -LiteralPath (Join-Path $stagingBundle $relative))) { throw "Release Bundle is missing $relative" } } foreach ($relative in @('agent.local.yaml', 'config\agent.local.example.yaml')) { - if (Test-Path -LiteralPath (Join-Path $bundle $relative)) { throw "Release Bundle must not contain local override input: $relative" } + if (Test-Path -LiteralPath (Join-Path $stagingBundle $relative)) { throw "Release Bundle must not contain local override input: $relative" } } -$manifestPath = Join-Path $bundle 'publish-manifest.sha256' -Get-ChildItem -LiteralPath $bundle -File -Recurse | +$manifestPath = Join-Path $stagingBundle 'publish-manifest.sha256' +Get-ChildItem -LiteralPath $stagingBundle -File -Recurse | Where-Object FullName -ne $manifestPath | Sort-Object FullName | ForEach-Object { - $relative = [IO.Path]::GetRelativePath($bundle, $_.FullName).Replace('\', '/') + $relative = [IO.Path]::GetRelativePath($stagingBundle, $_.FullName).Replace('\', '/') $hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() "$hash $relative" } | Set-Content -LiteralPath $manifestPath -Encoding utf8NoBOM -Compress-Archive -LiteralPath $bundle -DestinationPath $zip -CompressionLevel Optimal +Compress-Archive -LiteralPath $stagingBundle -DestinationPath $zip -CompressionLevel Optimal $zipHash = (Get-FileHash -LiteralPath $zip -Algorithm SHA256).Hash.ToLowerInvariant() "$zipHash $([IO.Path]::GetFileName($zip))" | Set-Content -LiteralPath $checksum -Encoding ascii @@ -70,8 +66,8 @@ try { if (-not $SkipRuntimeCheck) { Push-Location $freshBundle try { - & .\agent-mcp.exe check --config .\agent.yaml --lang en - if ($LASTEXITCODE -ne 0) { throw "Bundle check failed with exit code $LASTEXITCODE. Run this script in an elevated terminal." } + & .\agent-mcp.exe sandbox resolve --config .\agent.yaml --lang en + if ($LASTEXITCODE -ne 0) { throw "Bundle resolution check failed with exit code $LASTEXITCODE." } } finally { Pop-Location } } @@ -80,6 +76,25 @@ finally { if (Test-Path -LiteralPath $freshRoot) { Remove-Item -LiteralPath $freshRoot -Recurse -Force } } +# The ZIP is reproducible defaults only. The deployment directory keeps explicitly local, +# publish-excluded inputs while all versioned defaults and binaries are replaced. +try { + if (Test-Path -LiteralPath $bundle) { + $resolvedBundle = (Resolve-Path -LiteralPath $bundle).Path + if (-not $resolvedBundle.StartsWith($outputRootPath + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { + throw 'Existing deployment Bundle escaped the validated output root.' + } + Get-ChildItem -LiteralPath $resolvedBundle -Force | + Where-Object Name -notin @('agent.local.yaml', 'local', 'logs', 'state') | + Remove-Item -Recurse -Force + } + else { New-Item -ItemType Directory -Path $bundle | Out-Null } + Copy-Item -Path (Join-Path $stagingBundle '*') -Destination $bundle -Recurse -Force +} +finally { + if (Test-Path -LiteralPath $stagingRoot) { Remove-Item -LiteralPath $stagingRoot -Recurse -Force } +} + Write-Output "Bundle: $bundle" Write-Output "ZIP: $zip" Write-Output "SHA-256: $checksum" |
