Skip to content

Build Prepare

The build-prepare command swaps debug and release dependencies in pubspec.yaml files at build time. This strips debug-only packages (like monitoring with Crashlytics) from release builds by replacing them with lightweight no-op implementations.

Usage

bash
# Swap to debug dependencies for development
dart run monorepo_toolkit build-prepare debug

# Swap to release (noop) dependencies for production builds
dart run monorepo_toolkit build-prepare release

# Use a custom config path
dart run monorepo_toolkit build-prepare release --config path/to/config.yaml

Configuration

Create a build_prepare.yaml at the workspace root:

yaml
build_prepare:
  mappings:
    - debug: monitoring_impl
      release: monitoring_noop

    - debug: app_debugger
      release: app_debugger_noop

  target_paths:
    - apps/template_app

Configuration fields

FieldRequiredDescription
mappings[].debugYesThe debug/development package name (e.g., monitoring_impl)
mappings[].releaseYesThe release/noop package name (e.g., monitoring_noop)
target_pathsNoDirectories to scan for pubspec.yaml. If empty, scans all workspace packages

How it works

The command performs string replacement in pubspec.yaml files. When running in release mode, every occurrence of the debug package name is replaced with the release package name (and vice versa for debug mode). This includes both the dependency name and any path references.

For example, with the mapping monitoring_impl <-> monitoring_noop:

Debug mode (pubspec.yaml after build-prepare debug):

yaml
dependencies:
  monitoring_impl:
    path: ../../infrastructure/monitoring_impl

Release mode (pubspec.yaml after build-prepare release):

yaml
dependencies:
  monitoring_noop:
    path: ../../infrastructure/monitoring_noop

Melos shortcuts

bash
melos run build-prepare:debug    # Swap to debug dependencies
melos run build-prepare:release  # Swap to release (noop) dependencies

Fastlane integration

The template's Fastfile calls build-prepare automatically:

ruby
before_all do
  # Swap to noop implementations for release
  sh("dart run monorepo_toolkit build-prepare release")
end

after_all do
  # Restore debug implementations
  sh("dart run monorepo_toolkit build-prepare debug")
end

This ensures release builds always use noop packages, and the workspace is restored to debug state after the build completes.

CI integration

In GitHub Actions workflows, wrap build steps with prepare/restore:

yaml
steps:
  - name: Prepare release deps
    run: dart run monorepo_toolkit build-prepare release

  - name: Build release
    run: flutter build appbundle --flavor production

  - name: Restore debug deps
    run: dart run monorepo_toolkit build-prepare debug

Always restore debug dependencies after the build, even if the build fails. Use an if: always() condition on the restore step.

When to use this

Use build-prepare for packages that:

  • Have a debug implementation with heavy vendor SDKs (Crashlytics, Sentry)
  • Should be completely absent from release builds (not just disabled at runtime)
  • Follow the API/Impl + Noop pattern with a shared _api contract

The monitoring_impl / monitoring_noop pair is the canonical example: both implement AppMonitoring from monitoring_api, but monitoring_noop has zero vendor dependencies.

Built by Banua Coder