How to shorten build time of Flutter iOS app using fastlane
Asked Answered
D

1

6

My problem is that when using Firebase (cloud_firestore in particular) the build times of Flutter iOS app get so long, that my CI build on Bitrise reaches timeout (28 min for flutter build --release and again more than 20 min for fastlane's build_ios_app). So I'm unable to perform full iOS build on my CI. Caching of course is possible, but firstly an initial build must be done :/

According to this guide it's necessary to rebuild iOS app when archiving with Xcode using Fastlane. There is, however, a discussion on official Github repo about introducing a command to publish IPA file directly from Flutter but for now it's impossible.

My question is - are there any ways to shorten this build time e.g. by skipping building in fastlane step and just resigning and archiving .app file to .ipa? I couldn't make it work by myself.

Here you may find a sample Flutter app with cloud_firestore enabled.

Below you may find my Bitrise and fastlane configuration:

---
format_version: '7'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: flutter
trigger_map:
- push_branch: master
workflow: test
workflows:
prepare:
    steps:
    - [email protected]:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - [email protected]:
        title: APP_NAME
        inputs:
        - destination_keys: APP_NAME
        - value: pl.flutter.buildTimeIssue
    - [email protected]:
        title: FL_BUILD_NUMBER
        inputs:
        - destination_keys: FL_BUILD_NUMBER
        - value: "$BITRISE_BUILD_NUMBER"
    - [email protected]:
        title: FL_VERSION_NUMBER
        inputs:
        - destination_keys: FL_VERSION_NUMBER
        - value: 0.1.$BITRISE_BUILD_NUMBER
    - [email protected]: {}
    - cache-pull: {}
    - [email protected]: {}
    - flutter-installer:
        inputs:
        - version: v1.2.1
    - [email protected]:
        inputs:
        - content: |-
            #!/usr/bin/env bash
            # fail if any commands fails
            set -e
            # debug log
            set -x

            cd $BITRISE_FLUTTER_PROJECT_LOCATION/ios
            pod repo update
        title: Update pods repository
test:
    before_run:
    - prepare
    steps:
    - [email protected]:
        inputs:
        - project_location: "$BITRISE_FLUTTER_PROJECT_LOCATION"
        - ios_additional_params: "--release --no-codesign -t lib/main.dart
            --build-name=$FL_VERSION_NUMBER --build-number=$FL_BUILD_NUMBER"
        is_always_run: true
    - [email protected]:
        title: fastlane iOS
        inputs:
        - work_dir: "$BITRISE_FLUTTER_PROJECT_LOCATION/ios"
        - lane: ios test
    after_run:
    - finish
    envs:
    - opts:
        is_expand: false
    FLAVOR: tst
    - opts:
        is_expand: false
    TARGET_FILE: main_tst
finish:
    steps:
    - [email protected]:
        inputs:
        - ignore_check_on_paths: "~/Library/Developer/Xcode/DerivedData"
        - cache_paths: |-
            $BITRISE_FLUTTER_PROJECT_LOCATION/build
            $BITRISE_FLUTTER_PROJECT_LOCATION/ios/Pods
            ~/Library/Developer/Xcode/DerivedData
app:
envs:
- opts:
    is_expand: false
    BITRISE_FLUTTER_PROJECT_LOCATION: ./
- opts:
    is_expand: false
    BITRISE_PROJECT_PATH: ./ios/Runner.xcworkspace
- opts:
    is_expand: false
    BITRISE_SCHEME: tst
- opts:
    is_expand: false
    BITRISE_EXPORT_METHOD: ad-hoc

And here is fastlane:

default_platform(:ios)

platform :ios do
  lane :test do
    match(
      type: "adhoc",
      force_for_new_devices: true,
    )
    automatic_code_signing(
      use_automatic_signing: false
    )
    update_project_provisioning(
      profile: ENV["sigh_pl.flutter.buildTimeIssue_adhoc_profile-path"],
      build_configuration: "Release",
      code_signing_identity: "iPhone Distribution"
    )
    build_app(
      scheme: "tst",
      configuration: "Release",
      xcargs: "-allowProvisioningUpdates",
      export_options: {
        signingStyle: "manual",
        method: "ad-hoc",
        provisioningProfiles: {
          "pl.flutter.buildTimeIssue": "match AdHoc pl.flutter.buildTimeIssue"
        }
      },
      output_name: "Runner.ipa"
    )
    appcenter_upload(
      app_name: "Name",
      owner_name: "Owner",
      group: "All-users-of-Name",
      ipa: "Runner.ipa"
    )
  end
end
Deipnosophist answered 11/5, 2019 at 11:15 Comment(2)
Is there a way to do the full build outside of Bitrise? This would make it much easier for someone to take your example repository (awesome that your questions already contains one!) and try to recreate what you are experiencing. (Fastlane can execute any shell commands with the sh action for example, aybe this makes it possible to add a full_run lane to your Fastfile that does the whole thing locally?)Hauberk
Actually you could build this even on your machine. The reason why I'm mentioning Bitrise is that it creates clean VM every time so without pulling the cache a full build is required. So in other words you can simply run flutter build ios --release and then fastlane run build_ios_app. If one could skip all the Compiling tasks in fastlane/Xcode build it would be the solution for my problem.Deipnosophist
T
4

I had same problem that I fixed with precompiled binaries of Cloud Firestore framework from https://github.com/invertase/firestore-ios-sdk-frameworks like this:

# ...
target 'Runner' do
  pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '6.26.0'

# ...
end

Full instructions could be found here https://github.com/FirebaseExtended/flutterfire/issues/2751

Telemotor answered 18/8, 2020 at 14:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.