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.
Complete YAML
Section titled “Complete YAML”name: Monorepo iOS Buildplatform: iosenvironment: 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/iosMulti-Project Monorepo
Section titled “Multi-Project Monorepo”For repositories with multiple iOS apps:
name: Build Multiple Appsplatform: iosenvironment: 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-bMonorepo with Shared Dependencies
Section titled “Monorepo with Shared Dependencies”name: Monorepo with Shared Codeplatform: iosenvironment: 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/mobileKey Points
Section titled “Key Points”- Root-level Operations: Commands without
working_directoryrun from the repository root - Subdirectory Operations: Commands with
working_directoryrun 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
Repository Structure Examples
Section titled “Repository Structure Examples”Flat Monorepo
Section titled “Flat Monorepo”my-monorepo/├── Gemfile├── apps/│ ├── app-a/│ │ ├── Podfile│ │ ├── fastlane/│ │ └── MyAppA.xcworkspace/│ └── app-b/│ ├── Podfile│ ├── fastlane/│ └── MyAppB.xcworkspace/└── .runnerhub/ └── runnerhub.ymlNested Monorepo
Section titled “Nested Monorepo”my-project/├── mobile/│ ├── ios/│ │ ├── Podfile│ │ └── App.xcworkspace/│ └── android/│ └── build.gradle├── backend/│ └── package.json└── .runnerhub/ └── runnerhub.ymlConditional Builds by Directory
Section titled “Conditional Builds by Directory”You can use shell conditions to build only changed projects:
name: Conditional Monorepo Buildplatform: iosenvironment: 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/iosMonorepo vs Shared Repository
Section titled “Monorepo vs Shared Repository”These are two different approaches to multi-project builds:
| Approach | Use Case | How It Works |
|---|---|---|
| Monorepo (this page) | Multiple projects in subdirectories | One app, one pipeline, working_directory per step |
| Shared Repository | White-label / multi-brand apps | Multiple apps connected to the same repo, each with its own pipeline YAML |
For white-label apps, see Custom Pipeline Path and Shared Repositories.