# 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=<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 |
