Skip to content

Build Prepare for Release

What you'll learn

  • Configuring build_prepare.yaml to swap debug and release dependencies
  • Understanding the Noop/Impl pattern for build-time stripping
  • Running build_prepare before release builds in CI
  • Verifying that debug tools are excluded from production binaries

Prerequisites

  • An existing Archipelago monorepo (see Monorepo Scaffolding)
  • A monorepo_toolkit already generated at devtools/
  • At least one feature using the Impl + Noop pattern (e.g., app_debugger)

Step 1: Understand the Noop/Impl Pattern

Archipelago uses build-time dependency swapping to strip debug tools from release builds. Each feature that needs this has two implementations:

packages/
├── app_debugger/             # Noop — empty stubs, ships in release
└── app_debugger_impl/        # Impl — real debug UI, ships in debug

Both packages expose the same public API. The noop package has lightweight stubs that do nothing, while the impl package contains the real functionality. build_prepare swaps the dependency at the pubspec.yaml level before building.

Step 2: Configure build_prepare.yaml

Create or edit build_prepare.yaml in your monorepo root:

yaml
mappings:
  - debug: app_debugger_impl
    release: app_debugger
    targets:
      - app/pubspec.yaml

  - debug: monitoring_impl
    release: monitoring_noop
    targets:
      - app/pubspec.yaml
      - packages/feature_auth/pubspec.yaml

Each mapping entry defines:

  • debug — The package used during development (full implementation)
  • release — The package swapped in for release builds (noop/stripped)
  • targets — Which pubspec.yaml files reference this dependency

Step 3: Run Build Prepare Locally

Switch dependencies to release mode before building:

bash
# Swap to release dependencies
dart run devtools build_prepare --mode release

# Build your app
flutter build appbundle --flavor production

# Swap back to debug dependencies for development
dart run devtools build_prepare --mode debug

After running with --mode release, the target pubspec.yaml files will have their dependency references updated. For example, in app/pubspec.yaml:

yaml
# Before (debug mode)
dependencies:
  app_debugger_impl:
    path: ../packages/app_debugger_impl

# After (release mode)
dependencies:
  app_debugger:
    path: ../packages/app_debugger

Step 4: Integrate with CI

Add build_prepare to your GitHub Actions workflow before the build step:

yaml
- name: Prepare release dependencies
  run: dart run devtools build_prepare --mode release

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

- name: Restore debug dependencies
  if: always()
  run: dart run devtools build_prepare --mode debug

The if: always() on the restore step ensures dependencies are reset even if the build fails, keeping your working tree clean.

Step 5: Verify Debug Stripping

Confirm that debug packages are excluded from your release build:

bash
# Build with --analyze-size to inspect the bundle
flutter build appbundle --flavor production --analyze-size

# Check that debug symbols are not present
dart run devtools build_prepare --mode release --dry-run

The --dry-run flag shows which swaps would be made without modifying any files.

Key Customization Points

CustomizationWhere to Change
Add new debug/release pairsbuild_prepare.yaml — add a new mapping entry
Target additional pubspec filestargets list in the mapping entry
Default mode--mode flag (debug or release)
Preview changes without applying--dry-run flag

Next Steps

Built by Banua Coder