Skip to content

release: 1.0.0 - #31

Merged
StuartMeeks merged 1 commit into
mainfrom
release/1.0.0
Aug 22, 2026
Merged

release: 1.0.0#31
StuartMeeks merged 1 commit into
mainfrom
release/1.0.0

Conversation

@StuartMeeks

Copy link
Copy Markdown
Owner

Stacked on #30 (which is stacked on #29) — retargets automatically as those merge. Merge order: #29#30 → this.

First stable release. The public surface becomes a SemVer commitment: changing it afterwards requires a 2.0.0.

Breaking — for implementers only

IUpdateSource, IUpdateChecker and ISelfUpdater each carried an overload pair in which the abstract member was the one without the prerelease override, and the override-carrying member was a default interface implementation that discarded its argument:

// before 1.0.0
Task<RemoteRelease?> GetLatestAsync(string? channel, CancellationToken ct);           // abstract
Task<RemoteRelease?> GetLatestAsync(string? channel, bool? ovr, CancellationToken ct) // default
    => GetLatestAsync(channel, ct);                                                   // ...drops ovr

A custom IUpdateSource implementing the abstract member — the only one it was obliged to implement — compiled cleanly, ran, and silently ignored update --prerelease.

Now inverted: the override-carrying method is abstract, the no-override overload is the default and passes null. There is nothing left for an implementation to drop the override in.

Interface Now abstract Now the default overload
IUpdateSource GetLatestAsync(string?, bool?, CancellationToken) GetLatestAsync(string?, CancellationToken)
IUpdateChecker CheckAsync(bool?, CancellationToken) CheckAsync(CancellationToken)
ISelfUpdater GetLatestReleaseAsync(bool?, CancellationToken) GetLatestReleaseAsync(CancellationToken)

Callers are unaffected. Both overloads still exist with identical signatures, so every existing call site compiles and binds exactly as before. Only code that implements one of the three interfaces has to change, and the change is adding the bool? includePrereleasesOverride parameter to the method it already has and honouring it.

Package validation does not flag this, and that is expected rather than a gap: the API shape is unchanged — only which member carries the body moved, which an API-surface comparison cannot see. It passes against the 0.3.1 baseline. The break is a source and runtime break for implementers, which is why it is called out this prominently in the changelog rather than left to PKV.

Also in this PR

  • HttpManifestSource flipped so its real logic sits on the override-carrying method. It still ignores the override — correct for a single-release manifest, and now documented on the method itself rather than on the delegating stub.
  • InterfaceDefaultsTests implements each interface with only its abstract member and asserts the override arrives. If the abstract member ever moves back, the test project stops compiling.
  • README's custom-source example carries the new signature.
  • PackageValidationBaselineVersion 0.3.00.3.1. It was stale — 0.3.1 shipped to nuget.org on 2026-08-19.
  • CHANGELOG [Unreleased] cut to [1.0.0] — 2026-08-21, with the Unreleased/1.0.0 compare and tag link refs added.

Verification

Release build: 0 warnings, 0 errors. dotnet test --configuration Release: 408 passed, 0 failed (204 × net8.0/net10.0), up from 392 with the new regression tests.

Package inspected: 1.0.0, lib/net8.0 + lib/net10.0, per-TFM floors intact (net8 8.0.2/8.0.1, net10 10.0.11), license expression, icon, readme and repository metadata all present.

No tag has been pushed. Publishing is tag-gated; tag v1.0.0 only after this merges.

🤖 Generated with Claude Code

@StuartMeeks
StuartMeeks force-pushed the chore/codeql-conformance branch from 5e1a400 to c66ce09 Compare August 21, 2026 22:59
Base automatically changed from chore/codeql-conformance to main August 22, 2026 00:14
First stable release. Version 0.3.1 -> 1.0.0, PackageValidationBaselineVersion
0.3.0 -> 0.3.1 (it was stale — 0.3.1 shipped to nuget.org on 2026-08-19), and
CHANGELOG [Unreleased] cut to [1.0.0] with the compare/tag link refs added.

Breaking, for implementers only: the prerelease-override overloads on
IUpdateSource, IUpdateChecker and ISelfUpdater are inverted.

Before, the abstract member was the one WITHOUT the override, and the
override-carrying member was a default interface implementation that discarded
its argument. A custom IUpdateSource that implemented the abstract member — the
only one it was obliged to implement — compiled, ran, and silently ignored
`update --prerelease`.

Now the override-carrying method is abstract and the no-override overload is
the default implementation passing null. There is nothing left for an
implementation to drop the override in.

- IUpdateSource.GetLatestAsync(string?, bool?, CancellationToken) now abstract
- IUpdateChecker.CheckAsync(bool?, CancellationToken) now abstract
- ISelfUpdater.GetLatestReleaseAsync(bool?, CancellationToken) now abstract

Callers are unaffected: both overloads still exist with identical signatures,
so existing call sites compile and bind unchanged. Package validation does not
flag it for the same reason — only which member carries the body moved, and
that is invisible to an API-shape comparison. It passes against the 0.3.1
baseline.

HttpManifestSource is flipped so its real logic sits on the override-carrying
method; it still ignores the override, which is correct for a single-release
manifest and is now documented on the method itself. The other two built-in
sources and both pipeline types already had the right shape.

InterfaceDefaultsTests implements each interface with only its abstract member
and asserts the override arrives, so moving the abstract member back breaks the
build. The README custom-source example carries the new signature.

Release build: 0 warnings. 408 tests (204 × net8.0/net10.0) pass, up from 392.
Package verified: 1.0.0, lib/net8.0 + lib/net10.0, per-TFM floors intact
(net8 8.0.2/8.0.1, net10 10.0.11), license/icon/readme/repository present.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@StuartMeeks
StuartMeeks merged commit 9177cd5 into main Aug 22, 2026
9 checks passed
@StuartMeeks
StuartMeeks deleted the release/1.0.0 branch August 22, 2026 00:23
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.

1 participant