From 92f246be951aaa54ae17dcb2349bbac2ae1ec67b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:17:47 +0000 Subject: [PATCH 1/2] Initial plan From d753c2442789f6cc6b8f08e36bcdcd092bd5f96f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:20:30 +0000 Subject: [PATCH 2/2] Preserve update log in precheck info Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com> --- .../Download/Models/DownloadAsset.cs | 5 +- .../Download/Sources/HttpDownloadSource.cs | 5 +- .../Strategy/ClientStrategy.cs | 1 + .../CoreTest/Download/DownloadModelsTests.cs | 7 ++- .../Sources/HttpDownloadSourceTests.cs | 24 ++++++++ .../Strategy/ClientStrategyUpdateLogTests.cs | 61 +++++++++++++++++++ 6 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 tests/CoreTest/Strategy/ClientStrategyUpdateLogTests.cs diff --git a/src/GeneralUpdate.Core/Download/Models/DownloadAsset.cs b/src/GeneralUpdate.Core/Download/Models/DownloadAsset.cs index 8c406cfb..81f62170 100644 --- a/src/GeneralUpdate.Core/Download/Models/DownloadAsset.cs +++ b/src/GeneralUpdate.Core/Download/Models/DownloadAsset.cs @@ -22,7 +22,10 @@ public record DownloadAsset( int? AppType = null, string? AuthScheme = null, string? AuthToken = null -); +) +{ + public string? UpdateLog { get; init; } +} /// Ordered download plan built from server response. public record DownloadPlan(IReadOnlyList Assets, bool IsForcibly) diff --git a/src/GeneralUpdate.Core/Download/Sources/HttpDownloadSource.cs b/src/GeneralUpdate.Core/Download/Sources/HttpDownloadSource.cs index 9a4e6111..ce7648de 100644 --- a/src/GeneralUpdate.Core/Download/Sources/HttpDownloadSource.cs +++ b/src/GeneralUpdate.Core/Download/Sources/HttpDownloadSource.cs @@ -183,6 +183,9 @@ private static DownloadAsset MapVersionEntry(VersionEntry v) AppType: v.AppType, AuthScheme: v.AuthScheme, AuthToken: v.AuthToken - ); + ) + { + UpdateLog = v.UpdateLog + }; } } diff --git a/src/GeneralUpdate.Core/Strategy/ClientStrategy.cs b/src/GeneralUpdate.Core/Strategy/ClientStrategy.cs index 80d94ff8..610269d2 100644 --- a/src/GeneralUpdate.Core/Strategy/ClientStrategy.cs +++ b/src/GeneralUpdate.Core/Strategy/ClientStrategy.cs @@ -493,6 +493,7 @@ private async Task ExecuteStandardWorkflowAsync() IsFreeze = a.IsFreeze, AppType = a.AppType, PackageType = a.PackageType, + UpdateLog = a.UpdateLog, FallbackFullName = a.FallbackFullName, FallbackFullUrl = a.FallbackFullUrl, FallbackFullHash = a.FallbackFullHash diff --git a/tests/CoreTest/Download/DownloadModelsTests.cs b/tests/CoreTest/Download/DownloadModelsTests.cs index 1852b9af..b6af14b4 100644 --- a/tests/CoreTest/Download/DownloadModelsTests.cs +++ b/tests/CoreTest/Download/DownloadModelsTests.cs @@ -24,6 +24,7 @@ public void DownloadAsset_Defaults_AreSensible() Assert.Equal(DownloadPriority.Normal, asset.Priority); Assert.Equal(0, asset.PackageType); Assert.Null(asset.MinClientVersion); + Assert.Null(asset.UpdateLog); Assert.False(asset.IsForcibly); Assert.False(asset.IsFreeze); } @@ -39,7 +40,10 @@ public void DownloadAsset_FullySpecified_AllPropertiesSet() FallbackFullUrl: "https://cdn/full.zip", FallbackFullHash: "fullhash", IsForcibly: true, IsFreeze: false - ); + ) + { + UpdateLog = "Release notes" + }; Assert.Equal("package.zip", asset.Name); Assert.Equal("https://cdn/pkg.zip", asset.Url); @@ -48,6 +52,7 @@ public void DownloadAsset_FullySpecified_AllPropertiesSet() Assert.Equal("3.0.0", asset.Version); Assert.Equal(DownloadPriority.High, asset.Priority); Assert.Equal("2.0.0", asset.MinClientVersion); + Assert.Equal("Release notes", asset.UpdateLog); Assert.Equal("full-pkg", asset.FallbackFullName); Assert.Equal("https://cdn/full.zip", asset.FallbackFullUrl); Assert.Equal("fullhash", asset.FallbackFullHash); diff --git a/tests/CoreTest/Download/Sources/HttpDownloadSourceTests.cs b/tests/CoreTest/Download/Sources/HttpDownloadSourceTests.cs index 4405147e..574ca124 100644 --- a/tests/CoreTest/Download/Sources/HttpDownloadSourceTests.cs +++ b/tests/CoreTest/Download/Sources/HttpDownloadSourceTests.cs @@ -1,5 +1,7 @@ +using System.Reflection; using GeneralUpdate.Core.Configuration; using GeneralUpdate.Core.Download.Abstractions; +using GeneralUpdate.Core.Download.Models; using GeneralUpdate.Core.Download.Sources; using GeneralUpdate.Core.Security; @@ -103,4 +105,26 @@ public void Implements_IDownloadSource() } #endregion + + #region Mapping + + [Fact] + public void MapVersionEntry_PreservesUpdateLog() + { + var version = new VersionEntry + { + Name = "package.zip", + Url = "https://cdn.example.com/package.zip", + Version = "2.0.0", + UpdateLog = "# 2.0.0\n- Fixed startup issue" + }; + var method = typeof(HttpDownloadSource).GetMethod("MapVersionEntry", + BindingFlags.NonPublic | BindingFlags.Static); + + var asset = Assert.IsType(method!.Invoke(null, new object[] { version })); + + Assert.Equal(version.UpdateLog, asset.UpdateLog); + } + + #endregion } diff --git a/tests/CoreTest/Strategy/ClientStrategyUpdateLogTests.cs b/tests/CoreTest/Strategy/ClientStrategyUpdateLogTests.cs new file mode 100644 index 00000000..7bdebceb --- /dev/null +++ b/tests/CoreTest/Strategy/ClientStrategyUpdateLogTests.cs @@ -0,0 +1,61 @@ +using GeneralUpdate.Core; +using GeneralUpdate.Core.Configuration; +using GeneralUpdate.Core.Download; +using GeneralUpdate.Core.Download.Abstractions; +using GeneralUpdate.Core.Download.Models; +using GeneralUpdate.Core.Strategy; + +namespace CoreTest.Strategy; + +public class ClientStrategyUpdateLogTests +{ + [Fact] + public async Task ExecuteAsync_PrecheckReceivesUpdateLog() + { + var updateLog = "# 2.0.0\n- Preserve release notes"; + UpdateInfoEventArgs? captured = null; + var strategy = new ClientStrategy + { + DownloadSource = new StubDownloadSource(new DownloadAsset( + Name: "package.zip", + Url: "https://cdn.example.com/package.zip", + Size: 1024, + SHA256: "hash", + Version: "2.0.0", + AppType: (int)AppType.Client) + { + UpdateLog = updateLog + }) + }; + + strategy.UseUpdatePrecheck(args => + { + captured = args; + return true; + }); + strategy.Create(new UpdateContext + { + UpdateUrl = "https://api.example.com/update", + ClientVersion = "1.0.0", + AppSecretKey = "key", + MainAppName = "MainApp", + InstallPath = Path.GetTempPath() + }); + + await strategy.ExecuteAsync(); + + Assert.NotNull(captured); + var version = Assert.Single(captured.Info!.Body!); + Assert.Equal(updateLog, version.UpdateLog); + } + + private sealed class StubDownloadSource(DownloadAsset asset) : IDownloadSource + { + public Task ListAsync(CancellationToken token = default) + => Task.FromResult(new DownloadSourceResult + { + Assets = new[] { asset }, + HasMainUpdate = true + }); + } +}