Skip to content

Fail release build when signing secrets are missing - #82

Merged
neteinstein merged 1 commit into
mainfrom
claude/app-update-failure-t02jta
Sep 2, 2026
Merged

neteinstein merged 1 commit into
mainfrom
claude/app-update-failure-t02jta

Conversation

@neteinstein

Copy link
Copy Markdown
Owner

Summary

  • Root-caused the "downloads fine, then always fails to install" in-app update issue: CI logs for the v1.0.0.41 release build show KEYSTORE_FILE/KEYSTORE_PASSWORD/KEY_ALIAS/KEY_PASSWORD are all empty, so app/build.gradle's release build silently falls back to signingConfigs.debug.
  • GitHub Actions runners are ephemeral with no persisted ~/.android/debug.keystore, so that fallback mints a brand-new debug keystore on every workflow run. Each published GitHub Release APK therefore ends up signed with a different certificate than the previous release.
  • Android refuses to install an update whose signing certificate doesn't match the currently-installed app's, so AppUpdateInstaller.installPackage always downloads the new APK successfully and then the system Package Installer always rejects the install - the "app update failed" the user sees.
  • Added a guard step to .github/workflows/release.yml that fails the workflow with a clear ::error:: message when the signing secrets aren't configured, instead of silently publishing another release nobody can update to.

Note for the repo owner

This makes the underlying misconfiguration loud instead of silent, but the actual fix is to add real KEYSTORE_FILE (base64-encoded .keystore/.jks), KEYSTORE_PASSWORD, KEY_ALIAS, and KEY_PASSWORD secrets under Settings > Secrets and variables > Actions so every release is signed with the same, stable certificate. Until then, release.yml will fail on push to main rather than publish another broken update.

Test plan

  • Validated the updated release.yml parses as valid YAML.
  • Once signing secrets are added, confirm a Build and Release run succeeds and a device with an older release can install the new one via Settings > Update to latest.

🤖 Generated with Claude Code

https://claude.ai/code/session_01147MnP2Vf5sDY2BT7UhBbn


Generated by Claude Code

Confirmed via CI logs (release.yml run for v1.0.0.41) that
KEYSTORE_FILE/KEYSTORE_PASSWORD/KEY_ALIAS/KEY_PASSWORD are all empty in
this repo, so app/build.gradle's release build falls back to debug
signing. Each GitHub Actions job runs on a fresh, ephemeral VM with no
persisted ~/.android/debug.keystore, so that fallback generates a new,
different debug keystore on every run - meaning every published GitHub
Release APK is signed with a different certificate than the previous
one.

Android refuses to install an update whose signing certificate doesn't
match the currently-installed app's, so the in-app "Update to latest"
flow always downloads the new APK successfully and then always fails
at install time, regardless of network conditions or device.

Add a guard step that fails the workflow with a clear error instead of
silently publishing another release nobody can update to, until the
real signing secrets are configured in the repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01147MnP2Vf5sDY2BT7UhBbn
@neteinstein
neteinstein merged commit 63f5f57 into main Sep 2, 2026
1 check passed
@neteinstein
neteinstein deleted the claude/app-update-failure-t02jta branch September 2, 2026 07:00
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.

2 participants