| name | build-test-verify |
| description | Build the project, run tests, lint, format, spell check, generate mocks, or verify the build passes for Bitwarden iOS. Use when asked to "build", "run tests", "lint", "format", "verify build", "check if it compiles", "run swiftlint", "run swiftformat", "generate mocks", or to execute any part of the build/test/verify pipeline. |
Build, Test, and Verify — Bitwarden iOS
Initial Setup
brew bundle
./Scripts/bootstrap.sh
Git hooks set up by bootstrap.sh:
post-checkout / post-merge — automatically re-run bootstrap.sh
Project Generation
.xcodeproj files are gitignored and must be generated before building:
mint run xcodegen --spec project-pm.yml
mint run xcodegen --spec project-bwa.yml
mint run xcodegen --spec project-bwk.yml
mint run xcodegen --spec project-bwth.yml
Or run all at once via ./Scripts/bootstrap.sh.
Building
./Scripts/build.sh project-pm.yml Bitwarden Simulator
./Scripts/build.sh project-bwa.yml Authenticator Simulator
./Scripts/build.sh project-bwth.yml TestHarness Simulator
./Scripts/build.sh project-pm.yml Bitwarden Device
Running Tests
Always read the simulator config files before running tests:
DEVICE=$(tr -d '\n' < .test-simulator-device-name)
OS=$(tr -d '\n' < .test-simulator-ios-version)
Then run tests with:
xcodebuild test \
-workspace Bitwarden.xcworkspace \
-scheme Bitwarden \
-testPlan Bitwarden-Default \
-destination "platform=iOS Simulator,name=$DEVICE,OS=$OS"
Current values (as of last update): device iPhone 17 Pro, OS 26.2. Do not hardcode these — always read from .test-simulator-device-name and .test-simulator-ios-version at runtime, as they change when the project upgrades its simulator target.
CI runs all -Default test plans on PRs to main, commits to main, and release branches. Test execution order is randomized (randomExecutionOrder: true).
Snapshot tests are currently disabled. Do not run or re-record them. If you encounter a snapshot test, prefix the function name with disable (e.g., disabletest_snapshot_defaultState).
Lint, Format, Spell Check
mint run swiftlint
mint run swiftformat .
mint run swiftformat --lint --lenient .
typos
SwiftLint and SwiftFormat run automatically as post-compile scripts (configured in project-pm.yml).
Code Generation
Run automatically in pre-build phases; trigger manually when needed:
./Scripts/generate-mocks.sh BitwardenShared
./Scripts/generate-mocks.sh AuthenticatorShared
./Scripts/generate-mocks.sh BitwardenKit
mint run swiftgen config run --config swiftgen-bwr.yml
mint run swiftgen config run --config swiftgen-pm.yml
mint run swiftgen config run --config swiftgen-bwa.yml
mint run swiftgen config run --config swiftgen-bwth.yml
Tooling Reference
| Tool | Config | Purpose |
|---|
| XcodeGen | project-*.yml | Generates .xcodeproj from YAML specs |
| Mint | Mintfile | Swift tool package manager |
| SwiftLint | .swiftlint.yml | Linting with custom rules |
| SwiftFormat | .swiftformat | Code formatting |
| Sourcery | */Sourcery/sourcery.yml | Mock generation (AutoMockable) |
| SwiftGen | swiftgen-*.yml | Asset/localization code generation |
| typos | project config | Spell checking |
| Fastlane | fastlane/Fastfile | CI/CD automation |
Common Failures
| Problem | Cause | Fix |
|---|
.xcodeproj not found | Files are gitignored | Run ./Scripts/bootstrap.sh |
MockXxx not found | Sourcery not run | Add // sourcery: AutoMockable, run Sourcery or build |
| Snapshot test runs | Snapshots are currently disabled | Prefix function name with disable (e.g., disabletest_snapshot_defaultState) |
| Extension crash on unlock | Argon2id KDF > 64 MB | Check maxArgon2IdMemoryBeforeExtensionCrashing in Constants.swift |
| SwiftLint TODO warning | Missing JIRA ticket | // TODO: PM-12345 - description |
Debug Tips
- Error reporting:
ErrorReporter protocol + OSLogErrorReporter for development
- Flight recorder: In-app logging for debugging production issues
- SDK diagnostics: Xcode console errors prefixed
BitwardenSdk
- Network debugging: Set breakpoints in
APIService implementations in Networking/
- State debugging:
print(subject.state) in processor tests to inspect state changes