Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Automated mobile build, test, and deployment with Fastlane
.claude/skills/a5c-ai-fastlane-mobile-ci-cd/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 4 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 109% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 261% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 168% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 181% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 114% | 0% |
This skill provides comprehensive capabilities for mobile CI/CD automation using Fastlane. It enables automated builds, testing, code signing, beta distribution, and app store deployments for both iOS and Android platforms.
bash - Execute Fastlane commands, Ruby, and bundlerread - Analyze Fastfile, Appfile, and configuration fileswrite - Generate Fastlane configurations and lanesedit - Update existing Fastlane configurationsglob - Search for Fastlane and CI configuration filesgrep - Search for patterns in CI/CD configurationsThis skill integrates with the following processes:
mobile-cicd-fastlane.js - CI/CD pipeline setupautomated-release-management.js - Release automationios-appstore-submission.js - iOS deploymentandroid-playstore-publishing.js - Android deploymentbeta-testing-setup.js - Beta distributionproject-root/
├── fastlane/
│ ├── Fastfile
│ ├── Appfile
│ ├── Matchfile
│ ├── Pluginfile
│ ├── Gymfile
│ ├── Scanfile
│ ├── Deliverfile
│ ├── metadata/
│ │ ├── en-US/
│ │ │ ├── description.txt
│ │ │ ├── keywords.txt
│ │ │ └── release_notes.txt
│ │ └── review_information/
│ └── screenshots/
├── Gemfile
└── Gemfile.lockruby# Gemfile source "https://rubygems.org" gem "fastlane" gem "cocoapods" # For iOS plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path)
ruby# fastlane/Fastfile default_platform(:ios) before_all do ensure_git_status_clean git_pull end platform :ios do desc "Run tests" lane :test do scan( scheme: "MyApp", devices: ["iPhone 15 Pro"], code_coverage: true, output_directory: "./fastlane/test_output" ) end desc "Build and upload to TestFlight" lane :beta do increment_build_number(xcodeproj: "MyApp.xcodeproj") match(type: "appstore", readonly: true) gym( scheme: "MyApp", export_method: "app-store", output_directory: "./build" ) pilot( skip_waiting_for_build_processing: true, changelog: "Bug fixes and improvements" ) commit_version_bump( message: "Bump build number [skip ci]", xcodeproj: "MyApp.xcodeproj" ) push_to_git_remote end desc "Deploy to App Store" lane :release do capture_screenshots increment_version_number(bump_type: "patch") increment_build_number match(type: "appstore", readonly: true) gym(scheme: "MyApp", export_method: "app-store") deliver( submit_for_review: true, automatic_release: false, force: true, precheck_include_in_app_purchases: false ) end error do |lane, exception| slack( message: "Lane #{lane} failed: #{exception.message}", success: false ) end end platform :android do desc "Run tests" lane :test do gradle(task: "testDebugUnitTest") end desc "Build and upload to Firebase App Distribution" lane :beta do gradle( task: "bundle", build_type: "Release" ) firebase_app_distribution( app: ENV["FIREBASE_APP_ID"], groups: "internal-testers", release_notes: "Bug fixes and improvements" ) end desc "Deploy to Play Store" lane :release do gradle( task: "bundle", build_type: "Release" ) supply( track: "production", aab: "./app/build/outputs/bundle/release/app-release.aab", skip_upload_metadata: true, skip_upload_images: true, skip_upload_screenshots: true ) end end
ruby# fastlane/Matchfile git_url("git@github.com:organization/certificates.git") storage_mode("git") type("appstore") app_identifier(["com.example.myapp", "com.example.myapp.widget"]) username("developer@example.com") # For CI environments readonly(is_ci) # Platform platform("ios")
ruby# fastlane/Appfile # iOS app_identifier("com.example.myapp") apple_id("developer@example.com") team_id("XXXXXXXXXX") itc_team_id("XXXXXXXXXX") # Android json_key_file("./fastlane/play-store-key.json") package_name("com.example.myapp") # Environment-specific for_platform :ios do for_lane :beta do app_identifier("com.example.myapp.beta") end end
yaml# .github/workflows/ios-deploy.yml name: iOS Deploy on: push: branches: [main] tags: ['v*'] jobs: deploy: runs-on: macos-14 steps: - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: '3.2' bundler-cache: true - name: Install dependencies run: bundle install - name: Set up certificates env: MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_AUTH }} run: bundle exec fastlane match appstore --readonly - name: Build and deploy env: APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.ASC_KEY_ID }} APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }} APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_KEY }} run: | if [[ $GITHUB_REF == refs/tags/* ]]; then bundle exec fastlane ios release else bundle exec fastlane ios beta fi - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: build-artifacts path: | ./build/*.ipa ./fastlane/test_output/
yaml# .github/workflows/android-deploy.yml name: Android Deploy on: push: branches: [main] tags: ['v*'] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' cache: gradle - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: '3.2' bundler-cache: true - name: Decode keystore run: | echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > app/release.keystore - name: Create key.properties run: | echo "storeFile=release.keystore" >> android/key.properties echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> android/key.properties echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> android/key.properties echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties - name: Create Play Store key run: echo '${{ secrets.PLAY_STORE_KEY }}' > fastlane/play-store-key.json - name: Build and deploy run: | if [[ $GITHUB_REF == refs/tags/* ]]; then bundle exec fastlane android release else bundle exec fastlane android beta fi
app-store-connect - App Store managementgoogle-play-console - Play Store managementmobile-testing - Test automation| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 18,676 | 18,857 | +1% | 1 | 1 | 0% | 2,958 | 5,410 | +83% | 0 | 0 | — |
case-02 | fail→fail | 19,790 | 14,905 | -25% | 1 | 1 | 0% | 3,878 | 5,988 | +54% | 0 | 0 | — |
case-03 | pass→pass | 7,793 | 7,287 | -6% | 1 | 1 | 0% | 1,379 | 3,692 | +168% | 0 | 0 | — |
case-04 | pass→pass | 7,516 | 6,948 | -8% | 1 | 1 | 0% | 1,519 | 4,266 | +181% | 0 | 0 | — |
case-05 | pass→pass | 12,859 | 10,544 | -18% | 1 | 1 | 0% | 2,320 | 4,963 | +114% | 0 | 0 | — |
case-06 | fail→pass | 10,176 | 5,331 | -48% | 1 | 1 | 0% | 1,895 | 3,959 | +109% | 0 | 0 | — |
case-07 | pass→pass | 9,870 | 6,572 | -33% | 1 | 1 | 0% | 1,422 | 4,053 | +185% | 0 | 0 | — |
case-08 | fail→pass | 9,088 | 15,573 | +71% | 1 | 1 | 0% | 1,262 | 4,557 | +261% | 0 | 0 | — |
case-09 | pass→pass | 13,098 | 16,284 | +24% | 1 | 1 | 0% | 2,453 | 5,425 | +121% | 0 | 0 | — |
case-10 | pass→pass | 9,845 | 4,508 | -54% | 1 | 1 | 0% | 1,520 | 3,640 | +139% | 0 | 0 | — |
case-11 | pass→pass | 11,381 | 10,563 | -7% | 1 | 1 | 0% | 1,730 | 4,016 | +132% | 0 | 0 | — |
case-12 | pass→pass | 7,115 | 7,620 | +7% | 1 | 1 | 0% | 1,176 | 3,979 | +238% | 0 | 0 | — |
case-13 | pass→pass | 16,070 | 12,391 | -23% | 1 | 1 | 0% | 3,080 | 5,197 | +69% | 0 | 0 | — |
case-14 | pass→pass | 11,541 | 8,161 | -29% | 1 | 1 | 0% | 1,658 | 4,464 | +169% | 0 | 0 | — |
case-15 | pass→pass | 7,809 | 7,229 | -7% | 1 | 1 | 0% | 1,150 | 3,533 | +207% | 0 | 0 | — |
case-16 | pass→pass | 9,088 | 7,766 | -15% | 1 | 1 | 0% | 1,349 | 4,268 | +216% | 0 | 0 | — |
case-17 | pass→pass | 10,218 | 7,658 | -25% | 1 | 1 | 0% | 1,930 | 4,020 | +108% | 0 | 0 | — |
case-18 | pass→pass | 17,182 | 6,236 | -64% | 1 | 1 | 0% | 3,090 | 4,314 | +40% | 0 | 0 | — |
case-19 | fail→fail | 7,670 | 6,051 | -21% | 1 | 1 | 0% | 1,339 | 3,751 | +180% | 0 | 0 | — |
case-20 | pass→pass | 12,818 | 18,693 | +46% | 1 | 1 | 0% | 2,812 | 6,163 | +119% | 0 | 0 | — |
case-21 | pass→pass | 14,993 | 9,444 | -37% | 1 | 1 | 0% | 2,507 | 4,809 | +92% | 0 | 0 | — |
case-22 | pass→pass | 12,886 | 9,732 | -24% | 1 | 1 | 0% | 1,841 | 4,402 | +139% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.