Point in-app updater at Forgejo releases and Wolfskin assets #17

Closed
justinzeus wants to merge 0 commits from fm/wolfskin-5-updater into main
Owner

Closes justinzeus/wolfskin#5

The in-app updater now checks this repo's Forgejo releases instead of the upstream GitHub releases.

Changes

  • preferences/AppPreference.kt: default updateUrl is https://git.justinvisser.org/api/v1/repos/justinzeus/wolfskin/releases/latest.
  • services/UpdateChecker.kt: ASSET_NAME is Wolfskin, so ABI assets are matched as Wolfskin-<abi>.apk.
  • services/UpdateChecker.kt: getRelease(version) lists releases?limit=50 and returns the release whose name parses via Version.fromString to the installed version, or null. Wolfskin releases are named by git describe (for example v1.0.9-2-g3094fc8c) rather than vX.Y.Z, so the tag lookup used upstream would never match.
  • Tests: Forgejo-shaped fixtures forgejo_release_latest.json and forgejo_releases.json (fields per the Release and Attachment schemas in the Forgejo swagger) under app/src/test/resources/. TestUpdateChecker covers latest-release parsing, ABI asset selection with Wolfskin-* names, and version-match lookup (match and no match). GitHub fixtures kept.

Validation (head 0f7a23faa8)

  • make test: BUILD SUCCESSFUL in 3m 14s (testDefaultDebugUnitTest).
  • make apk-debug: BUILD SUCCESSFUL in 1m 16s. Output: Wholphin-default-debug-1.0.9-6-g0f7a23fa-53{,-arm64-v8a,-armeabi-v7a,-x86_64}.apk.

Notes for reviewer

  • The debug APK filename still starts with Wholphin- because that comes from the upstream build output naming. The updater now expects release assets named Wolfskin-*, so the release pipeline must rename assets to Wolfskin-* when publishing. This PR does not change that naming.
  • make apk (release signing) was not run, per spec.
Closes justinzeus/wolfskin#5 The in-app updater now checks this repo's Forgejo releases instead of the upstream GitHub releases. ## Changes - `preferences/AppPreference.kt`: default `updateUrl` is `https://git.justinvisser.org/api/v1/repos/justinzeus/wolfskin/releases/latest`. - `services/UpdateChecker.kt`: `ASSET_NAME` is `Wolfskin`, so ABI assets are matched as `Wolfskin-<abi>.apk`. - `services/UpdateChecker.kt`: `getRelease(version)` lists `releases?limit=50` and returns the release whose `name` parses via `Version.fromString` to the installed version, or null. Wolfskin releases are named by `git describe` (for example `v1.0.9-2-g3094fc8c`) rather than `vX.Y.Z`, so the tag lookup used upstream would never match. - Tests: Forgejo-shaped fixtures `forgejo_release_latest.json` and `forgejo_releases.json` (fields per the Release and Attachment schemas in the Forgejo swagger) under `app/src/test/resources/`. `TestUpdateChecker` covers latest-release parsing, ABI asset selection with `Wolfskin-*` names, and version-match lookup (match and no match). GitHub fixtures kept. ## Validation (head 0f7a23faa8c52d53759170e2aed1f7e9adb4da5e) - `make test`: BUILD SUCCESSFUL in 3m 14s (`testDefaultDebugUnitTest`). - `make apk-debug`: BUILD SUCCESSFUL in 1m 16s. Output: `Wholphin-default-debug-1.0.9-6-g0f7a23fa-53{,-arm64-v8a,-armeabi-v7a,-x86_64}.apk`. ## Notes for reviewer - The debug APK filename still starts with `Wholphin-` because that comes from the upstream build output naming. The updater now expects release assets named `Wolfskin-*`, so the release pipeline must rename assets to `Wolfskin-*` when publishing. This PR does not change that naming. - `make apk` (release signing) was not run, per spec.
justinzeus added 1 commit 2026-10-22 15:55:30 +02:00
Point updater at Forgejo releases and Wolfskin assets
Some checks failed
review/code-gpt Request changes: version equivalence and lost positive asset-selection coverage
0f7a23faa8
Author
Owner

Code review: request changes

Reviewed SHA: 0f7a23faa8c52d53759170e2aed1f7e9adb4da5e.

Two blocking findings:

  1. Installed release matching differs from updater ordering — services/UpdateChecker.kt:74-81 uses data-class Version ==, including the hash and null-vs-zero commit count. util/Version.kt:41-70 ordering ignores hash and treats absent count as zero. An executed probe confirms that 1.0.9 does not match release v1.0.9-0-gabcdef0, and 1.0.9-2-g3094fc8 does not match v1.0.9-2-g3094fc8c, although neither side orders greater than the other. Use ordering-equivalent matching and retain regression coverage. The installed no-leading-v case with identical count/hash already works.

  2. Lost positive asset-selection coverage — test/TestUpdateChecker.kt:50-87 changes formerly positive release/debug assertions to null checks. The Forgejo fixture restores unsuffixed ABI/universal positives, but contains no Wolfskin-debug*.apk or Wolfskin-release*.apk assets. Debug is now tested only negatively (:111-114); returning null for all debug builds would pass. Restore positive debug ABI/universal and release-suffixed priority/fallback coverage using Wolfskin-named assets.

Verification: ran flock /tmp/wolfskin-gradle.lock make test once: BUILD SUCCESSFUL in 2m 23s, 389 tests, zero failures/errors/skips (388 committed tests plus one temporary smoke probe, now removed). All 12 committed updater tests pass. The actual updater smoke reproduced both version-equivalence misses, parsed the old GitHub fixture, positively selected debug ABI/universal assets, returned null on HTTP 200 [] and HTTP 503, and observed IOException propagation on transport failure. Settings catches Exception (PreferencesViewModel.kt:148-161); no settings crash found. No TV/emulator was available; installation/signing continuity remains unverified.

Notes, not blockers:

  • Both fixtures' fields agree with this server's live Swagger Release/Attachment schemas, including assets[].browser_download_url. They are schema-shaped synthetic fixtures, not demonstrated captures; live Wolfskin releases currently return [].
  • Only the first 50 releases are searched; older installed notes may be absent.
  • Valid-response parser extraction preserves existing behavior. Transport failures throw rather than returning null, but the settings caller handles them.
  • Publishing must rename assets to exact supported names, e.g. Wolfskin.apk and Wolfskin-arm64-v8a.apk (or Wolfskin-release[-<abi>].apk). make apk still emits Wholphin-default-release-<versionName>-<versionCode>[-<abi>].apk (app/build.gradle.kts:214-225). Merely swapping the prefix leaves unmatched flavor/version/code segments. No release build, push, or merge performed.
## Code review: request changes Reviewed SHA: `0f7a23faa8c52d53759170e2aed1f7e9adb4da5e`. Two blocking findings: 1. **Installed release matching differs from updater ordering** — `services/UpdateChecker.kt:74-81` uses data-class `Version ==`, including the hash and null-vs-zero commit count. `util/Version.kt:41-70` ordering ignores hash and treats absent count as zero. An executed probe confirms that `1.0.9` does not match release `v1.0.9-0-gabcdef0`, and `1.0.9-2-g3094fc8` does not match `v1.0.9-2-g3094fc8c`, although neither side orders greater than the other. Use ordering-equivalent matching and retain regression coverage. The installed no-leading-v case with identical count/hash already works. 2. **Lost positive asset-selection coverage** — `test/TestUpdateChecker.kt:50-87` changes formerly positive release/debug assertions to null checks. The Forgejo fixture restores unsuffixed ABI/universal positives, but contains no `Wolfskin-debug*.apk` or `Wolfskin-release*.apk` assets. Debug is now tested only negatively (`:111-114`); returning null for all debug builds would pass. Restore positive debug ABI/universal and release-suffixed priority/fallback coverage using Wolfskin-named assets. Verification: ran `flock /tmp/wolfskin-gradle.lock make test` once: **BUILD SUCCESSFUL in 2m 23s**, 389 tests, zero failures/errors/skips (388 committed tests plus one temporary smoke probe, now removed). All 12 committed updater tests pass. The actual updater smoke reproduced both version-equivalence misses, parsed the old GitHub fixture, positively selected debug ABI/universal assets, returned null on HTTP 200 `[]` and HTTP 503, and observed IOException propagation on transport failure. Settings catches Exception (`PreferencesViewModel.kt:148-161`); no settings crash found. No TV/emulator was available; installation/signing continuity remains unverified. Notes, not blockers: - Both fixtures' fields agree with this server's live Swagger Release/Attachment schemas, including `assets[].browser_download_url`. They are schema-shaped synthetic fixtures, not demonstrated captures; live Wolfskin releases currently return `[]`. - Only the first 50 releases are searched; older installed notes may be absent. - Valid-response parser extraction preserves existing behavior. Transport failures throw rather than returning null, but the settings caller handles them. - **Publishing must rename assets to exact supported names**, e.g. `Wolfskin.apk` and `Wolfskin-arm64-v8a.apk` (or `Wolfskin-release[-<abi>].apk`). `make apk` still emits `Wholphin-default-release-<versionName>-<versionCode>[-<abi>].apk` (`app/build.gradle.kts:214-225`). Merely swapping the prefix leaves unmatched flavor/version/code segments. No release build, push, or merge performed.
Author
Owner

Closing unmerged after review (version matching used exact equality instead of the updater's ordering equivalence; positive debug/release asset coverage was lost). A takeover PR continues from this head (0f7a23fa) and will say Supersedes this one.

Closing unmerged after review (version matching used exact equality instead of the updater's ordering equivalence; positive debug/release asset coverage was lost). A takeover PR continues from this head (0f7a23fa) and will say `Supersedes` this one.
justinzeus closed this pull request 2026-10-22 16:04:28 +02:00
Some checks failed
review/code-gpt Request changes: version equivalence and lost positive asset-selection coverage

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
exploring
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: justinzeus/wolfskin#17
No description provided.