Skip to content

Support numbered prerelease updates - #8

Merged
DysektAI merged 4 commits into
masterfrom
fix/semver-prerelease-updates
Jul 23, 2026
Merged

Support numbered prerelease updates#8
DysektAI merged 4 commits into
masterfrom
fix/semver-prerelease-updates

Conversation

@DysektAI

@DysektAI DysektAI commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

  • Compare complete Semantic Versioning precedence in the in-app updater, including numbered alpha, beta, and RC identifiers.
  • Keep stable installs off prerelease channels while allowing prerelease installs to advance through beta/RC and then stable.
  • Ignore build metadata for update precedence.
  • Document the alpha → beta → RC → stable lifecycle and immutable unique release tags.
  • Set the next bridge release version to 4.0.1-beta.1 so existing 4.0.0-beta installs can discover it.

Release sequence

4.0.0-beta      (already published; old updater)
4.0.1-beta.1    (bridge release with full SemVer updater)
4.0.1-beta.2
4.0.1-rc.1
4.0.1

After the bridge release, prerelease iterations reuse the same numeric target and increment the prerelease identifier instead of consuming patch versions.

Validation

  • dotnet build RatScanner.sln -c Release
  • dotnet test RatScanner.sln -c Release --no-build --no-restore — 203 passed
  • Focused GitHubUpdateServiceTests — alpha/beta/RC/stable/build-metadata coverage
  • dotnet csharpier check .
  • scripts/lint-markdown.ps1
  • scripts/test-agent-docs.ps1 — 11/11 passed
  • scripts/check-agent-docs.ps1
  • Transitive package vulnerability audit — 0 vulnerabilities
  • git diff --check

Open in Devin Review

Confidence Score: 5/5

Safe to merge — the update logic is correct, thoroughly tested, and stable installs are protected from accidentally receiving prerelease builds at both the app layer and the GitHub release metadata layer.

The core SelectUpdateRelease logic handles all meaningful combinations (stable→stable, prerelease→prerelease, prerelease→stable) correctly and is backed by 200+ passing tests including five new scenario tests covering the exact channel-isolation contract. The only gap worth watching is the missing symmetric guard in the workflow for the operator error of publishing a prerelease version string to the latest channel, but even there the app-level IsNewerVersion check prevents stable users from receiving unwanted updates.

release.yml around the channel validation logic — a symmetric guard for the latest+prerelease-version case would close the remaining operator foot-gun.

Important Files Changed

Filename Overview
src/App/GitHubUpdateService.cs Replaces custom VersionInfo struct with NuGet.Versioning's NuGetVersion; adds SelectUpdateRelease that routes stable installs to /releases/latest and pre-release installs to the full releases list, then picks the highest SemVer candidate. Custom CompareSemanticVersions correctly implements SemVer 2.0 precedence (including build-metadata exclusion). Logic is well-tested and correct.
.github/workflows/release.yml Adds a channel input (testing/latest) that controls the GitHub prerelease flag and make_latest. Guards against publishing a stable version to testing, but no symmetric guard prevents publishing a prerelease version to latest, which would occupy the /releases/latest slot (though app logic still prevents stable users from receiving it).
tests/RatScanner.Tests/PresentationServicesTests.cs Adds thorough SelectUpdateRelease scenario tests (stable channel isolation, prerelease advancement, stable promotion, draft/untrusted-asset filtering) and inline data for alpha→beta→RC→stable precedence including very-large-number and case-sensitivity edge cases.
src/App/RatScanner.csproj Bumps version to 4.0.1-beta.1 (bridge release) and adds NuGet.Versioning 7.6.0 package reference.
docs/agent-context/release-and-versioning.md Documents the pre-release lifecycle (alpha→beta→RC→stable), the two-channel release model, and the bridge rollout procedure. Accurately describes the new updater behaviour.
CONTRIBUTING.md Adds pre-release stage table and numbered-iteration examples; updates example version and release-tag description to match new workflow.
AGENTS.md One-line update to the CI description replacing 'Latest release' with the two-channel description. Accurate and minimal.

Sequence Diagram

sequenceDiagram
    participant App as RatScanner App
    participant US as GitHubUpdateService
    participant GH as GitHub API

    App->>US: TryGetLatestReleaseAsync()
    US->>US: TryParseSemanticVersion(RatConfig.Version)
    alt current version is pre-release
        US->>GH: "GET /releases?per_page=100"
        GH-->>US: JSON array of all releases
        US->>US: "SelectUpdateRelease(includePrereleases=true)"
        US->>US: "Filter: draft=false, stable+prerelease allowed"
        US->>US: IsNewerVersion() — allows pre-release→pre-release and pre-release→stable
        US->>US: OrderByDescending(SemVer), pick highest
    else current version is stable
        US->>GH: GET /releases/latest
        GH-->>US: JSON object — latest non-draft non-prerelease release
        US->>US: "SelectUpdateRelease(includePrereleases=false)"
        US->>US: "Filter: draft=false, prerelease=false only"
        US->>US: IsNewerVersion() — blocks pre-release onto stable
    end
    US-->>App: LatestRelease? (or null)
    alt update available
        App->>US: TryApplyUpdate(release)
        US->>GH: Download RatScanner.zip (redirect-validated)
        US->>US: Extract, validate RatScanner.exe present
        US->>App: Spawn apply-update.ps1, return true
        App->>App: Exit
    end
Loading

Reviews (4): Last reviewed commit: "fix: address follow-up review findings" | Re-trigger Greptile

Context used:

  • Context used - AGENTS.md (source)

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The project advances to 4.0.1-beta.1, documents prerelease lifecycle and release channels, adds channel-aware publishing, and updates GitHubUpdateService to select newer releases using strict SemVer precedence.

Changes

Versioning and release flow

Layer / File(s) Summary
Release lifecycle contract
CONTRIBUTING.md, docs/agent-context/release-and-versioning.md, src/App/RatScanner.csproj, AGENTS.md
Version metadata and documentation define prerelease stages, same-target iteration, unique tags, and testing versus latest release channels.
Channel-aware release publishing
.github/workflows/release.yml
Manual releases derive prerelease status from <Version>, validate the testing channel, and publish testing or latest releases with corresponding GitHub visibility.
Semantic update selection and validation
src/App/GitHubUpdateService.cs, tests/RatScanner.Tests/PresentationServicesTests.cs
The updater parses strict SemVer, compares prerelease identifiers while ignoring build metadata, selects valid newer releases, and tests stable, prerelease, promotion, parsing, and asset-filtering cases.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubUpdateService
  participant GitHubReleasesApi
  participant NuGetVersion
  GitHubUpdateService->>GitHubReleasesApi: Query stable or prerelease releases
  GitHubReleasesApi-->>GitHubUpdateService: Return release JSON
  GitHubUpdateService->>NuGetVersion: Parse and compare SemVer versions
  NuGetVersion-->>GitHubUpdateService: Return release precedence
  GitHubUpdateService-->>GitHubUpdateService: Select newer trusted release
Loading

Possibly related PRs

Suggested labels: size:XXL

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: SemVer prerelease handling with numbered prerelease updates.
Description check ✅ Passed The description is directly aligned with the changeset, covering updater logic, release workflow, documentation, and version bump.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/semver-prerelease-updates

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednuget/​nuget.versioning@​7.6.010010090100100

View full report

@codeant-ai

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

cubic-dev-ai[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Jul 23, 2026
@DysektAI
DysektAI merged commit 3b2c66c into master Jul 23, 2026
15 checks passed
@DysektAI
DysektAI deleted the fix/semver-prerelease-updates branch July 23, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant