# Flaunch CLI

Blazing fast Flutter build, version bump, upload & notification CLI tool written in Rust.

Flaunch streamlines your release workflow by automating version bumping, building, uploading, and team notifications - all from a single command.

## Features

- **Version Management** - Semantic versioning with automatic pubspec.yaml/Cargo.toml updates
- **Multi-Flavor Builds** - Support for multiple build flavors (dev, staging, prod, etc.)
- **Split APK Support** - Automatic handling of per-ABI split APKs
- **ReleaseHub Integration** - Direct upload to ReleaseHub with chunked uploads
- **SFTP Upload** - Legacy SFTP upload support with SSH key authentication
- **Discord Notifications** - Rich embeds with version info and commit history
- **Git Integration** - Auto-commit version bumps and track commits between builds
- **Interactive Mode** - User-friendly menu for common operations
- **Local Config Override** - Keep sensitive data out of version control

## Installation

### Windows

```powershell
irm https://releases.example.com/install.ps1 | iex
```

### macOS / Linux

```bash
curl -fsSL https://releases.example.com/install | sh
```

The installer automatically:
- Installs the binary to `~/.local/bin`
- Installs man pages to `~/.local/share/man/man1`
- Updates your shell profile (`~/.bashrc` or `~/.zshrc`) with PATH and MANPATH

After installation, access documentation with:

```bash
man flaunch
man flaunch-run
man flaunch-bump
man flaunch-upload
man flaunch-sync
```

### From Source

```bash
cargo install --path .
```

## Quick Start

### Initialize a new project

```bash
flaunch init
```

This launches an interactive wizard to create your `flaunch.yaml` configuration.

### Run the full pipeline

```bash
# Using flavor shortcut (recommended)
flaunch production

# With channel specification
flaunch production -c beta

# With version bump type
flaunch production -t minor -c stable

# Using explicit run command
flaunch run -f production -c beta
```

### Interactive mode

```bash
flaunch
```

Launches an interactive menu when no arguments are provided.

## Commands

### Flavor Shortcut

Run the full pipeline for a flavor with a single command:

```bash
flaunch <flavor> [options]
```

**Examples:**

```bash
flaunch production                    # Full pipeline for 'production' flavor
flaunch dev -c beta                   # Upload to 'beta' channel
flaunch staging -t minor              # Minor version bump
flaunch prod -c stable -t patch       # Patch bump, stable channel
```

**Options:**

| Short | Long | Description |
|-------|------|-------------|
| `-c` | `--channel` | Release channel for ReleaseHub |
| `-t` | `--bump-type` | Version bump type (build, patch, minor, major) |

---

### `run` - Full Pipeline

Run the complete pipeline: bump -> build -> upload -> notify

```bash
flaunch run -f <flavor> [options]
```

**Options:**

| Short | Long | Description | Default |
|-------|------|-------------|---------|
| `-f` | `--flavor` | Flavor to build and deploy | *required* |
| `-t` | `--bump-type` | Version bump type | `build` |
| `-c` | `--channel` | Release channel | - |
| `-l` | `--changelog` | Changelog/release notes | - |
| `-B` | `--no-bump` | Skip version bump | `false` |
| `-K` | `--no-build` | Skip build step | `false` |
| `-U` | `--no-upload` | Skip upload step | `false` |
| `-N` | `--no-notify` | Skip Discord notification | `false` |
| `-s` | `--sftp` | Force SFTP upload | `false` |

---

### `bump` - Version Bump

Bump the version in pubspec.yaml or Cargo.toml.

```bash
flaunch bump [options]
```

**Options:**

| Short | Long | Description | Default |
|-------|------|-------------|---------|
| `-t` | `--type` | Bump type: build, patch, minor, major | `build` |
| `-m` | `--commit` | Auto-commit the version bump | `false` |

**Examples:**

```bash
flaunch bump                    # 1.0.0+1 -> 1.0.0+2
flaunch bump -t patch           # 1.0.0 -> 1.0.1
flaunch bump -t minor           # 1.0.0 -> 1.1.0
flaunch bump -t major           # 1.0.0 -> 2.0.0
flaunch bump -t patch -m        # Bump and auto-commit
```

---

### `build` - Build Only

Run build commands for a specific flavor.

```bash
flaunch build -f <flavor>
```

---

### `upload` - Upload Only

Upload built artifacts to ReleaseHub or SFTP.

```bash
flaunch upload -f <flavor> [options]
```

**Options:**

| Short | Long | Description |
|-------|------|-------------|
| `-f` | `--flavor` | Flavor that was built |
| `-c` | `--channel` | Release channel |
| `-l` | `--changelog` | Changelog/release notes |
| `-s` | `--sftp` | Force SFTP upload |

---

### `sync` - Sync Version from Remote

Sync local version with the latest from ReleaseHub.

```bash
flaunch sync [options]
```

**Options:**

| Short | Long | Description | Default |
|-------|------|-------------|---------|
| `-c` | `--channel` | Channel to sync from | - |
| `-b` | `--bump` | Bump build number after sync | `true` |

---

### `notify` - Send Notification

Send a Discord notification manually.

```bash
flaunch notify -f <flavor> [options]
```

---

### `version` - Show Version

Display the current version from pubspec.yaml/Cargo.toml.

```bash
flaunch version
```

---

### `flavors` - List Flavors

List all available build flavors.

```bash
flaunch flavors
```

---

### `validate` - Validate Config

Check the configuration file for errors.

```bash
flaunch validate
```

---

### `init` - Initialize Config

Create a new configuration file with an interactive wizard.

```bash
flaunch init [options]
```

**Options:**

| Short | Long | Description |
|-------|------|-------------|
| `-f` | `--force` | Overwrite existing config |

---

## Global Options

These options work with all commands:

| Short | Long | Description | Default |
|-------|------|-------------|---------|
| `-c` | `--config` | Path to config file | `flaunch.yaml` |
| `-C` | `--directory` | Working directory | - |
| `-v` | `--verbose` | Enable verbose output | `false` |
| `-h` | `--help` | Print help | - |
| `-V` | `--version` | Print version | - |

## Configuration

Flaunch uses a YAML configuration file (`flaunch.yaml`).

### Project Configuration

```yaml
project:
  # Display name for your project
  name: "My App"

  # Bundle/Application ID (optional, for file naming)
  bundle_id: "com.example.myapp"

  # Project type: flutter, fvm, cargo, cargo+iss
  type: "flutter"

  # Base URL for download links (for SFTP uploads)
  download_base_url: "https://releases.example.com/"

  # Output naming pattern
  output_naming: "{name}-{version}-{arch}-{flavor}.apk"
```

#### Project Types

| Type | Version File | Description |
|------|--------------|-------------|
| `flutter` | pubspec.yaml | Standard Flutter project |
| `fvm` | pubspec.yaml | Flutter with FVM |
| `cargo` | Cargo.toml | Rust project |
| `cargo+iss` | Cargo.toml | Rust + Inno Setup installer (auto-updates .iss) |

### Flavors Configuration

```yaml
flavors:
  dev:
    display_name: "Development"
    single_apk: false
    build_commands:
      - "flutter clean"
      - "flutter pub get"
      - "flutter build apk --flavor dev --split-per-abi --release"
    output_paths:
      - "build/app/outputs/apk/dev/release/app-dev-arm64-v8a-release.apk"
      - "build/app/outputs/apk/dev/release/app-dev-armeabi-v7a-release.apk"
    env:
      API_URL: "https://dev.api.example.com"

  prod:
    display_name: "Production"
    single_apk: true
    build_commands:
      - "flutter build apk --flavor prod --release"
    output_paths:
      - "build/app/outputs/apk/prod/release/app-prod-release.apk"
```

### ReleaseHub Configuration

```yaml
releasehub:
  # ReleaseHub server URL
  api_url: "https://releases.example.com"

  # API key (use env var or local config)
  api_key: "${RELEASEHUB_API_KEY}"

  # Default release channel
  channel: "stable"

  # Platform: android, windows, macos, ios, linux
  platform: "android"

  # Chunk size for uploads (default: 10MB)
  chunk_size: 10485760

  # Create releases as drafts
  create_as_draft: false

  # Changelog template (optional)
  changelog_template: "## Changes\n{commits}"
```

### SFTP Configuration (Legacy)

```yaml
upload:
  host: "your-server.com"
  port: 22
  username: "deploy"

  # Authentication (choose one):
  password: "${SFTP_PASSWORD}"        # Password (use env var!)
  private_key: "~/.ssh/id_rsa"        # SSH key path
  # Or omit both to use SSH agent

  remote_dir: "/var/www/releases"
```

### Discord Notifications

```yaml
discord:
  webhooks:
    - "${DISCORD_WEBHOOK_URL}"
    - "${DISCORD_TEAM_WEBHOOK}"       # Multiple webhooks supported

  embed_color: 3066993                # Green (decimal)
  embed_title: "New Build Available!"
  include_commits: true               # Include git commits in message
```

### Git Integration

```yaml
git:
  enabled: true
  build_cache: ".flaunch_cache"       # Tracks last build commit
  auto_commit_bump: false
  bump_commit_message: "chore: bump version to {version}"
```

### Output Naming Placeholders

| Placeholder | Description | Example |
|-------------|-------------|---------|
| `{name}` | Project name | `MyApp` |
| `{bundle_id}` | Bundle ID | `com.example.myapp` |
| `{version}` | Full version | `1.2.3+45` |
| `{semver}` | Semantic version | `1.2.3` |
| `{build}` | Build number | `45` |
| `{flavor}` | Build flavor | `production` |
| `{arch}` | Architecture | `arm64-v8a` |

## Local Config Override (flaunch.local.yaml)

The local config file allows you to:
- **Keep secrets out of version control** - API keys, passwords, webhooks
- **Override any setting** from flaunch.yaml without modifying it
- **Use different credentials** per machine (dev vs CI)

### How It Works

1. Flaunch first loads `flaunch.yaml`
2. Then looks for `flaunch.local.yaml` in the same directory
3. Values in local config **override** values in main config
4. The local file is **automatically added to .gitignore**

### Creating the Local Config

Create `flaunch.local.yaml` next to your `flaunch.yaml`:

```yaml
# flaunch.local.yaml
# This file is auto-gitignored - safe for secrets

# Override ReleaseHub credentials
releasehub:
  api_key: "rh_live_abc123def456..."

# Override SFTP credentials
upload:
  password: "my-secret-password"
  # Or use SSH key instead:
  # private_key: "~/.ssh/id_ed25519"

# Override Discord webhooks
discord:
  webhooks:
    - "https://discord.com/api/webhooks/123/abc..."
    - "https://discord.com/api/webhooks/456/def..."
```

## Environment Variables

Use `${VAR_NAME}` syntax to reference environment variables:

```yaml
releasehub:
  api_key: ${RELEASEHUB_API_KEY}

upload:
  password: ${SFTP_PASSWORD}

discord:
  webhooks:
    - ${DISCORD_WEBHOOK_URL}
```

## CI/CD Integration

### GitHub Actions

```yaml
- name: Build and Deploy
  env:
    RELEASEHUB_API_KEY: ${{ secrets.RELEASEHUB_API_KEY }}
    DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK }}
  run: |
    flaunch production -c ${{ github.ref_name }} -l "${{ github.event.head_commit.message }}"
```

### GitLab CI

```yaml
deploy:
  script:
    - flaunch production -c stable -l "$CI_COMMIT_MESSAGE"
  variables:
    RELEASEHUB_API_KEY: $RELEASEHUB_API_KEY
    DISCORD_WEBHOOK_URL: $DISCORD_WEBHOOK
```

## Troubleshooting

### Config not found

```bash
flaunch -c path/to/flaunch.yaml production
```

### Verbose output for debugging

```bash
flaunch -v production
```

### Validate configuration

```bash
flaunch validate
```

### List available flavors

```bash
flaunch flavors
```

### Show current version

```bash
flaunch version
```

---

*Flaunch is proprietary software by Version Two s.r.o.*
