Files
BSO-Mod/release.ps1
T
MrMahoandClaude Opus 5.5 35f2d1330d Erste Version
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 17:26:23 +01:00

46 lines
2.9 KiB
PowerShell

# Signiert ein Release und laedt es auf den BSO Master (wie release.ps1 bei MSCO).
# .\release.ps1 -Product mod|launcher|server -Version 0.2.0 -File dist\BSO-Mod.zip [-Changelog "..."]
# Braucht: Release-Schluessel (BSO-Launcher\new-release-key.ps1), BSO_RELEASE_TOKEN (= RELEASE_TOKEN des Masters),
# optional BSO_MASTER_URL (Standard https://bso.mbm.wtf).
# Signiert wird "BSO-RELEASE|produkt|version|sha256" - der Launcher prueft das mit dem eingebauten oeffentlichen Schluessel.
param(
[Parameter(Mandatory)][ValidateSet("mod", "launcher", "server")][string]$Product,
[Parameter(Mandatory)][string]$Version,
[Parameter(Mandatory)][string]$File,
[string]$Changelog = ""
)
$ErrorActionPreference = "Stop"
Add-Type -AssemblyName System.Security
Add-Type -AssemblyName System.Net.Http
$master = ($env:BSO_MASTER_URL, "https://bso.mbm.wtf" | Where-Object { $_ } | Select-Object -First 1).TrimEnd('/')
$token = $env:BSO_RELEASE_TOKEN
if (-not $token) { Write-Host "BSO_RELEASE_TOKEN nicht gesetzt - nicht hochgeladen"; return }
$keyFile = Join-Path $env:APPDATA "BSO\release-key.dpapi"
if (-not (Test-Path $keyFile)) { throw "Kein Release-Schluessel ($keyFile) - erst new-release-key.ps1 im BSO-Launcher-Repo" }
$data = [IO.File]::ReadAllBytes((Resolve-Path $File))
$sha = ([System.Security.Cryptography.SHA256]::Create().ComputeHash($data) | ForEach-Object { $_.ToString("x2") }) -join ""
$private = [System.Security.Cryptography.ProtectedData]::Unprotect([IO.File]::ReadAllBytes($keyFile), $null,
[System.Security.Cryptography.DataProtectionScope]::CurrentUser)
$rsa = [System.Security.Cryptography.RSA]::Create()
$rsa.FromXmlString([Text.Encoding]::UTF8.GetString($private))
$message = [Text.Encoding]::UTF8.GetBytes("BSO-RELEASE|$Product|$Version|$sha")
$signature = [Convert]::ToBase64String($rsa.SignData($message, [System.Security.Cryptography.HashAlgorithmName]::SHA256,
[System.Security.Cryptography.RSASignaturePadding]::Pkcs1))
$http = New-Object System.Net.Http.HttpClient
$http.Timeout = [TimeSpan]::FromMinutes(10)
$http.DefaultRequestHeaders.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $token)
$form = New-Object System.Net.Http.MultipartFormDataContent
foreach ($pair in @(@("product", $Product), @("version", $Version), @("changelog", $Changelog), @("signature", $signature))) {
$form.Add((New-Object System.Net.Http.StringContent($pair[1])), "`"$($pair[0])`"")
}
$content = New-Object System.Net.Http.ByteArrayContent(, $data)
$form.Add($content, "`"file`"", "`"$(Split-Path $File -Leaf)`"")
$res = $http.PostAsync("$master/api/releases/upload", $form).Result
$body = $res.Content.ReadAsStringAsync().Result
if ($res.StatusCode -eq [Net.HttpStatusCode]::Conflict) { Write-Host "$Product $Version gibt es schon auf $master"; return }
if (-not $res.IsSuccessStatusCode) { throw "Hochladen fehlgeschlagen ($([int]$res.StatusCode)): $body" }
Write-Host "$Product $Version hochgeladen nach $master (sha256 $sha)"