Repository navigation
Conversation
…uild Sideloaded installs had no way to learn that a release was out: the GitHub APK is what most foss users run, and nothing told them about 0.4.1 or 0.4.2 short of watching the repository. The foss build now asks /releases/latest once a day (WorkManager, network constraint), posts one low-importance notification per new release, and shows a Version section at the top of Diagnostics with the installed version, the release notes, and a download-and-install button. The APK is checked against the size and the SHA-256 digest GitHub publishes for each asset, then handed to the system installer with ACTION_VIEW: Android asks the user and refuses anything not signed by the same key, which is the real guarantee. Same pattern as NewPipe and Vela; no code taken from either. Who gets it, and why the split is where it is: - google flavour: nothing. Play forbids self-updating outside Play and restricts REQUEST_INSTALL_PACKAGES, so the permission and the FileProvider live in app/src/foss/AndroidManifest.xml and the google build binds NoAppUpdater, the same seam FcmSupport uses. - foss builds not signed with the release key (debug, forks, F-Droid's own signature): the updater compares the app's signing certificate to RELEASE_CERT_SHA256 and stays off, since Android would refuse the update after a 30 MB download anyway. The constant is what apksigner prints for plmail-0.4.2-foss.apk. Traps for whoever touches this next: - versionCodeOf is duplicated from the convention plugin (build logic can't be a runtime dependency); GitHubReleasesTest pins both on the plugin's documented examples. - The asset suffix -foss.apk is a contract with release.yml's renaming step. Renaming assets silently turns every updater off. - UpdateFileProvider subclasses FileProvider because :core:data already declares androidx FileProvider for blobs, and two providers with one class name merge into one. - The check runs on opening Diagnostics only when a release was already announced, so the screen still makes no requests just for being opened in the ordinary case. It never contacts the mail server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflict in docs/RELEASING.md only: karatektus#76/karatektus#81 added a "Google Play" section in the same spot as this branch's "The in-app updater". Both kept, Google Play first, since it follows the release in the order things happen. Nothing merged from main touches the APK asset names the updater relies on (-foss.apk) or any code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CFCshXUp57k1yHeHy68JXy
karatektus#75 landed first, so values-fr now exists in :core:notifications and :feature:settings without the 17 strings this branch adds: the update notification's channel, title and text, and the Version section of Diagnostics. Lint's MissingTranslation would fail the build once this is merged, although this pull request's own CI ran green before karatektus#75. Same conventions as the rest of the French translation: "vous", the typographic apostrophe, and a no-break space before ":" and "%". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CFCshXUp57k1yHeHy68JXy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #77
Opened together with the issue; happy to wait for
acceptedbefore anything is merged.What changes
The
fossbuild checksGET /repos/karatektus/pl_mail_android/releases/latestonce a day and can install a newer release itself.UpdateCheckWorker, a dailyPeriodicWorkRequestwith a network constraint. It takes the*-foss.apkasset of the latest stable release (/releases/latestnever returns pre-releases) and compares versionCodes computed with the same formula as the convention plugin.LOWnotification per new release, on its own "App updates" channel. Tapping it opens Diagnostics.filesDir/updates, checked (aPKheader, the size, and the SHA-256 GitHub publishes in each asset'sdigest), then handed to the system installer withACTION_VIEWthrough a FileProvider. Android confirms with the user and refuses an APK signed by another key. A checked download is kept, so reopening the installer does not download again.Who gets it:
fosssigned with the release keyfossdebug, forks, F-Droid-signedRELEASE_CERT_SHA256(6076e3a3…, fromapksigneronplmail-0.4.2-foss.apk), since Android would refuse the update anywaygoogleREQUEST_INSTALL_PACKAGES.GoogleUpdateBindingsbindsNoAppUpdater, the same seam asFcmSupportdocs/RELEASING.mdgains a section on what this expects of a release: the asset suffix, no pre-releases, and the certificate constant to change if the key is ever replaced.How it was checked
./gradlew testlocally: 1599 tests, 0 failures, including the newGitHubReleasesTest(release parsing against the real v0.4.2 response shape, flavour asset picking, drafts and pre-releases refused, versionCode parity with the convention plugin, digest parsing, file checks).fossDebug,googleDebug)../gradlew build(lint). CI will tell.Note
#75 (French translation) landed first, so
mainis merged in and the 17 new strings now have French copies too (2d5a2ca). That commit was checked by a script for key coverage (none missing invalues/,values-de/orvalues-fr/) and byspotlessCheck; a local lint and build run was stopped for lack of memory, so CI'sbuildis the check for it.Checklist
./gradlew test)spotlessApplydone,./gradlew buildleft to CIvalues/strings.xmlandvalues-de/strings.xmldocs/RELEASING.md)🤖 Generated with Claude Code
https://claude.ai/code/session_01CFCshXUp57k1yHeHy68JXy