Ana Sayfa / Blog / Fastlane ile release automation: gerçek bir pipeline

Fastlane ile release automation: gerçek bir pipeline

iOS release tek tıkla olmalı. Fastlane ile benim kullandığım 12 app'te tekrarlanabilir pipeline.

iOS release manuel yapılırsa: build, archive, dSYM upload, TestFlight, metadata update, screenshot, release notes, submit. Hepsi ayrı click. Bir release 3-4 saat. Yanlış yapıldığında ise 1-2 gün kaybedebiliyorsun.

Fastlane ile tüm bu steps tek komutla çalışıyor. 12 app’imde kullandığım pipeline’ı paylaşacağım.

Fastlane nedir, kısaca

Fastlane Ruby-based iOS/Android automation tool. Fastfile’da “lane” tanımlıyorsun, her lane bir iş akışı.

Install:

brew install fastlane
# veya
gem install fastlane

Fastfile (project root’ta fastlane/Fastfile):

platform :ios do
  lane :beta do
    # TestFlight release
  end
  
  lane :release do
    # App Store release
  end
end

Komut: fastlane beta veya fastlane release.

Temel beta pipeline’ım

Fastfile’ımdaki beta lane:

lane :beta do
  # 1. Git check
  ensure_git_status_clean
  
  # 2. Certificates
  match(type: "appstore", readonly: true)
  
  # 3. Build
  build_app(
    scheme: "MyApp",
    configuration: "Release",
    export_method: "app-store",
    output_directory: "./builds",
    clean: true
  )
  
  # 4. TestFlight upload
  upload_to_testflight(
    skip_waiting_for_build_processing: true,
    changelog: File.read("./CHANGELOG.md")
  )
  
  # 5. dSYM upload
  upload_symbols_to_crashlytics(
    dsym_path: lane_context[SharedValues::DSYM_OUTPUT_PATH],
    gsp_path: "./GoogleService-Info.plist"
  )
  
  # 6. Slack notification
  slack(
    message: "Beta build uploaded to TestFlight",
    success: true
  )
  
  # 7. Git tag
  add_git_tag(tag: "beta-#{get_build_number}")
  push_git_tags
end

Bu 7 step manuel yapsan 2-3 saat. Fastlane ile fastlane beta tek komut, 10-15 dakika.

Production release pipeline

lane :release do
  # Pre-release checks
  ensure_git_branch(branch: "main")
  ensure_git_status_clean
  
  # Version bump (minor)
  increment_version_number(bump_type: "minor")
  increment_build_number
  
  # Build
  match(type: "appstore", readonly: true)
  build_app(scheme: "MyApp", configuration: "Release")
  
  # Metadata update (App Store Connect)
  deliver(
    submit_for_review: false,
    automatic_release: false,
    force: true,
    metadata_path: "./fastlane/metadata",
    screenshots_path: "./fastlane/screenshots"
  )
  
  # Crashlytics dSYM
  upload_symbols_to_crashlytics(
    dsym_path: lane_context[SharedValues::DSYM_OUTPUT_PATH]
  )
  
  # Commit version changes
  version = get_version_number(target: "MyApp")
  build = get_build_number
  commit_version_bump(message: "Release #{version} (#{build})")
  add_git_tag(tag: "v#{version}")
  push_to_git_remote
  
  # Slack notification
  slack(
    message: "New version #{version} submitted to App Store",
    channel: "#releases"
  )
end

Bu pipeline ile her production release 20-30 dakika. Yanlış yapma riski neredeyse yok.

Match: code signing otomasyon

Fastlane’in en güçlü tool’u match. Certificate + provisioning profile management automated.

Setup:

fastlane match init

Git repo seçiyorsun (private), match certificates’ı oraya şifreli save ediyor. Team’inin tüm developer’ları aynı cert’e erişiyor.

Usage (Fastfile):

match(type: "appstore", readonly: true)

readonly: true yeni cert üretmiyor, mevcut kullanıyor. CI’da her zaman readonly.

Match olmadan certificate management her developer için manuel, onboarding 1-2 saat. Match ile 5 dakika.

Metadata management

App Store Connect’e her release metadata (description, keywords, what’s new, screenshots) girmek zaman alıyor.

Fastlane deliver bu işi otomatize ediyor:

fastlane/metadata/
  en-US/
    description.txt
    keywords.txt
    release_notes.txt
  tr-TR/
    description.txt
    ...
  [36 dilde]

Her dil için text file. fastlane deliver → App Store Connect’e upload.

Yeni versiyon release notes’u güncelleyip fastlane beta çalıştırıyorsun. Metadata tüm dillerde update.

Screenshots automation (snapshot)

App Store’da 36 dil * 6 screenshot * 3 device = 648 screenshot. Manuel imkansız.

Fastlane snapshot:

  1. UI test target oluştur
  2. Snapfile config: desteklenen device’lar, diller
  3. UI test’ler ekranları capture ediyor
  4. fastlane snapshot → 648 screenshot generated
# Snapfile
devices([
  "iPhone 15 Pro",
  "iPhone SE (3rd generation)",
  "iPad Pro 12.9-inch"
])
languages([
  "en-US", "tr-TR", "de-DE", ... # 36 dil
])

1-2 saatlik iş. Haftada çalıştırıyorum, release’den önce güncel screenshot’lar hazır.

CI/CD integration

Fastlane local’de çalışıyor ama CI/CD’de automate et:

GitHub Actions example:

# .github/workflows/release.yml
name: Release
on:
  push:
    tags: ['v*']

jobs:
  release:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.1'
          bundler-cache: true
      
      - name: Run Fastlane
        env:
          APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
        run: bundle exec fastlane release

Git tag push edince (git tag v2.3.0 && git push origin v2.3.0) otomatik release pipeline çalışıyor.

Secrets management

Fastlane’in kullandığı secret’lar:

  • Apple ID password / App Store Connect API key
  • Match password (cert decryption)
  • GitHub API token (git push için)
  • Firebase API key (Crashlytics için)
  • Slack webhook URL

Bu secrets environment variable olarak geçiyor:

env FASTLANE_PASSWORD=xxx MATCH_PASSWORD=yyy fastlane beta

CI’da GitHub Secrets, local’de .env file (gitignore’de).

Don’t:
– Fastfile içinde secret hard-code etme
– Secret’ları shell history’e bırakma
– Git’te secrets.yml tutma

Do:
.env.default dummy values ile committed, .env actual values gitignored
– CI’da secrets management (GitHub Secrets, AWS Secrets Manager)
– Rotation disciplin: quarterly secret rotation

Error handling

Fastlane pipeline fail olunca ne olacak?

error do |lane, exception|
  slack(
    message: "Fastlane fail: #{exception.message}",
    success: false,
    channel: "#alerts"
  )
end

error do block’u fail’de çalışıyor. Slack alert gönderiyor, team immediately biliyor.

Ayrıca rollback logic:

lane :release do
  # ... pipeline steps ...
  
  rescue => e
    # Version'ı revert et
    git_revert
    UI.user_error!("Release failed: #{e}")
end

Yarım deploy’ları prevent ediyor.

Plugin ecosystem

Fastlane 400+ plugin. Most popular:

  • fastlane-plugin-firebase_app_distribution: Firebase test distribution
  • fastlane-plugin-sentry: Sentry dSYM upload
  • fastlane-plugin-versioning: Advanced version bumping
  • fastlane-plugin-badge: Icon’a badge ekle (beta, staging)
  • fastlane-plugin-changelog: Changelog generation from git

Install:

fastlane add_plugin sentry

Common pitfalls

1. Fastfile çok uzun. 500 satır Fastfile unreadable. Lanes’i modular yap, shared logic’i method’lara çıkart.

2. Version bump’ı hatalı. Build number monotonic artmalı. Git tag’lerle sync discipline gerekli.

3. Metadata’da typo. App Store Connect reject ediyor. Pre-upload validation:

fastlane run deliver --metadata_only --submit_for_review false

4. Expire olmuş certificates. Match readonly kullanıyor ama cert expire olmuşsa fail. Quarterly check et.

5. TestFlight beta expiry. 90 gün sonra build’ler expire. Lanes’e expiry warning logic ekle.

Bundle versioning

Gem’leri Gemfile’da lock:

# Gemfile
source "https://rubygems.org"
gem "fastlane", "~> 2.215.0"

Lockfile commit’le. Team member’lar ve CI aynı Fastlane version kullanıyor, breaking change’ler surprise olmuyor.

Continuous improvement

Pipeline zaman içinde evolve ediyor. Benim 12 app’teki refinement’lar:

  • Initial: basic build + TestFlight
  • +1 month: dSYM upload automation
  • +2 months: Slack notifications
  • +3 months: Automated screenshots (snapshot)
  • +6 months: Multi-environment pipelines (staging, production)
  • +12 months: Complex metadata management

Every release’den sonra pipeline’a eklenecek bir şey buluyorum. Continuous improvement mindset.

Sonuç

Fastlane iOS release automation’ın altın standardı. Initial setup 1-2 günlük iş ama ondan sonra her release 3-4 saatten 20-30 dakikaya düşüyor.

Match code signing, deliver metadata, snapshot screenshots, CI/CD integration. Hepsi production-ready.

Solo developer için overkill değil. 12 app’lik portfolyomu tek başıma yönetmek Fastlane olmadan imkansız. Senin portföyün 2-3 app olsa bile yatırım karşılanıyor.

Bu konuda bir projeniz mi var?

Kısa bir özet bırakın, 24 saat içinde size dönüş yapayım.

İletişime Geç