Skip to content

Monorepo Setup

Monorepos house multiple projects in a single repository. This recipe demonstrates how to run build steps in specific subdirectories using the working_directory parameter.

name: Monorepo iOS Build
platform: ios
environment:
xcode: "16.4"
triggers:
- push
- pull_request
steps:
- name: Install pods
run: pod install
working_directory: apps/ios
- name: Build
run: fastlane build
working_directory: apps/ios

For repositories with multiple iOS apps:

name: Build Multiple Apps
platform: ios
environment:
xcode: "16.4"
triggers:
- push
steps:
- name: Install dependencies (App A)
run: pod install
working_directory: apps/app-a
- name: Build App A
run: fastlane build
working_directory: apps/app-a
- name: Install dependencies (App B)
run: pod install
working_directory: apps/app-b
- name: Build App B
run: fastlane build
working_directory: apps/app-b
name: Monorepo with Shared Code
platform: ios
environment:
xcode: "16.4"
triggers:
- push
- pull_request
steps:
- name: Install workspace gems
run: bundle install
- name: Install pod dependencies
run: pod install
working_directory: apps/mobile
- name: Run tests
run: fastlane test
working_directory: apps/mobile
- name: Build
run: fastlane build
working_directory: apps/mobile
  • Root-level Operations: Commands without working_directory run from the repository root
  • Subdirectory Operations: Commands with working_directory run in that subdirectory
  • Relative Paths: Paths in steps are relative to their working_directory (if specified) or the repo root
  • Shared Dependencies: Install workspace-level dependencies (e.g., bundle install) at the root, then app-specific dependencies in subdirectories
my-monorepo/
├── Gemfile
├── apps/
│ ├── app-a/
│ │ ├── Podfile
│ │ ├── fastlane/
│ │ └── MyAppA.xcworkspace/
│ └── app-b/
│ ├── Podfile
│ ├── fastlane/
│ └── MyAppB.xcworkspace/
└── .runnerhub/
└── runnerhub.yml
my-project/
├── mobile/
│ ├── ios/
│ │ ├── Podfile
│ │ └── App.xcworkspace/
│ └── android/
│ └── build.gradle
├── backend/
│ └── package.json
└── .runnerhub/
└── runnerhub.yml

You can use shell conditions to build only changed projects:

name: Conditional Monorepo Build
platform: ios
environment:
xcode: "16.4"
triggers:
- push
steps:
- name: Build if iOS app changed
run: |
if git diff HEAD~1 HEAD --name-only | grep -q "apps/ios/"; then
pod install && fastlane build
else
echo "No iOS changes, skipping build"
fi
working_directory: apps/ios

These are two different approaches to multi-project builds:

ApproachUse CaseHow It Works
Monorepo (this page)Multiple projects in subdirectoriesOne app, one pipeline, working_directory per step
Shared RepositoryWhite-label / multi-brand appsMultiple apps connected to the same repo, each with its own pipeline YAML

For white-label apps, see Custom Pipeline Path and Shared Repositories.