Release build uploads new mod versions to the keymaster automatically

release.ps1 (needs MSCO_RELEASE_TOKEN), changelog from CHANGELOG.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 22:12:46 +02:00
co-authored by Claude Opus 5.5
parent 3ea0e8ebca
commit 15c9ee548d
3 changed files with 214 additions and 128 deletions
+5 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
@@ -149,4 +149,8 @@ copy "$(TargetPath)" "C:\Users\nico\Documents\MySummerCar\Mods\Mods" /y
) )
</PostBuildEvent> </PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- Release-Build: neue Version automatisch auf den Keymaster laden (nur mit Release-Token, siehe release.ps1) -->
<Target Name="MscoRelease" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
<Exec Command="powershell -NoProfile -ExecutionPolicy Bypass -File &quot;$(MSBuildProjectDirectory)\release.ps1&quot; -Product mod -File &quot;$(TargetPath)&quot;" ContinueOnError="true" />
</Target>
</Project> </Project>
+3
View File
@@ -96,6 +96,9 @@ msbuild MSCO.csproj -p:Configuration=Release
- **Großes Update** (Protokoll inkompatibel geändert): `ProtocolVersion` in `MSCO.cs` **und** `GameServer.ModVersion` im - **Großes Update** (Protokoll inkompatibel geändert): `ProtocolVersion` in `MSCO.cs` **und** `GameServer.ModVersion` im
Server erhöhen (z.B. `2.9`), `ModVersion` auf `2.9.0`. Dann brauchen alle die neue Mod und den neuen Server. Server erhöhen (z.B. `2.9`), `ModVersion` auf `2.9.0`. Dann brauchen alle die neue Mod und den neuen Server.
- Verglichen werden immer nur die ersten zwei Stellen; übers Netz geht nur die Netzwerk-Version. - Verglichen werden immer nur die ersten zwei Stellen; übers Netz geht nur die Netzwerk-Version.
- **Automatisch hochladen**: Ist lokal `MSCO_RELEASE_TOKEN` gesetzt (= `RELEASE_TOKEN` des Keymasters, oder in
`%AppData%\MSCO␍elease-token.txt`), lädt jeder Release-Build eine neue Version selbst auf den Keymaster
(`release.ps1`, Changelog aus dem passenden Abschnitt in `CHANGELOG.md`). Gibt es die Version schon, passiert nichts.
## Aufbau ## Aufbau
+79
View File
@@ -0,0 +1,79 @@
# Neue Version automatisch auf den Keymaster hochladen (msco.mbm.wtf -> /download, Launcher-Updates).
# Läuft nach dem Release-Build von selbst (MSCO.csproj bzw. MSCO.Launcher.csproj) - oder von Hand:
# powershell -ExecutionPolicy Bypass -File release.ps1 -Product mod -File bin\Release\MSCO.dll
#
# Braucht den Release-Token des Keymasters (RELEASE_TOKEN in dessen .env), lokal als Umgebungsvariable
# MSCO_RELEASE_TOKEN oder in %AppData%\MSCO\release-token.txt. Ohne Token wird nichts hochgeladen.
# Gibt es die Version auf dem Keymaster schon, passiert nichts - also einfach die Version erhöhen und bauen.
param(
[Parameter(Mandatory = $true)][ValidateSet("mod", "launcher")][string]$Product,
[Parameter(Mandatory = $true)][string]$File,
[string]$Version = "",
[string]$Changelog = ""
)
$ErrorActionPreference = "Stop"
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$token = $env:MSCO_RELEASE_TOKEN
$tokenFile = Join-Path $env:APPDATA "MSCO\release-token.txt"
if (-not $token -and (Test-Path $tokenFile)) { $token = (Get-Content $tokenFile -Raw).Trim() }
if (-not $token) {
Write-Host "MSCO release: no release token (MSCO_RELEASE_TOKEN or $tokenFile) - not uploading."
exit 0
}
$keymaster = if ($env:MSCO_KEYMASTER) { $env:MSCO_KEYMASTER.TrimEnd("/") } else { "https://msco.mbm.wtf" }
if (-not (Test-Path $File)) { Write-Host "MSCO release: $File not found"; exit 1 }
# Version: aus MSCO.cs (Mod) bzw. aus der Datei (Produktversion)
if (-not $Version) {
$source = Join-Path $here "MSCO.cs"
if ($Product -eq "mod" -and (Test-Path $source)) {
$m = Select-String -Path $source -Pattern 'ModVersion\s*=\s*"([^"]+)"' | Select-Object -First 1
if ($m) { $Version = $m.Matches[0].Groups[1].Value }
}
if (-not $Version) { $Version = ((Get-Item $File).VersionInfo.ProductVersion -split '\+')[0] }
}
# Changelog: Abschnitt "## <Version>" aus CHANGELOG.md (Text ohne Markdown, gekürzt)
if (-not $Changelog) {
$log = Join-Path $here "CHANGELOG.md"
if (Test-Path $log) {
$lines = Get-Content $log -Encoding UTF8
$start = [Array]::FindIndex($lines, [Predicate[string]] { param($l) $l -match "^##\s+$([regex]::Escape($Version))\b" })
if ($start -ge 0) {
$text = @()
for ($i = $start + 1; $i -lt $lines.Count -and $lines[$i] -notmatch '^##\s'; $i++) {
$l = $lines[$i].Trim() -replace '\*\*', '' -replace '`', ''
if ($l) { $text += $l }
}
$Changelog = ($text -join " ")
if ($Changelog.Length -gt 3500) { $Changelog = $Changelog.Substring(0, 3500) + " …" }
}
}
}
Add-Type -AssemblyName System.Net.Http
$client = New-Object System.Net.Http.HttpClient
$client.Timeout = [TimeSpan]::FromMinutes(10)
$client.DefaultRequestHeaders.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $token)
$form = New-Object System.Net.Http.MultipartFormDataContent
$form.Add((New-Object System.Net.Http.StringContent($Product)), "product")
$form.Add((New-Object System.Net.Http.StringContent($Version)), "version")
$form.Add((New-Object System.Net.Http.StringContent($Changelog)), "changelog")
$bytes = [System.IO.File]::ReadAllBytes((Resolve-Path $File))
$form.Add((New-Object System.Net.Http.ByteArrayContent(,$bytes)), "file", [System.IO.Path]::GetFileName($File))
try {
$res = $client.PostAsync("$keymaster/api/releases/upload", $form).GetAwaiter().GetResult()
$body = $res.Content.ReadAsStringAsync().GetAwaiter().GetResult()
} catch {
Write-Host "MSCO release: keymaster not reachable ($($_.Exception.Message)) - not uploaded"
exit 0
}
switch ([int]$res.StatusCode) {
200 { Write-Host "MSCO release: $Product $Version uploaded to $keymaster" }
409 { Write-Host "MSCO release: $Product $Version is already on the keymaster - raise the version to publish a new one" }
default { Write-Host "MSCO release: upload failed (HTTP $([int]$res.StatusCode)): $body" }
}
exit 0