From 327c5fffab0034ec61ebebe54bdb14abef150a16 Mon Sep 17 00:00:00 2001 From: cottongin Date: Wed, 11 Mar 2026 04:10:53 -0400 Subject: [PATCH] docs: add build script design document Captures the design for an interactive bash build script that handles release signing, keystore management, and APK output. Made-with: Cursor --- docs/plans/2026-03-11-build-script-design.md | 97 ++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/plans/2026-03-11-build-script-design.md diff --git a/docs/plans/2026-03-11-build-script-design.md b/docs/plans/2026-03-11-build-script-design.md new file mode 100644 index 0000000..0f565b0 --- /dev/null +++ b/docs/plans/2026-03-11-build-script-design.md @@ -0,0 +1,97 @@ +# Build Script Design + +## Problem + +Building the app requires Android Studio or memorizing Gradle commands. Sharing signed APKs with friends requires keystore setup and signing configuration. This is friction that a simple interactive script can eliminate. + +## Solution + +A single `build.sh` bash script at the project root that provides an interactive terminal menu for building, signing, and outputting APKs. + +## Design + +### Main Menu + +``` +╔══════════════════════════════════╗ +║ Radio 247 Build Tool ║ +╚══════════════════════════════════╝ + +What would you like to do? + + 1) Build Release APK (signed, shareable) + 2) Build Debug APK (quick, for testing) + 3) Manage Keystore (create or check signing key) + 4) Clean (remove build artifacts) + 5) Exit +``` + +### Build Flow — Release + +1. Check for keystore at `keystore/radio247-release.jks` — if missing, redirect to keystore creation +2. Prompt for keystore password (hidden input) +3. Run `./gradlew assembleRelease` with signing injected via CLI properties +4. Copy signed APK to `dist/` with descriptive filename +5. Print path and file size + +### Build Flow — Debug + +1. Run `./gradlew assembleDebug` +2. Copy APK to `dist/` +3. Print path + +### Keystore Management + +- Stored at `keystore/radio247-release.jks` (gitignored) +- Created via `keytool` (ships with JDK) +- Prompts: name, optional organization, password (with confirmation) +- Key alias: `radio247` +- Validity: 10,000 days + +### Signing Method + +Signing config is injected via Gradle command-line properties rather than modifying `build.gradle.kts`: + +```bash +./gradlew assembleRelease \ + -Pandroid.injected.signing.store.file=keystore/radio247-release.jks \ + -Pandroid.injected.signing.store.password= \ + -Pandroid.injected.signing.key.alias=radio247 \ + -Pandroid.injected.signing.key.password= +``` + +This keeps secrets out of version control and build files clean. + +### Output + +- Directory: `dist/` at project root (auto-created, gitignored) +- Naming: `radio247-v{versionName}-{buildType}.apk` +- Example: `radio247-v1.0-release.apk` +- Same version+type overwrites previous file + +### Pre-flight Checks + +- `java` or `JAVA_HOME` available +- `./gradlew` exists and is executable +- Keystore exists (for release builds) + +### Error Handling + +- Build failures show last ~20 lines of Gradle output with colored error banner +- Non-zero exit codes propagated +- Password never written to disk or logged + +### Gitignore Additions + +- `dist/` +- `keystore/` + +## Decisions + +| Aspect | Choice | Rationale | +|--------|--------|-----------| +| Language | Bash | Zero dependencies, macOS ships with it | +| Interface | `select` menu | Built-in, no external tools needed | +| Signing | CLI properties | Keeps build.gradle.kts clean, secrets out of git | +| Keystore location | `keystore/` dir | Separate from source, easy to gitignore | +| Output location | `dist/` | User preference, clear separation from build artifacts |