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
@@ -62,6 +62,7 @@
ContinueOnError="true"
StandardErrorImportance="low">
<Output TaskParameter="ConsoleOutput" PropertyName="DcGitCommitLong" />
<Output TaskParameter="ExitCode" PropertyName="DcGitExitCodeLong" />
</Exec>
<Exec Command="git rev-parse --short HEAD"
@@ -70,6 +71,7 @@
ContinueOnError="true"
StandardErrorImportance="low">
<Output TaskParameter="ConsoleOutput" PropertyName="DcGitCommitShort" />
<Output TaskParameter="ExitCode" PropertyName="DcGitExitCodeShort" />
</Exec>
<PropertyGroup>
@@ -96,8 +98,18 @@
</PropertyGroup>
<PropertyGroup>
<DcGitCommitLong Condition="'$(DcGitCommitLong)' == ''">UNKNOWN_COMMIT</DcGitCommitLong>
<DcGitCommitShort Condition="'$(DcGitCommitShort)' == ''">UNKNOWN</DcGitCommitShort>
<DcGitExitCodeLong Condition="'$(DcGitExitCodeLong)' == ''">1</DcGitExitCodeLong>
<DcGitExitCodeShort Condition="'$(DcGitExitCodeShort)' == ''">1</DcGitExitCodeShort>
<!--
ConsoleToMSBuild faengt auch stderr ein. Wenn git fehlschlaegt (z. B.
ausserhalb einer Git-Arbeitskopie, Quell-Tarball, Docker-Build ohne .git),
landet die Fehlermeldung (z. B. "fatal: Kein Git-Repository...") in
der Eigenschaft. Wir pruefen daher ExitCode und validieren die Ausgabe
per Hex-Regex, um verlaesslich auf UNKNOWN_COMMIT/UNKNOWN zurueckzufallen.
-->
<DcGitCommitLong Condition="'$(DcGitExitCodeLong)' != '0' Or !$([System.Text.RegularExpressions.Regex]::IsMatch('$(DcGitCommitLong.Trim())', '^[0-9a-fA-F]{40}$'))">UNKNOWN_COMMIT</DcGitCommitLong>
<DcGitCommitShort Condition="'$(DcGitExitCodeShort)' != '0' Or !$([System.Text.RegularExpressions.Regex]::IsMatch('$(DcGitCommitShort.Trim())', '^[0-9a-fA-F]{7,40}$'))">UNKNOWN</DcGitCommitShort>
<!-- Zeilenumbrueche aus der Git-Ausgabe entfernen, sie wuerden das Literal sprengen. -->
<DcGitCommitLong>$(DcGitCommitLong.Trim())</DcGitCommitLong>
<DcGitCommitShort>$(DcGitCommitShort.Trim())</DcGitCommitShort>
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
@@ -308,20 +308,24 @@ namespace Deploymentcenter.Client
: directory!;
string candidate = Path.Combine(dir, AgentFileName);
if (File.Exists(candidate))
return candidate;
if (!File.Exists(candidate))
return null;
// Ein Paket, das fuer die jeweils andere Plattform gebaut wurde,
// bringt den Agenten unter dem dortigen Namen mit. Lieber finden
// als daran scheitern.
foreach (string alternative in new[] { "update-agent", "update-agent.exe" })
// Ist die Starterdatei ein Apphost eines Framework-abhaengigen Builds
// (erkennbar an einer runtimeconfig.json oder deps.json daneben),
// muss zwingend auch die verwaltete .dll vorhanden sein.
// Ohne diese wuerde Process.Start zwar gelingen, der Prozess aber
// unmittelbar mit "The application to execute does not exist" abbrechen.
string dllCandidate = Path.Combine(dir, "update-agent.dll");
string runtimeConfig = Path.Combine(dir, "update-agent.runtimeconfig.json");
string depsJson = Path.Combine(dir, "update-agent.deps.json");
if ((File.Exists(runtimeConfig) || File.Exists(depsJson)) && !File.Exists(dllCandidate))
{
string path = Path.Combine(dir, alternative);
if (File.Exists(path))
return path;
return null;
}
return null;
return candidate;
}
/// <summary>