Skip to content

Implement the prerelease (beta) software-update channel - #24

Merged
dayglojesus merged 1 commit into
mainfrom
software-update/prerelease-channel
Jun 11, 2026
Merged

Implement the prerelease (beta) software-update channel#24
dayglojesus merged 1 commit into
mainfrom
software-update/prerelease-channel

Conversation

@dayglojesus

Copy link
Copy Markdown
Collaborator

Summary

All three update channels pointed at releases/latest, which excludes GitHub prereleases by definition, so the beta channel could never offer one and its "Prereleases" menu item had been removed from the prefs dropdown. This makes the beta channel real.

  • OakSelectGitHubRelease(releases, includePrereleases) — given a GitHub "list releases" response, picks the highest-version non-draft entry per OakCompareVersionStrings. Selection is by version, not array position (the list is creation-ordered; a hotfix published after a newer beta must not win). Stables are included so beta users converge back onto the stable release once it catches up with the beta cycle.
  • Feed parser accepts arrays — the list endpoint returns a JSON array, which previously fell into the "Malformed server response" branch. Arrays are reduced via OakSelectGitHubRelease before OakExtractUpdateInfo; an empty selection routes to the existing "Incomplete server response" path.
  • Channel re-point — beta now fetches /releases?per_page=20; Release stays on releases/latest; Canary too (no nightly stream exists).
  • Prefs UI — "Prereleases" menu item (tag 1) and the kSoftwareUpdateChannelPrerelease transformer entry restored.
  • Publishingrelease.yml adds --prerelease to gh release create when the CHANGELOG version matches *-beta*, keeping releases/latest (the stable feed) on the stable build. A beta release is therefore just a CHANGELOG entry whose version is vX.Y.Z-undead-beta.N. bin/extract_changes needs no change (exact string match on the version).

Tests

  • t_OakCompareVersionStrings.mm: ordering assertions for the fork's real tag forms (2.1.2-undead-beta.1 < 2.1.2-undead, beta.2 < beta.10, 2.1.1-undead < 2.1.2-undead-beta.1, legacy 2.0.23-undead.0). The existing comparator passed all of them unchanged.
  • t_OakSelectGitHubRelease.mm (new): stable-only list, mixed lists in both orders, position trap, draft/garbage/missing-tag entries, empty list, prerelease-only list with prereleases excluded.

Runtime verification

Driven in the running app (channel set to beta, real menu action triggered):

  • Doctored local feed with a fabricated v2.1.2-undead-beta.1 prerelease placed second in the array behind a stable → offer dialog: "TextMate 2.1.2-undead-beta.1 is now available. You have version 2.1.1-undead."
  • Empty list [] → "Error Checking for Update — Incomplete server response."
  • Live GitHub endpoint (no prereleases published yet) → "Up To Date. You are running 2.1.1-undead."
  • Release channel → releases/latest, "Up To Date" (unchanged path).
  • Preferences → Software Update popup shows "Prereleases" when the channel default is beta.

Not covered here

Publishing the first actual beta (a CHANGELOG entry with a -beta.N version) is a follow-up action; until one exists the beta channel resolves the newest stable, as verified above.

All three update channels pointed at releases/latest, which excludes
GitHub prereleases by definition, so the beta channel could never offer
one and its menu item had been removed from the prefs dropdown.

- New OakSelectGitHubRelease(releases, includePrereleases): given a
  GitHub "list releases" response, picks the highest-version non-draft
  entry per OakCompareVersionStrings (the list is creation-ordered, so
  a hotfix published after a newer beta must not win by position).
  Including stables means beta users converge back onto the stable
  release once it catches up with the beta cycle.
- The feed parser now accepts a JSON array, reducing it via
  OakSelectGitHubRelease before OakExtractUpdateInfo; an empty
  selection routes to the existing "Incomplete server response" path.
- Beta channel now fetches /releases?per_page=20; Release stays on
  releases/latest, Canary too (no nightly stream exists).
- Prefs: "Prereleases" menu item and transformer entry restored.
- release.yml: versions containing -beta publish with --prerelease,
  keeping releases/latest (the stable feed) on the stable build.
- Tests: -undead/-undead-beta.N ordering assertions (comparator needed
  no changes) and coverage for the selection function (stable-only
  list, mixed lists in both orders, position trap, draft/garbage
  entries, empty list).

Verified against a doctored local feed (offer dialog showed
2.1.2-undead-beta.1 over 2.1.1-undead) and against the live endpoint
(stable-only list reports "Up To Date").
@dayglojesus
dayglojesus merged commit 364967c into main Jun 11, 2026
2 checks passed
@dayglojesus
dayglojesus deleted the software-update/prerelease-channel branch August 21, 2026 02:52
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