Files
Android-247-Radio/docs/plans/2026-03-11-build-script-design.md
cottongin 327c5fffab 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
2026-03-11 04:10:53 -04:00

3.0 KiB

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:

./gradlew assembleRelease \
  -Pandroid.injected.signing.store.file=keystore/radio247-release.jks \
  -Pandroid.injected.signing.store.password=<password> \
  -Pandroid.injected.signing.key.alias=radio247 \
  -Pandroid.injected.signing.key.password=<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