summaryrefslogtreecommitdiff
path: root/scripts/Publish-Release.ps1
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-08-09 21:08:20 +0900
committertanaka takashi <isazaka@gmail.com>2026-08-09 21:08:20 +0900
commitb07b41cd435991cd254957af79055080c85b346e (patch)
tree27720d3ce14e4d0b84670a55ac26a2f877ce3a20 /scripts/Publish-Release.ps1
parent2fefd29e86c3b926d0cf4a362251d3f119688612 (diff)
feat: AI Agent Sandbox MCP Server v1を実装
Specifications、Design、ImplementationPlanの優先順位を整理し、単一Task実行モデル、typed option優先、設定可能なresource上限、local Ollamaを必須とするRelease Gateを文書化。 .NET 10/C# 14の5 production project、3 test project、E2E Clientを構築。typed YAML、en/ja locale、fixed/user prompt、stdioおよびloopback限定Streamable HTTP、agent_run/agent_status、Session、Ollama text/tool/Vision、TaskGraphとtoken accountingを実装。 Windows sandboxとしてfixed AppContainer、canonical/reparse検査、能力別ACL、path+SHA-256 executable approval、child-process restriction、Job Object、task journal、atomic file transaction、crash recoveryを実装。WFPのIPv4/IPv6 default denyとexact allow、dynamic session、temporary loopback exemption、管理者/BFE診断を追加。 Security/Recovery test、MCP/Ollama integration test、stdio/HTTP Operational E2E、Release Bundle生成・checksum・manifest・fresh extraction検査を追加。Requirement TraceabilityとPhase 0〜11の進捗、初回セットアップ可能なREADMEを整備。 Debug/Release/publish/objをrepository rootのbuild/へ集約し、旧project-local bin/objへの依存を除去。artifacts/とbuild/をGit管理外に設定し、clean checkoutでもsolution buildからE2E Clientまで生成可能にした。
Diffstat (limited to 'scripts/Publish-Release.ps1')
-rw-r--r--scripts/Publish-Release.ps176
1 files changed, 76 insertions, 0 deletions
diff --git a/scripts/Publish-Release.ps1 b/scripts/Publish-Release.ps1
new file mode 100644
index 0000000..8ada466
--- /dev/null
+++ b/scripts/Publish-Release.ps1
@@ -0,0 +1,76 @@
+param(
+ [string]$Version = '1.0.0',
+ [string]$OutputRoot = 'build\Release\publish',
+ [switch]$SkipRuntimeCheck
+)
+
+$ErrorActionPreference = 'Stop'
+$repository = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
+$outputRootPath = [IO.Path]::GetFullPath((Join-Path $repository $OutputRoot))
+$buildRootPath = [IO.Path]::GetFullPath((Join-Path $repository 'build'))
+if (-not $outputRootPath.StartsWith($buildRootPath + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) {
+ throw 'Release output must remain inside the repository build directory.'
+}
+$bundleName = "agent-sandbox-mcp-$Version-win-x64"
+$bundle = Join-Path $outputRootPath $bundleName
+$zip = Join-Path $outputRootPath "$bundleName.zip"
+$checksum = "$zip.sha256"
+
+New-Item -ItemType Directory -Force -Path $outputRootPath | Out-Null
+if (Test-Path -LiteralPath $bundle) { Remove-Item -LiteralPath $bundle -Recurse -Force }
+if (Test-Path -LiteralPath $zip) { Remove-Item -LiteralPath $zip -Force }
+if (Test-Path -LiteralPath $checksum) { Remove-Item -LiteralPath $checksum -Force }
+
+$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
+if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed with exit code $LASTEXITCODE" }
+
+$required = @(
+ 'agent-mcp.exe', 'agent.yaml', 'config\locales\en.json', 'config\locales\ja.json',
+ '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" }
+}
+
+$manifestPath = Join-Path $bundle 'publish-manifest.sha256'
+Get-ChildItem -LiteralPath $bundle -File -Recurse |
+ Where-Object FullName -ne $manifestPath |
+ Sort-Object FullName |
+ ForEach-Object {
+ $relative = [IO.Path]::GetRelativePath($bundle, $_.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
+$zipHash = (Get-FileHash -LiteralPath $zip -Algorithm SHA256).Hash.ToLowerInvariant()
+"$zipHash $([IO.Path]::GetFileName($zip))" | Set-Content -LiteralPath $checksum -Encoding ascii
+
+$freshRoot = Join-Path ([IO.Path]::GetTempPath()) ("agent-mcp-release-check-" + [Guid]::NewGuid().ToString('N'))
+New-Item -ItemType Directory -Path $freshRoot | Out-Null
+try {
+ Expand-Archive -LiteralPath $zip -DestinationPath $freshRoot
+ $freshBundle = Join-Path $freshRoot $bundleName
+ $sourceReferences = Get-ChildItem -LiteralPath $freshBundle -File -Recurse |
+ Where-Object Extension -in @('.yaml', '.json', '.md', '.config') |
+ Select-String -SimpleMatch -Pattern $repository
+ if ($sourceReferences) { throw 'Release Bundle contains a source-tree reference.' }
+ 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." }
+ }
+ finally { Pop-Location }
+ }
+}
+finally {
+ if (Test-Path -LiteralPath $freshRoot) { Remove-Item -LiteralPath $freshRoot -Recurse -Force }
+}
+
+Write-Output "Bundle: $bundle"
+Write-Output "ZIP: $zip"
+Write-Output "SHA-256: $checksum"