Flutter multi-flavor build automation CLI β read your
flavorizrconfig and build all your app flavors in a single command.
build_it build --all --parallel
Managing Flutter builds across multiple flavors quickly becomes tedious:
different applicationIds, per-environment Dart defines, and varying build
targets require long, error-prone shell commands.
build_it turns this:
flutter build apk --flavor apple --dart-define ENV=prod --dart-define-from-file config/apple.json
flutter build apk --flavor banana --dart-define ENV=prod --dart-define-from-file config/banana.json
flutter build ios --flavor apple --dart-define ENV=prod --dart-define-from-file config/apple.jsonInto this:
build_it build --all --parallel| Feature | Details |
|---|---|
| All flavorizr syntaxes | v1 (legacy flat keys), v2+ standalone flavorizr.yaml, embedded in pubspec.yaml |
| Per-flavor dart-defines | Global β flavor β CLI priority merge |
| Smart parallel builds | Automatic parallelism across different targets; sequential within the same target |
| Build type control | --type release (default) / profile / debug |
| Rich terminal output | Live progress, per-flavor logs, final summary table with durations |
| Zero config to start | Works out of the box; .build_it.yaml is optional |
| pip / pipx installable | Single command global install, no manual PATH setup |
You can install build_it as a Python package, download a prebuilt binary, or build it from source.
If you have Python 3.10+ installed, you can use pip:
# Via pipx (recommended β fully isolated global install)
pipx install flutter-build-it
# Via pip
pip install flutter-build-itIf you do not have Python installed, you can download a standalone executable.
Linux / macOS (One-line installer):
curl -sSL https://raw.githubusercontent.com/Dasero197/build_it/main/scripts/install.sh | shWindows (PowerShell One-line installer): Open PowerShell and run:
irm https://raw.githubusercontent.com/Dasero197/build_it/main/scripts/install.ps1 | iex(Alternatively, for a manual install):
- Download
build_it-windows.exefrom the Latest GitHub Release. - Rename it to
build_it.exe. - Place it in a custom folder (e.g.,
C:\build_it) - Add that folder to your system's
PATHvariable: Open Start > "Environment Variables" > Select "Path" > Edit > AddC:\build_it.
You can manually build the standalone executable on your machine using PyInstaller.
# Clone the repository
git clone https://github.com/Dasero197/build_it.git
cd build_it
# Install dependencies and build tools
pip install -e ".[dev]"
pip install pyinstaller
# Build the executable
pyinstaller --onefile --name build_it --hidden-import "build_it.core.models" --hidden-import "build_it.core.parser" --hidden-import "build_it.core.config" --hidden-import "build_it.core.builder" --hidden-import "build_it.cli.main" --hidden-import "build_it.utils.guards" build_it/cli/main.py
# Your binary will be ready in the dist/ folder!# Run from the root of your Flutter project
build_it info # check project detection and tool version
build_it list # list detected flavors and resolved config
build_it init # generate a .build_it.yaml starter config
build_it build --flavor apple # build one flavor
build_it build --all # build all flavors (sequential)
build_it build --all --parallel # build across targets in parallel
build_it build --all --target appbundle # force a specific target
build_it build --flavor apple --type profile # profile build
build_it build --all -D ENV=staging -y # extra defines, skip promptPlace this file at the root of your Flutter project (next to pubspec.yaml).
Generate a pre-populated version with build_it init.
# .build_it.yaml
global:
targets: [apk] # default targets for every flavor
dart_defines: # applied to every build job
ENV: production
dart_define_files:
- config/global.json
extra_args: []
flavors:
apple:
targets: [apk, ios] # overrides global targets for this flavor
dart_defines:
FLAVOR_NAME: apple
dart_define_files:
- config/apple.json
entry_point: lib/main_apple.dart # optional custom entry point
banana:
# no targets β inherits global.targets
dart_defines:
FLAVOR_NAME: bananaYou can also embed the config directly in pubspec.yaml under the build_it: key.
| Priority | Source |
|---|---|
| 1 (highest) | --dart-define / --dart-define-from-file on the CLI |
| 2 | Flavor-specific dart_defines in .build_it.yaml |
| 3 (lowest) | Global dart_defines in .build_it.yaml |
For key/value pairs, higher-priority values override lower-priority ones on key collision. For files, all sources are concatenated: global β flavor β CLI.
| Priority | Source |
|---|---|
| 1 (highest) | --target on the CLI |
| 2 | Flavor targets in .build_it.yaml |
| 3 (lowest) | Global targets in .build_it.yaml |
| Scenario | Behaviour |
|---|---|
| Multiple flavors, same target | Sequential β prevents build/ directory corruption |
| Multiple flavors, different targets | Parallel automatically suggested |
--parallel flag |
Forced parallel mode |
Output directories are printed in the summary table at the end of every build.
| Command | Description |
|---|---|
build_it info |
Project detection status and tool version |
build_it list |
Detected flavors with resolved targets and dart-defines |
build_it init [--force] |
Generate .build_it.yaml pre-populated with detected flavors |
build_it build [OPTIONS] |
Build one or all flavors |
build_it --version |
Print the installed version |
| Option | Short | Description |
|---|---|---|
--flavor NAME |
-f |
Flavor to build (omit to build all) |
--target TARGET |
-t |
Override build target |
--all |
-a |
Build all detected flavors |
--parallel |
-p |
Run builds in parallel across targets |
--type MODE |
-T |
Build mode: release (default), profile, debug |
--dart-define K=V |
-D |
Extra dart define, repeatable |
--dart-define-from-file PATH |
-F |
Extra define file, repeatable |
--yes |
-y |
Skip confirmation prompt |
| Value | Flutter command |
|---|---|
apk |
flutter build apk |
appbundle |
flutter build appbundle |
ios |
flutter build ipa |
web |
flutter build web |
macos |
flutter build macos |
windows |
flutter build windows |
linux |
flutter build linux |
Note β iOS and macOS builds require macOS. They are automatically skipped with status
β skippedon Linux and Windows hosts.
build_it/
βββ pyproject.toml
βββ README.md
βββ .gitignore
βββ scripts/
β βββ build_binaries.sh β PyInstaller build script
βββ build_it/
β βββ __init__.py β version & author
β βββ core/
β β βββ enums.py β BuildTarget, BuildStatus, BuildType
β β βββ models.py β Pydantic models (FlavorInfo, BuildJob, β¦)
β β βββ parser.py β flavorizr parser (syntaxes A, B, C)
β β βββ config.py β .build_it.yaml loader + resolver
β β βββ builder.py β async runner, parallel/sequential, summary
β βββ cli/
β β βββ main.py β Typer app: list / build / init / info
β βββ utils/
β βββ constants.py β project-wide constants (no circular deps)
β βββ utils.py β has_flutter_project(), safe_load_yaml()
β βββ guards.py β require_flutter_project() pre-flight check
βββ tests/
βββ fixtures/
β βββ syntax_a.yaml β flavorizr v2+ standalone
β βββ syntax_b.yaml β flavorizr embedded in pubspec.yaml
β βββ syntax_c.yaml β flavorizr v1 legacy (flat keys)
βββ unit/
βββ test_parser_config.py
# Clone and install in editable mode with dev dependencies
git clone https://github.com/dasero197/build_it.git
cd build_it
pip install -e ".[dev]"
# Run the test suite
pytest
# Build a standalone binary (requires PyInstaller)
bash scripts/build_binaries.shpytest -v
The test suite covers:
- Parser β all three flavorizr syntaxes (A, B, C) and edge cases
- Config β loading, target resolution, dart-define merge priority
generate_default_configβ YAML validity and content
Tests never invoke flutter β the build runner is tested separately via mocks.
- P0 β Standalone project structure & package skeleton
- P1 β flavorizr parser (syntaxes A, B, C) +
.build_it.yamlresolver - P2 β Builder (async runner) + CLI commands (
list,build,init,info) - P3 β Distribution: PyPI publication + PyInstaller binary + GitHub CI/CD setup
- P4 β Polish: verbose/quiet logging, build report, extended test coverage
This project was developed in collaboration with Claude and Gemini via the Antigravity agent.
In the modern era of AI, it is crucial not to fall into blind dependency, but rather to master the art of conciliating human architectural skills with the raw execution speed of AI. By maintaining the role of the Architectβdesigning workflows, drafting precise skeletons, defining rules, and steering correctionsβwhile delegating boilerplate, bash scripting, and exhaustive docstring generation to the AI, we were able to deliver a complete, robust, and pristine product in record time.
This repository stands as a testament to augmented software engineering: a powerful synergy between human vision and artificial intelligence.
Contributions, issues, and feature requests are welcome. Please open an issue before submitting a PR so we can discuss the approach.
MIT Β© Dayane S. R. Assogba