feat: UpdateAgent Selbstaktualisierung & kopflose Installation, .NET 10 Migration, Backend- & SDK-Fixes

- .NET 10 Migration: Alle .NET-Projekte auf net10.0 umgestellt (#459)
- Client-SDK: ResolveAgentPath bereinigt und DLL-Pruefung ergaenzt (#458)
- Packager: Commit-Ermittlung aus publishDir / Assembly InformationalVersion (#456)
- BuildInfo.targets: ExitCode-Abfang und Regex-Validierung gegen Git-Fehlertexte (#363)
- UpdateService: Re-Publish erhaelt bestehende Manifeste und Werte (#457)
- Bugtracker API: on_roadmap-Filter in manage?action=list durchgereicht (#349)
- Watchdog API: project_slug-Filter in GET /status ergaenzt (#420)
- UpdateService API: no_release_for_platform mit verfuegbaren Plattformen (#421)
- Bugtracker Core: Fehler-Normalisierung gegen zersplitterte error_hashes (#419)
- UpdateAgent: Kopfloser Installationsmodus via --answers (#89)
- Installer & Agent: Automatische Selbstaktualisierung beim Start
- Tooling: AGENTS.md, CLAUDE.md und Standalone-CLI scripts/dc.py hinzugefuegt
This commit is contained in:
Deploymentcenter Bot
2026-09-02 23:43:37 +02:00
parent 8447b2d10a
commit 087f4392a9
26 changed files with 1582 additions and 67 deletions
@@ -282,8 +282,9 @@ namespace Deploymentcenter.Packager
string manifestJsonPath = Path.Combine(outputTempDir, "manifest.json");
string sha256FilePath = Path.Combine(outputTempDir, "package.tar.gz.sha256");
string gitCommit = GetGitCommitLong();
string gitCommitShort = GetGitCommitShort();
string? mainAssemblyPath = ResolveMainAssembly(publishDir, project, GetArg(args, "--main-assembly"));
var (gitCommit, gitCommitShort) = DetermineGitCommit(publishDir, mainAssemblyPath);
Console.WriteLine($"[INFO] Git-Commit : {gitCommitShort} ({gitCommit})");
string buildDateUtc = DateTime.UtcNow.ToString("o");
var packageManifest = new PackageManifest
@@ -1156,32 +1157,79 @@ namespace Deploymentcenter.Packager
Console.WriteLine();
}
static string GetGitCommitLong()
static (string CommitLong, string CommitShort) DetermineGitCommit(string publishDir, string? mainAssemblyPath)
{
try
string? assemblyCommit = null;
if (!string.IsNullOrWhiteSpace(mainAssemblyPath) && File.Exists(mainAssemblyPath))
{
var psi = new ProcessStartInfo("git", "rev-parse HEAD") { RedirectStandardOutput = true, UseShellExecute = false };
using var p = Process.Start(psi);
string outStr = p?.StandardOutput.ReadToEnd().Trim() ?? "";
p?.WaitForExit();
if (!string.IsNullOrEmpty(outStr)) return outStr;
try
{
var info = FileVersionInfo.GetVersionInfo(mainAssemblyPath);
string? prodVer = info.ProductVersion?.Trim();
if (!string.IsNullOrWhiteSpace(prodVer) && prodVer.Contains('+'))
{
string candidate = prodVer.Split('+')[1].Trim();
if (System.Text.RegularExpressions.Regex.IsMatch(candidate, "^[0-9a-fA-F]{7,40}$"))
{
assemblyCommit = candidate;
}
}
}
catch { }
}
catch { }
return "UNKNOWN_COMMIT";
}
static string GetGitCommitShort()
{
string? gitCommitFromDir = null;
try
{
var psi = new ProcessStartInfo("git", "rev-parse --short HEAD") { RedirectStandardOutput = true, UseShellExecute = false };
var psi = new ProcessStartInfo("git", "rev-parse HEAD")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = Directory.Exists(publishDir) ? publishDir : Environment.CurrentDirectory
};
using var p = Process.Start(psi);
string outStr = p?.StandardOutput.ReadToEnd().Trim() ?? "";
p?.WaitForExit();
if (!string.IsNullOrEmpty(outStr)) return outStr;
if (p?.ExitCode == 0 && System.Text.RegularExpressions.Regex.IsMatch(outStr, "^[0-9a-fA-F]{40}$"))
{
gitCommitFromDir = outStr;
}
}
catch { }
return "UNKNOWN";
// Bevorzuge Assembly-Commit (falls vorhanden), da er den tatsaechlich kompilierten Stand repraesentiert
string commitLong = assemblyCommit ?? gitCommitFromDir ?? "UNKNOWN_COMMIT";
string commitShort;
if (commitLong != "UNKNOWN_COMMIT" && commitLong.Length >= 7)
{
commitShort = commitLong.Substring(0, 7);
}
else
{
commitShort = "UNKNOWN";
try
{
var psiShort = new ProcessStartInfo("git", "rev-parse --short HEAD")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = Directory.Exists(publishDir) ? publishDir : Environment.CurrentDirectory
};
using var pShort = Process.Start(psiShort);
string outStrShort = pShort?.StandardOutput.ReadToEnd().Trim() ?? "";
pShort?.WaitForExit();
if (pShort?.ExitCode == 0 && System.Text.RegularExpressions.Regex.IsMatch(outStrShort, "^[0-9a-fA-F]{7,40}$"))
{
commitShort = outStrShort;
}
}
catch { }
}
return (commitLong, commitShort);
}
}
}