test: gate unified compose deployment
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
param(
|
||||
[string]$RepositoryRoot = "",
|
||||
[string]$ThothctlPath = ""
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($RepositoryRoot)) {
|
||||
$RepositoryRoot = (& git rev-parse --show-toplevel).Trim()
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "git could not resolve the repository root"
|
||||
}
|
||||
}
|
||||
$RepositoryRoot = [System.IO.Path]::GetFullPath($RepositoryRoot)
|
||||
|
||||
$tracked = @(& git -C $RepositoryRoot ls-files)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "git ls-files failed"
|
||||
}
|
||||
|
||||
$scriptRelativePath = "scripts/test-windows-clone-contract.ps1"
|
||||
$eolAttribute = (& git -C $RepositoryRoot check-attr eol -- $scriptRelativePath).Trim()
|
||||
if ($LASTEXITCODE -ne 0 -or -not $eolAttribute.EndsWith("eol: crlf", [System.StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "the Windows contract script must have the repository eol=crlf attribute"
|
||||
}
|
||||
$scriptBytes = [System.IO.File]::ReadAllBytes((Join-Path $RepositoryRoot $scriptRelativePath))
|
||||
if (-not ($scriptBytes -contains [byte]0x0D)) {
|
||||
throw "the Windows contract script was not checked out with CRLF bytes"
|
||||
}
|
||||
|
||||
$offenders = [System.Collections.Generic.List[string]]::new()
|
||||
foreach ($relativePath in $tracked) {
|
||||
$name = [System.IO.Path]::GetFileName($relativePath)
|
||||
$mustBeLf = $relativePath.EndsWith(".sh", [System.StringComparison]::OrdinalIgnoreCase) -or
|
||||
$relativePath.EndsWith(".yml", [System.StringComparison]::OrdinalIgnoreCase) -or
|
||||
$relativePath.EndsWith(".yaml", [System.StringComparison]::OrdinalIgnoreCase) -or
|
||||
$name.Equals("Dockerfile", [System.StringComparison]::OrdinalIgnoreCase) -or
|
||||
$name.StartsWith("Dockerfile.", [System.StringComparison]::OrdinalIgnoreCase) -or
|
||||
$name.EndsWith(".Dockerfile", [System.StringComparison]::OrdinalIgnoreCase)
|
||||
if (-not $mustBeLf) {
|
||||
continue
|
||||
}
|
||||
$absolutePath = Join-Path $RepositoryRoot $relativePath
|
||||
$bytes = [System.IO.File]::ReadAllBytes($absolutePath)
|
||||
if ($bytes -contains [byte]0x0D) {
|
||||
$offenders.Add($relativePath)
|
||||
}
|
||||
}
|
||||
if ($offenders.Count -ne 0) {
|
||||
throw "CR byte 0x0D found in tracked LF contract files: $($offenders -join ', ')"
|
||||
}
|
||||
|
||||
$temporaryRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("thothii-windows-contract-" + [guid]::NewGuid().ToString("N"))
|
||||
$savedEnvironment = @{
|
||||
THT_WORKSPACE_GIT_REMOTE = $env:THT_WORKSPACE_GIT_REMOTE
|
||||
PI_AUTH_FILE = $env:PI_AUTH_FILE
|
||||
THT_SECRETS_FILE = $env:THT_SECRETS_FILE
|
||||
}
|
||||
try {
|
||||
[System.IO.Directory]::CreateDirectory($temporaryRoot) | Out-Null
|
||||
$piAuth = Join-Path $temporaryRoot "pi-auth.json"
|
||||
$secrets = Join-Path $temporaryRoot "thothii.secrets"
|
||||
[System.IO.File]::WriteAllText($piAuth, "{}`n", [System.Text.UTF8Encoding]::new($false))
|
||||
[System.IO.File]::WriteAllText($secrets, "THT_MODEL_API_KEY=windows-contract`n", [System.Text.UTF8Encoding]::new($false))
|
||||
|
||||
$env:THT_WORKSPACE_GIT_REMOTE = "https://git.example.invalid/platform/thoth-workspaces.git"
|
||||
$env:PI_AUTH_FILE = $piAuth
|
||||
$env:THT_SECRETS_FILE = $secrets
|
||||
$composeFiles = @(
|
||||
"--project-directory", $RepositoryRoot,
|
||||
"-f", (Join-Path $RepositoryRoot "compose.yaml"),
|
||||
"-f", (Join-Path $RepositoryRoot "deploy/compose.local.yaml")
|
||||
)
|
||||
$services = @(& docker compose @composeFiles config --services)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Docker Compose could not render the Windows clone"
|
||||
}
|
||||
if ((($services | Sort-Object) -join ",") -ne "core,frontend") {
|
||||
throw "rendered Windows stack must contain exactly core and frontend"
|
||||
}
|
||||
& docker compose @composeFiles config --quiet
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Docker Compose rejected the Windows clone"
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ThothctlPath)) {
|
||||
$ThothctlPath = Join-Path $RepositoryRoot "dist/thothctl/thothctl-windows-amd64.exe"
|
||||
}
|
||||
$ThothctlPath = [System.IO.Path]::GetFullPath($ThothctlPath)
|
||||
if (-not [System.IO.File]::Exists($ThothctlPath)) {
|
||||
throw "Windows thothctl binary is missing: $ThothctlPath"
|
||||
}
|
||||
& $ThothctlPath --help | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Windows thothctl invocation failed"
|
||||
}
|
||||
}
|
||||
finally {
|
||||
foreach ($name in $savedEnvironment.Keys) {
|
||||
[System.Environment]::SetEnvironmentVariable($name, $savedEnvironment[$name], "Process")
|
||||
}
|
||||
if ([System.IO.Directory]::Exists($temporaryRoot)) {
|
||||
Remove-Item -LiteralPath $temporaryRoot -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output "Windows clone, LF-byte, Compose render, and thothctl invocation contracts passed."
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
root="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
# shellcheck source=./unified-deployment-smoke.sh
|
||||
source "$root/scripts/unified-deployment-smoke.sh"
|
||||
|
||||
task13_smoke_main update
|
||||
Executable
+1031
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user