- Read keystore.properties at Gradle config time; wire signingConfig into the release build type (degrades gracefully when the file is absent)
6.8 KiB
Publishing guide
Steps to generate signing credentials and publish both apps. See
docs/architecture.md for what each app does and CLAUDE.md for build
commands.
1. .gitignore
Keystore files and credential properties must never be committed. Already
added to .gitignore:
*.jks
*.keystore
keystore.properties
If you generate a keystore with a different name/extension, add that specific path too — don't rely on a broad glob you might forget to check.
2. Android companion app → Google Play
2.1 Generate an upload keystore
keytool -genkeypair -v \
-keystore SchwertUndMagieOnPebbleCompanionApp/release.keystore \
-alias sum-release \
-keyalg RSA -keysize 2048 -validity 10000
keytool will prompt for a keystore password, a key password (can be the
same), and your name/org details for the certificate (these become public
metadata in the signed APK, not secret). Store the keystore file and both
passwords in a password manager — losing this keystore means you can never
publish an update to the same Play Store listing again under the same app;
Google cannot recover or reset it for you.
2.2 Store credentials in a gitignored properties file
Create SchwertUndMagieOnPebbleCompanionApp/keystore.properties (already
gitignored, never commit it):
storeFile=release.keystore
storePassword=<keystore password>
keyAlias=sum-release
keyPassword=<key password>
2.3 Wire the signing config
Add to SchwertUndMagieOnPebbleCompanionApp/app/build.gradle.kts, near the
top:
import java.util.Properties
val keystoreProps = Properties().apply {
rootProject.file("keystore.properties").takeIf { it.exists() }
?.reader()?.use { load(it) }
}
Inside the android { } block:
signingConfigs {
create("release") {
keystoreProps["storeFile"]?.let { storeFile = file(it as String) }
storePassword = keystoreProps["storePassword"] as String?
keyAlias = keystoreProps["keyAlias"] as String?
keyPassword = keystoreProps["keyPassword"] as String?
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
// ...existing isMinifyEnabled / proguardFiles
}
}
This degrades gracefully (null signing config values) on any machine without
keystore.properties — CI or a contributor's checkout — rather than failing
the whole Gradle configuration.
2.4 Build the release bundle
cd SchwertUndMagieOnPebbleCompanionApp
./gradlew bundleRelease # produces app/build/outputs/bundle/release/app-release.aab
./gradlew assembleRelease # produces app/build/outputs/apk/release/app-release.apk, for sideload testing
Play Store requires the AAB (bundleRelease output), not the APK — Play
re-packages per-device APKs from it (including ABI splits, so arm64-v8a/
x86_64 native VICE libraries each ship only to matching devices).
2.5 Play Console setup (one-time, per app listing)
- Enroll in the Google Play Developer program (one-time account fee).
- Create the app in Play Console, set its package name
(
de.ladkau.schwertundmagieonpebblecompanionapp) — this is permanent. - App content: privacy policy URL, content rating questionnaire, data safety form (declare what data the app collects — this app's only network activity is the loopback HTTP server talking to Core for Pebble, so "no data collected/shared" likely applies, but fill out the form yourself).
- Store listing: title, short/full description, icon (512×512 PNG), feature graphic (1024×500), phone screenshots (min 2, current device's actual aspect ratio).
- Enroll in Play App Signing when prompted on first upload — Google re-signs your AAB with its own key for distribution; your upload keystore (§2.1) only needs to be kept for future uploads to this listing, not for the keys end users' devices actually trust.
- Upload the AAB to an internal testing track first, verify the install works on a real device, then promote to closed/open testing or production.
2.6 Versioning for future releases
Bump both fields in app/build.gradle.kts before every release build:
versionCode = 2 // must strictly increase on every Play Store upload
versionName = "1.1" // user-visible, free-form
3. Pebble watch app → Rebble app store / direct distribution
The official Pebble app store shut down years ago; the community-run Rebble store is the closest equivalent today, alongside the 2025 Core Devices relaunch of Pebble hardware. Check Rebble's current developer portal directly for their exact submission flow and requirements — that's outside this repo and changes independently of it.
3.1 Build the artifact
cd SchwertUndMagieOnPebbleWatchApp
pebble build # produces build/SchwertUndMagieOnPebbleWatchApp.pbw
The .pbw is the complete distributable — it bundles all target platforms
(aplite/basalt/chalk/diorite/emery/flint/gabbro) declared in
package.json. There is no signing step analogous to Android; Pebble apps
are not cryptographically signed by the developer.
3.2 Direct distribution (no store)
Anyone with the .pbw file and Core for Pebble installed can sideload it —
this is the lowest-friction path and doesn't depend on any third party's
store being operational. This watch app is tightly coupled to the companion
app's HTTP bridge (see docs/architecture.md §1), so it's not really
meaningful as a standalone listing anyway — distribute both together.
3.3 Store submission (if Rebble's process applies)
Expect to need: an app icon resource (not yet configured in package.json —
there's no icon/menu-icon entry currently, only the in-app IMAGE_SPLASH
bitmap), a short description, and screenshots per platform. Generate
screenshots the same way used during development:
pebble install --emulator emery --vnc
pebble screenshot --vnc --no-open docs/screenshots/emery.png
(repeat per target platform you want a store screenshot for).
3.4 Versioning
Bump version in SchwertUndMagieOnPebbleWatchApp/package.json before each
release build.
4. Pre-publish checklist
- Release keystore generated, passwords saved in a password manager, both gitignored (§1, §2.1)
keystore.propertiesexists locally and is not tracked by git./gradlew bundleReleasesucceeds and installs/runs on a real device from the resulting AAB (test viabundletoolor Play internal testing)- Play Console store listing content complete (icon, screenshots, privacy policy, content rating, data safety form)
pebble buildsucceeds for all target platforms;.pbwsideloads and runs correctly against the signed companion app buildversionCode/versionName(Android) andversion(Pebble) bumped