Overview
BuckSample includes a complete CircleCI configuration that automates building, testing, and validation of your Buck-based iOS project. The CI pipeline ensures code quality and catches issues before they reach production.
CircleCI Configuration
The project uses CircleCI 2.0 with macOS executors to run iOS builds and tests.
Configuration File
The .circleci/config.yml file defines the CI workflow:
version : 2
jobs :
build-and-test :
macos :
xcode : "12.2.0"
environment :
TERM : dumb
steps :
- checkout
- run :
name : Prepare environment
command : |
gem install bundler:1.17.3
bundle install
java -version
- run :
name : Build and run tests
command : make ci
workflows :
version : 2
build-and-test :
jobs :
- build-and-test
The configuration uses Xcode 12.2.0 on macOS executors. Update the xcode version to match your project’s requirements.
CI Workflow Steps
The CircleCI workflow executes the following steps:
Checkout Code
CircleCI checks out your repository code: This automatically clones your repository at the commit being tested.
Prepare Environment
Installs required dependencies: - run :
name : Prepare environment
command : |
gem install bundler:1.17.3
bundle install
java -version
This step:
Installs Bundler 1.17.3 for Ruby dependency management
Runs bundle install to install Ruby gems (including RSpec for tests)
Verifies Java installation (required for Buck)
Build and Test
Runs the comprehensive CI command: - run :
name : Build and run tests
command : make ci
This executes the make ci target, which runs all validation checks.
The CI Make Target
The make ci command orchestrates the entire CI pipeline:
ci : install_buck install_ruby_gems targets build test ui_test ruby_test project xcode_tests watch message
echo "Done"
This single command runs all critical tasks:
install_buck
Downloads and installs Buck if not already present: install_buck :
curl https://jitpack.io/com/github/airbnb/buck/f2865fec86dbe982ce1f237494f10b65bce3d270/buck-f2865fec86dbe982ce1f237494f10b65bce3d270-java11.pex --output tools/buck
chmod u+x tools/buck
install_ruby_gems
Installs Ruby dependencies: install_ruby_gems :
bundle install --path vendor/bundle
targets
Lists all Buck targets to verify build files are valid: targets :
$( BUCK ) targets //...
build
Builds the main app target: build :
$( BUCK ) build //App:ExampleApp
test
Runs unit tests with code coverage: test :
@ rm -f $( buck_out ) /tmp/*.profraw
@ rm -f $( buck_out ) /gen/*.profdata
$( BUCK ) test //App:ExampleAppCITests --test-runner-env XCTOOL_TEST_ENV_LLVM_PROFILE_FILE=" $( buck_out ) /tmp/code-%p.profraw%15x" \
--config-file code_coverage.buckconfig
xcrun llvm-profdata merge -sparse " $( buck_out ) /tmp/code-"*.profraw -o " $( buck_out ) /gen/Coverage.profdata"
xcrun llvm-cov report " $( TEST_BUNDLE ) /ExampleAppCITests" -instr-profile " $( buck_out ) /gen/Coverage.profdata" -ignore-filename-regex "Pods|Carthage|buck-out"
See Code Coverage for details.
ui_test
Runs UI tests using XCUITest: ui_test :
$( BUCK ) build //App:XCUITests
rm -rf ${ UI_TESTS_TMP }
mkdir -p ${ UI_TESTS_TMP }
ln -sf $( buck_out ) /gen/App/XCUITests#apple-test-bundle,dwarf,no-include-frameworks,no-linkermap/XCUITests.xctest $( UI_TESTS_TMP )
cp $( UI_TESTS_TOOLS ) /ExampleApp.xctestrun $( UI_TESTS_TMP )
unzip $( UI_TESTS_TOOLS ) /XCUITests-Runner.app.zip -d $( UI_TESTS_TMP )
xcrun simctl boot $( TARGET_SIMULATOR ) || true
xcrun simctl install $( TARGET_SIMULATOR ) $( UI_TESTS_TMP ) /XCUITests.xctest/PlugIns/ExampleApp.app
xcodebuild test-without-building -xctestrun $( UI_TESTS_TMP ) /ExampleApp.xctestrun -destination 'platform=iOS Simulator,name= $( shell echo $( TARGET_SIMULATOR )) ,OS=latest'
ruby_test
Runs RSpec tests for Ruby scripts: ruby_test :
buck_binary_path=tools/buck bundle exec rspec BuckLocal/ruby_scripts/ -I BuckLocal/ruby_scripts/
project
Generates an Xcode workspace and runs tests within Xcode: project : clean
$( BUCK ) project //App:workspace
open App/ExampleApp-BUCK.xcworkspace
xcode_tests : project
xcodebuild build test -workspace App/ExampleApp-BUCK.xcworkspace -scheme ExampleApp -destination 'platform=iOS Simulator,name=iPhone 8,OS=latest' | xcpretty && exit ${ PIPESTATUS[0] }
watch and message
Builds additional app extensions: watch :
$( BUCK ) build //App:ExampleWatchAppExtension#watchsimulator-i386
message :
$( BUCK ) build //App:ExampleMessageExtension
The make ci command is comprehensive and may take several minutes to complete. It’s designed to catch all possible issues before merging code.
Running CI Locally
You can run the exact same CI pipeline locally before pushing:
This helps catch issues early and reduces CI failures.
Running Individual CI Steps
You can also run individual steps:
Install Buck
Build Only
Run Tests
UI Tests
Xcode Tests
Setting Up CircleCI
Connect Repository
Go to CircleCI
Sign up or log in with your GitHub/Bitbucket account
Add your project from the dashboard
Configure Environment
CircleCI will automatically detect the .circleci/config.yml file. No additional configuration is needed unless you want to:
Add environment variables (Settings → Environment Variables)
Configure SSH keys for private dependencies
Set up deployment keys
Trigger First Build
Push a commit or manually trigger a build from the CircleCI dashboard. The pipeline will:
Provision a macOS executor with Xcode
Install dependencies
Run all build and test steps
Report results
Status Badges
Add a CircleCI status badge to your README:
[  ]( https://circleci.com/gh/USERNAME/REPO )
Replace USERNAME and REPO with your GitHub username and repository name.
Badge Styles
CircleCI offers different badge styles:
[  ]( https://circleci.com/gh/USERNAME/REPO )
Optimization Tips
Cache Dependencies
Add caching to speed up builds: - restore_cache :
keys :
- buck-{{ checksum ".buckconfig" }}
- buck-
- save_cache :
key : buck-{{ checksum ".buckconfig" }}
paths :
- ~/buck-cache
Parallelize Tests
Split tests across multiple containers: jobs :
build-and-test :
parallelism : 4
# ... rest of config
Use Buck's HTTP Cache
Configure Buck to use a shared HTTP cache for faster builds across CI runs. See Buck documentation for setup details.
Troubleshooting
Build Fails on CI but Works Locally
Check the Xcode version matches between CI and local
Verify all dependencies are committed (or properly fetched)
Ensure Buck version is consistent
Tests Timeout
Increase the timeout in CircleCI config:
- run :
name : Build and run tests
command : make ci
no_output_timeout : 30m
Consider splitting the make ci target into separate jobs
Out of Memory Errors
Use a larger resource class:
macos :
xcode : "12.2.0"
resource_class : large
Reduce parallelism in Buck config
Next Steps
Set up code coverage reports
Configure deployment pipelines
Add notifications for build failures
Integrate with GitHub Checks for PR status