fix(android): brand-green app icon + tag-derived APK versioning#15
Conversation
Two Android packaging fixes plus install docs. App icon: the adaptive-icon background was #0b0e12 (near-black), so the dark #111 foreground mark rendered as "black on grey". Set it to the SharpMUSH brand green #00f5b7 so the mark reads cleanly on a proper branded background. Release versioning: the APK hardcoded ApplicationDisplayVersion=1.0 / ApplicationVersion=1, and the release workflow never overrode them. Every build shipped versionName 1.0 / versionCode 1 regardless of the release tag, so Obtainium showed "1.0" against a "v0.2" release (and never offered updates), and Android refused in-place updates because the versionCode never changed. The release workflow now derives both from the tag: versionName = tag minus v/pre- release suffix; versionCode = major*1e6 + minor*1e4 + patch*100 (monotonic). README: document installing via Obtainium (source URL + deep link), the single universal APK, tag-derived versioning, and the pre-release toggle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates Android packaging details (icon + release builds) so installs and incremental updates reflect GitHub Release versions, and documents how to install/update via Obtainium.
Changes:
- Update Android app icon adaptive background color to match brand green.
- Add Android install/update instructions (sideload + Obtainium) to the README.
- Compute and pass Android
versionName/versionCodefrom the GitHub Release tag in the release workflow.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/SharpClient.App/SharpClient.App.csproj | Changes MauiIcon adaptive icon background color and documents rationale. |
| README.md | Adds Android installation/update instructions, including Obtainium flow. |
| .github/workflows/release-apk.yml | Derives and injects application version values from release tags for signed APK/AAB outputs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ``` | ||
| https://github.com/SharpMUSH/SharpClient | ||
| ``` | ||
| or use the deep link [obtainium://add/https://github.com/SharpMUSH/SharpClient](obtainium://add/https://github.com/SharpMUSH/SharpClient). |
There was a problem hiding this comment.
Fixed in 1ceb9d4 — the deep link is now presented as a fenced code block for copy/paste, since GitHub's markdown sanitizer strips non-http(s) schemes and won't render obtainium:// as clickable.
| if [ "${{ github.event_name }}" = "release" ]; then | ||
| VERSION="${{ github.event.release.tag_name }}" | ||
| VERSION="${VERSION#v}" # v0.2.1 -> 0.2.1 | ||
| VERSION="${VERSION%%-*}" # 0.2.1-rc1 -> 0.2.1 | ||
| else | ||
| VERSION="0.0.0" | ||
| fi | ||
| IFS='.' read -r MAJ MIN PAT <<< "$VERSION" | ||
| MAJ=${MAJ:-0}; MIN=${MIN:-0}; PAT=${PAT:-0} | ||
| if [ "${{ github.event_name }}" = "release" ]; then | ||
| CODE=$(( 10#$MAJ * 1000000 + 10#$MIN * 10000 + 10#$PAT * 100 )) | ||
| else | ||
| CODE=${{ github.run_number }} | ||
| fi |
There was a problem hiding this comment.
Fixed in 1ceb9d4. The tag is now stripped of build metadata (%%+*) before parsing, and versionCode widened to major*1e8 + minor*1e4 + patch so ordering holds for larger minor/patch (0.1.123→10123 now sorts below 0.2.0→20000). It also fails fast when a tag isn't numeric semver or exceeds range (major<=20, minor/patch<=9999, under Android's 2.1e9 cap).
| else | ||
| CODE=${{ github.run_number }} | ||
| fi |
There was a problem hiding this comment.
Fixed in 1ceb9d4. Non-release (workflow_dispatch) builds now use a fixed 0.0.0-dev / versionCode 1 instead of run_number, so a dispatched build can never overtake a real release's versionCode and block its update. Those artifacts only upload to the run and are never attached to a release anyway.
Addresses review feedback on the versioning workflow and README: - Strip SemVer build metadata (+...) from the tag before parsing, so tags like v1.2.3+4 no longer corrupt the patch component. - Widen the versionCode formula to major*1e8 + minor*1e4 + patch so larger minor/patch values keep monotonic ordering (previously 0.1.123 produced a code above 0.2.0, which Android would treat as a downgrade). Fail fast when a tag isn't numeric semver or exceeds the supported range (major<=20, minor/patch<=9999, staying under Android's 2.1e9 versionCode cap). - Non-release (workflow_dispatch) builds now use a fixed 0.0.0-dev / versionCode 1 instead of github.run_number, so a dispatched build can never overtake a real release's versionCode and block its in-place update. - README: present the obtainium:// deep link as copyable code, since GitHub's markdown sanitizer strips non-http(s) schemes and won't render it clickable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp
Two Android packaging fixes plus install docs.
App icon
The adaptive-icon background was
#0b0e12(near-black), so the dark#111foreground mark rendered as "black on grey". SetMauiIcon Colorto the SharpMUSH brand green#00f5b7(the "Phosphor" accent used across the SharpMUSH web portal) so the mark reads cleanly on a proper branded background.Rendered preview (current → new square → new circular-masked):
dark
Mmark on#00f5b7green — clean and on-brand.Note: modern devices (Android 8+, adaptive icons) get the clean centered mark on solid green. On Android 7.x legacy launchers the flattened icon may differ; those are a negligible slice at
minSdk 24. Shout if you want a dedicated solid-background asset for legacy too.Release versioning (the Obtainium bug)
The APK hardcoded
ApplicationDisplayVersion=1.0/ApplicationVersion=1, andrelease-apk.ymlnever overrode them. So every build shippedversionName 1.0/versionCode 1regardless of the release tag:1.0against av0.2release and couldn't reconcile them (often reads it as "already ahead", so never offers the update).versionCodenever changed.release-apk.ymlnow derives both from the release tag and threads them into the APK and AAB publishes:versionName= tag minus leadingvand any pre-release suffix (v0.2→0.2)versionCode=major*1_000_000 + minor*10_000 + patch*100— monotonic with semver (v0.2→20000,v0.3→30000,v1.0→1000000; verified locally)Manual
workflow_dispatchruns (no tag) fall back to0.0.0+run_number.README
Adds an "Installing on Android" section: Obtainium source URL + deep link, the single universal APK, tag-derived versioning, and the pre-release toggle.
🤖 Generated with Claude Code