VoltTracker ships two APK streams:
latest-debug: a rolling debug APK built from every push tomainby.github/workflows/android.yml. It is attached to the prerelease taglatest-debugasvolttracker-vX.Y.Z-<commit>-debug.apk.- Tagged releases: conventional-commit merges to
mainrun.github/workflows/release.yml.feat:creates a minor bump,fix:andperf:create patch bumps, andBREAKING CHANGE:creates a major bump. When a release is cut, the workflow attaches both an install-oriented release APK and a debuggable APK to the tagged release.
Local debug APKs use the standard Android debug key. They are intended for quick on-phone validation on devices that do not already have a differently signed VoltTracker install:
cd mobile/android
./gradlew :app:assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apkIf installing from a browser or file manager, Android must allow "Install unknown apps" for that app. Android treats two APKs with the same package name as the same app only when their signing certificates match, so local debug builds generally cannot update a tagged release APK.
Tagged releases attach clearly named APKs to the vX.Y.Z GitHub release:
volttracker-vX.Y.Z-release.apk: the normal signed user build.volttracker-vX.Y.Z-debug.apk: the debuggable build for developers and field diagnostics. When signing secrets are configured, it is signed with the same stable app key as the release APK so it can update the tagged release build while still allowingadb run-asand WebView debugging. If signing secrets are unavailable, it falls back to the standard Android debug key and may require a backup, uninstall, install, and restore cycle.
The signing secrets are:
ANDROID_KEYSTORE_BASE64ANDROID_KEYSTORE_PASSWORDANDROID_KEY_ALIASANDROID_KEY_PASSWORD
The workflow writes mobile/android/keystore.properties and
mobile/android/app/release.keystore only on the runner, verifies the keystore
with keytool, and removes both files in the final cleanup step. Tagged release
builds fail when these secrets are absent instead of publishing an unsigned
release APK.
Before changing release automation, run:
python .github/scripts/check_release_config.py
cd mobile/android && ./gradlew --no-daemon verifyActiveAppThe Python check keeps the semantic-release config, PR title lint types, release
workflow guardrails, and VERSION source of truth aligned.
For release-candidate branches, run the local preflight before requesting final review:
scripts/release-preflight.shThe manual Release dry run workflow predicts the semantic-release bump/tag for the checked-out branch without publishing artifacts.
The repo-root CHANGELOG.md is generated and owned by python-semantic-release
(config in /pyproject.toml); the release workflow regenerates it on every
version bump from the Conventional Commit subjects on main. Do not hand-edit,
split, or truncate it — the tool rewrites it and manual changes will be lost or
cause churn. Its size is expected: it is the full release history.
To read recent entries, start at the top — newest release first (e.g.
head -n 100 CHANGELOG.md), or use the per-tag release notes on the GitHub
Releases page, which carry the same generated content per version.