Skip to content

fix: use fallback defaults instead of hardcoded overrides for runtime options#401

Merged
JusterZhu merged 4 commits into
masterfrom
fix/fallback-defaults-runtime-options
May 25, 2026
Merged

fix: use fallback defaults instead of hardcoded overrides for runtime options#401
JusterZhu merged 4 commits into
masterfrom
fix/fallback-defaults-runtime-options

Conversation

@JusterZhu

Copy link
Copy Markdown
Collaborator

Summary

Fixes unconditional hardcoded overrides in strategy and bootstrap methods that silently overwrite user-configured UpdateOptions values with defaults. Also removes dead code and adds missing extension injection tests.

Closes #400

Changes

Source files (5)

File Change
GeneralUpdateBootstrap.cs ApplyRuntimeOptions(): replace = GetOption(...) with ??= or conditional assignment to preserve Upgrade path values from InitializeFromEnvironment()
ClientUpdateStrategy.cs Remove dead if (true) branch; delete redundant ApplyRuntimeOptions(encoding, timeout) override; add ApplyStrategyDefaults() with ??= fallback; fix Format = "ZIP"Format = _configInfo.Format ?? "ZIP"
UpgradeUpdateStrategy.cs Encoding = UTF8Encoding ??= UTF8; Format = ZIPFormat ??= ZIP
OSSUpdateStrategy.cs const int TimeOut = 60ResolveTimeout() reads _configInfo.DownloadTimeOut with fallback
BootstrapFullParameterMatrixTests.cs +15 tests covering all 14 extension injection methods + chained injection

Test results

  • ✅ 320/320 tests pass (0 regressions)

Key pattern change

// Before: overwrites user config and Upgrade path values
_configInfo.Encoding = GetOption(UpdateOptions.Encoding);  // = UTF8 (default)

// After: only applies when not already set
_configInfo.Encoding ??= GetOption(UpdateOptions.Encoding); // only if null

This is critical for the Upgrade path where InitializeFromEnvironment() already sets Encoding/Format/DownloadTimeOut from the client's ProcessInfo.

… options

Closes #400

- Remove dead 'if (true)' branch in ClientUpdateStrategy.ExecuteWorkflowAsync()
  (silent routing now handled by GeneralUpdateBootstrap.LaunchSilentAsync())
- Replace unconditional '= GetOption(...)' with '??=' or conditional
  assignment in Bootstrap.ApplyRuntimeOptions() to avoid overwriting
  InitializeFromEnvironment() values in the Upgrade path
- Replace '= Encoding.UTF8' / '= Format.ZIP' / '= 60' with '??=' fallback
  pattern in ClientUpdateStrategy, UpgradeUpdateStrategy, OSSUpdateStrategy
- Fix hardcoded 'Format = "ZIP"' in ClientUpdateStrategy ProcessInfo builder
- Add 15 hook/extension injection tests to BootstrapFullParameterMatrixTests
  covering all 14 extension methods + chained injection
Copilot AI review requested due to automatic review settings May 25, 2026 06:06
Bootstrap.ApplyRuntimeOptions() is the single source of truth for reading
UpdateOptions and applying defaults. Strategy classes should not duplicate
this logic.

- Remove ApplyStrategyDefaults() from ClientUpdateStrategy
- Remove ApplyRuntimeOptions() from UpgradeUpdateStrategy
- Inline OSSUpdateStrategy timeout fallback

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to stop silently overwriting user-specified UpdateOptions/environment-populated runtime settings by switching from unconditional assignments to fallback-default behavior in bootstrapping and strategy runtime option handling, while also removing dead code and expanding bootstrap extension-injection test coverage.

Changes:

  • Update bootstrap/strategies to apply runtime options via null-coalescing / conditional assignment rather than unconditional overrides.
  • Simplify ClientUpdateStrategy workflow by removing dead branching and centralizing “fallback defaults” in ApplyStrategyDefaults().
  • Add tests covering all extension injection methods in the bootstrap parameter matrix.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs Changes ApplyRuntimeOptions() to use fallback-default patterns instead of unconditional overrides.
src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs Removes dead workflow branch and adds strategy-level fallback defaults; adjusts ProcessInfo format mapping.
src/c#/GeneralUpdate.Core/Strategy/UpgradeUpdateStrategy.cs Switches runtime option defaults to null-coalescing assignments.
src/c#/GeneralUpdate.Core/Strategy/OSSUpdateStrategy.cs Uses config-driven timeout with a default fallback instead of a hardcoded constant.
tests/CoreTest/Bootstrap/BootstrapFullParameterMatrixTests.cs Adds coverage for bootstrap extension injection methods and chaining.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +302 to +309
// Download behaviour — preserve existing values (Upgrade path or property initializers)
// and only apply UpdateOptions when the current value is at its unset default
if (_configInfo.MaxConcurrency <= 0)
_configInfo.MaxConcurrency = GetOption(UpdateOptions.MaxConcurrency);
if (_configInfo.RetryCount <= 0)
_configInfo.RetryCount = GetOption(UpdateOptions.RetryCount);
if (_configInfo.RetryInterval <= TimeSpan.Zero)
_configInfo.RetryInterval = GetOption(UpdateOptions.RetryInterval);
Comment on lines +290 to +295
// Core runtime — use ??= so Upgrade path (InitializeFromEnvironment) values
// are not overwritten by GetOption defaults
_configInfo.Encoding ??= GetOption(UpdateOptions.Encoding);
_configInfo.Format ??= GetOption(UpdateOptions.Format);
if (_configInfo.DownloadTimeOut <= 0)
_configInfo.DownloadTimeOut = GetOption(UpdateOptions.DownloadTimeout) ?? 60;
private void ApplyStrategyDefaults()
{
_configInfo!.Encoding ??= Encoding.UTF8;
_configInfo.Format ??= "ZIP";
Comment on lines 180 to 187
var downloadVersions = downloadPlan.Assets.Select(a => new VersionInfo
{
Name = a.Name,
Hash = a.SHA256,
Url = a.Url,
Version = a.Version,
Format = "ZIP"
Format = _configInfo.Format ?? "ZIP"
}).ToList();
Comment on lines 120 to 122
_configInfo.Format ??= Format.ZIP;
}

private const int DefaultTimeOut = 60;

private int ResolveTimeout()
=> _configInfo.DownloadTimeOut > 0 ? _configInfo.DownloadTimeOut : DefaultTimeOut;
JusterZhu added 2 commits May 25, 2026 14:25
Remove the broken '<= 0' guards on MaxConcurrency/RetryCount/RetryInterval.
These guards checked C# type defaults (0) but GlobalConfigInfo property
initializers already set functionally reasonable values (3, 3, 1s), so
the guards would never trigger in the Client path — user-configured
values via .Option(MaxConcurrency, 8) were silently ignored.

Only Encoding/Format/DownloadTimeOut need ??= protection — they are the
only options that InitializeFromEnvironment() may populate on the
Upgrade path before ApplyRuntimeOptions() runs.
UpdateOptions.Format default value is "ZIP", but pipeline constructs zip
file paths as `{name}{format}` and CompressProvider.Decompress switches
on Format.ZIP (".zip"). If Format stays "ZIP", paths become "MyAppZIP"
and decompression fails.

Previously, ClientUpdateStrategy.ApplyRuntimeOptions(encoding, timeout)
silently overwrote this with Format.ZIP (".zip"). After removing that
redundant override in PR #401, the bug becomes visible.

Normalize to Format.ZIP in Bootstrap.ApplyRuntimeOptions() — the single
source of truth for runtime options.
@JusterZhu JusterZhu merged commit 41b617d into master May 25, 2026
3 checks passed
@JusterZhu JusterZhu deleted the fix/fallback-defaults-runtime-options branch May 25, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: use fallback defaults instead of hardcoded overrides for runtime options

2 participants