Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How we use fastlane at Wantedly

How we use fastlane at Wantedly

2015.06.26 #fastlane_jp

Jiro Nagashima

June 26, 2015
Tweet

More Decks by Jiro Nagashima

Other Decks in Technology

Transcript

  1. How we use fastlane
    at Wantedly
    JIRO NAGASHIMAʗ@hedjirog

    View full-size slide

  2. Jiro Nagashima
    @hedjirog
    wantedly.com/users/3153

    View full-size slide

  3. γΰτͰίίϩΦυϧ

    View full-size slide

  4. γΰτͰίίϩΦυϧ

    View full-size slide

  5. γΰτͰίίϩΦυϧ

    View full-size slide

  6. γΰτͰίίϩΦυϧ
    2 Apps

    View full-size slide

  7. γΰτͰίίϩΦυϧ
    2 Apps
    1 Project
    (Targets)

    View full-size slide

  8. γΰτͰίίϩΦυϧ
    • It's a lot of trouble…
    • Beta Distribution
    • Submitting to the App Store
    • Integration Tests
    2 Apps
    (Targets)

    View full-size slide

  9. γΰτͰίίϩΦυϧ

    View full-size slide

  10. γΰτͰίίϩΦυϧ
    • Use fastlane to
    1. Distribute beta buils
    2. Submit apps to the App Store
    3. Take screenshots
    fastlane

    View full-size slide

  11. γΰτͰίίϩΦυϧ
    1. Beta Distribution

    View full-size slide

  12. Build
    Distribution
    Download
    Import

    View full-size slide

  13. Build
    Distribution
    Download
    Import

    View full-size slide

  14. Workflow
    Push

    View full-size slide

  15. γΰτͰίίϩΦυϧ
    • Tools
    • Fabric (Crashlytics Beta)
    • fastlane
    • CircleCI
    Beta Distribution

    View full-size slide

  16. γΰτͰίίϩΦυϧ
    • Tools
    • Fabric (Crashlytics Beta)
    • fastlane
    • CircleCI
    Beta Distribution

    View full-size slide

  17. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import

    View full-size slide

  18. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import

    View full-size slide

  19. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import

    View full-size slide

  20. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import

    View full-size slide

  21. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import

    View full-size slide

  22. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile - Built-in Action
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import
    Action
    Action
    Action

    View full-size slide

  23. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile - Custom Action
    lane :beta do
    # Import certificates
    cert_dir = "./fastlane/certificates"
    import_certificates(
    cert_paths: [
    File.join(cert_dir, "apple.cer")
    ],
    key_paths: [
    File.join(cert_dir, "development.p12"),
    File.join(cert_dir, "distribution.p12")
    ]
    )
    # Download provisioning profiles
    sigh(
    app_identifier: "com.wantedly.app-qa",
    adhoc: true
    )
    # Build
    ipa(
    scheme: "app",
    configuration: "QA"
    )
    # Push to Crashlytics
    crashlytics(
    crashlytics_path: "./Pods/Fabric/Crashlytics.framework",
    groups: "Developers"
    )
    end
    Build
    Distribution
    Download
    Import
    Custom Action

    View full-size slide

  24. γΰτͰίίϩΦυϧ
    Beta Distribution
    fastlane / Fastfile - Custom Action
    class ImportCertificatesAction < Action
    def self.run(params)
    cert_paths = params[:cert_paths]
    key_paths = params[:key_paths]
    keychain = "ios-build.keychain"
    password = "ios-build"
    timeout_seconds = 3600
    begin
    sh "security create-keychain -p #{password} #{keychain}"
    sh "security default-keychain -s #{keychain}"
    sh "security list-keychains -s #{keychain}"
    sh "security unlock-keychain -p #{password} #{keychain}"
    sh "security set-keychain-settings -t #{timeout_seconds} -l #{keychain}"
    cert_paths.each do |cert_path|
    sh "security import #{cert_path} -k #{keychain} -T /usr/bin/codesign"
    end
    key_paths.each do |key_path|
    # Don't use `sh` so as not to output a password.
    `security import #{key_path} -k #{keychain} -P #{ENV['P12_PASSWORD']} -T /usr/bin/codesign`
    raise "Password is not correct" unless $?.to_i == 0
    end
    Helper.log.info 'Successfully import certificates .'.green
    rescue => ex
    Helper.log.error 'Failed to import certificates'.red
    raise ex
    end
    end

    View full-size slide

  25. γΰτͰίίϩΦυϧ
    • Tools
    • Fabric (Crashlytics Beta)
    • fastlane
    • CircleCI
    Beta Distribution

    View full-size slide

  26. γΰτͰίίϩΦυϧ
    Beta Distribution
    CircleCI / circle.yml
    deployment:
    beta:
    branch: master
    commands:
    - bundle exec fastlane beta_app1
    - bundle exec fastlane beta_app2
    • Execute workflows with fastlane

    View full-size slide

  27. γΰτͰίίϩΦυϧ
    Beta Distribution
    CircleCI / circle.yml
    deployment:
    beta:
    branch: master
    commands:
    - bundle exec fastlane beta_app1
    - bundle exec fastlane beta_app2
    • Execute workflows with fastlane

    View full-size slide

  28. γΰτͰίίϩΦυϧ
    2. Submitting Apps

    View full-size slide

  29. γΰτͰίίϩΦυϧ
    Submitting Apps
    Fastfile
    lane :deploy do
    ensure_git_status_clean
    increment_build_number
    commit_version_bump
    schemes = ["app1", "app2"]
    schemes.each do |scheme|
    ipa(
    scheme: scheme,
    configuration: "Release"
    )
    deliver(
    deliver_file_path: "./fastlane/#{scheme}"
    )
    end
    end

    View full-size slide

  30. γΰτͰίίϩΦυϧ
    Submitting Apps
    Fastfile
    lane :deploy do
    ensure_git_status_clean
    increment_build_number
    commit_version_bump
    schemes = ["app1", "app2"]
    schemes.each do |scheme|
    ipa(
    scheme: scheme,
    configuration: "Release"
    )
    deliver(
    deliver_file_path: "./fastlane/#{scheme}"
    )
    end
    end
    • Specify Deliverfile for each app

    View full-size slide

  31. γΰτͰίίϩΦυϧ
    Submitting Apps
    Contents of Directories
    $ tree fastlane
    fastlane
    ├── Fastfile
    ├── app1
    │ ├── Deliverfile
    │ …
    └── app2
    ├── Deliverfile

    View full-size slide

  32. γΰτͰίίϩΦυϧ
    Submitting Apps
    Contents of Directories
    $ tree fastlane
    fastlane
    ├── Fastfile
    ├── app1
    │ ├── Deliverfile
    │ …
    └── app2
    ├── Deliverfile

    Multiple Deliverfiles

    View full-size slide

  33. γΰτͰίίϩΦυϧ
    Submitting Apps
    Contents of Directories
    $ tree fastlane
    fastlane
    ├── Fastfile
    └── app1
    ├── Deliverfile
    └── metadata
    └── ja-JP
    ├── description.txt
    ├── keywords.txt
    ├── privacy_url.txt
    ├── software_url.txt
    ├── support_url.txt
    ├── title.txt
    └── version_whats_new.txt

    View full-size slide

  34. γΰτͰίίϩΦυϧ
    Submitting Apps
    Commands
    $ bundle exec fastlane deploy
    • That’s all!

    View full-size slide

  35. γΰτͰίίϩΦυϧ
    3. Taking Screenshots

    View full-size slide

  36. γΰτͰίίϩΦυϧ
    Taking Screenshots
    iPhone 5
    iPhone 6
    iPhone 6 Plus
    iPad Air
    2 Apps

    View full-size slide

  37. γΰτͰίίϩΦυϧ
    Taking Screenshots
    Fastfile
    lane :snapshot do
    schemes = ["app1", "app2"]
    schemes.each do |scheme|
    snapshot(
    snapshot_file_path: "./fastlane/#{scheme}"
    )
    end
    end

    View full-size slide

  38. γΰτͰίίϩΦυϧ
    Taking Screenshots
    Fastfile
    lane :snapshot do
    schemes = ["app1", "app2"]
    schemes.each do |scheme|
    snapshot(
    snapshot_file_path: "./fastlane/#{scheme}"
    )
    end
    end
    • Specify Snapfile for each app

    View full-size slide

  39. γΰτͰίίϩΦυϧ
    Taking Screenshots
    Contents of Directories
    $ tree fastlane
    fastlane
    ├── Fastfile
    ├── app1
    │ ├── Snapfile
    │ …
    └── app2
    ├── Snapfile

    View full-size slide

  40. γΰτͰίίϩΦυϧ
    Taking Screenshots
    Contents of Directories
    $ tree fastlane
    fastlane
    ├── Fastfile
    ├── app1
    │ ├── Snapfile
    │ …
    └── app2
    ├── Snapfile

    Multiple Snapfile

    View full-size slide

  41. γΰτͰίίϩΦυϧ
    Taking Screenshots
    Contents of Directories
    $ tree fastlane
    fastlane
    ├── Fastfile
    └── app1
    ├── Snapfile
    └── js
    ├── helpers
    │ └── capture.js
    ├── screens
    │ ├── activitiesScreen.js
    │ ├── featureScreen.js
    │ ├── messagesScreen.js
    │ ├── profileScreen.js
    │ ├── projectScreen.js
    │ ├── projectsScreen.js
    │ ├── screen.js
    │ ├── settingsScreen.js
    │ └── welcomeScreen.js
    ├── screens.js
    └── snapshot.js

    View full-size slide

  42. γΰτͰίίϩΦυϧ
    Taking Screenshots
    Commands
    $ bundle exec fastlane snapshot
    • That’s all!

    View full-size slide

  43. γΰτͰίίϩΦυϧ
    • Use fastlane to
    1. Distribute beta buils
    2. Submit apps to the App Store
    3. Take screenshots

    View full-size slide

  44. iOS, Android, Rails Engineer
    WE’RE HIRING!!!

    View full-size slide