通过 Crashlytics 构建和上传多种口味的 Fastfile

这是一个多风味应用程序的 Fastfile 设置示例。它为你提供了构建和部署所有口味或单一口味的选项。部署之后,它向 Slack 报告部署状态,并通过 Crashlytics 测试人员组向 Beta 测试人员发送通知。

要构建和部署所有口味,请使用:

fastlane android beta

要构建单个 APK 并部署使用:

fastlane android beta app:flavorName

使用单个 Fastlane 文件,你可以管理 iOS,Android 和 Mac 应用程序。如果你只为一个应用程序使用此文件,则不需要 platform

这个怎么运作

  1. android 论证告诉 fastlane 我们将使用:android 平台。
  2. :android 平台内,你可以拥有多个车道。目前,我只有:beta 车道。上面命令的第二个参数指定了我们想要使用的通道。
  3. options[:app]
  4. 有两个 Gradle 任务。首先,它运行 gradle clean。如果你提供了 app 键的味道,fastfile 运行 gradle assembleReleaseFlavor。否则,它会运行 gradle assembleRelease 来构建所有构建版本。
  5. 如果我们为所有风格构建,则生成的 APK 文件名数组存储在 SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS 中。我们使用它来循环生成的文件,并通过 Crashlytics 将它们部署到 Betanotificationsgroups 字段是可选的。它们用于通知 CrashlyticsBeta 上注册该应用的测试人员
  6. 如果你熟悉 Crashlytics,你可能知道要在门户中激活应用程序,你必须先在设备上运行它并首先使用它。否则,Crashlytics 将假定应用程序处于非活动状态并抛出错误。在这种情况下,我捕获它并向 Slack 报告失败,因此你将知道哪个应用程序处于非活动状态。
  7. 如果部署成功, fastlane 将向 Slack 发送成功消息。
  8. #{/([^\/]*)$/.match(apk)} 这个正则表达式用于从 APK 路径获取风味名称。如果它不适合你,你可以将其删除。
  9. get_version_nameget_version_code 是两个 Fastlane 插件,用于检索应用程序版本名称和代码。如果要使用,则必须安装这些宝石,或者可以删除它们。在此处阅读有关插件的更多信息
  10. 如果你正在构建和部署单个 APK,则将执行 else 语句。我们没有向 Crashlytics 提供 apk_path,因为我们只有一个应用程序。
  11. 最后的 error do 块用于在执行期间出现任何其他错误时收到通知。

注意

不要忘记用自己的凭据替换 SLACK_URLAPI_TOKENGROUP_NAMEBUILD_SECRET

fastlane_version "1.46.1"

default_platform :android

platform :android do

    before_all do
        ENV["SLACK_URL"] = "https://hooks.slack.com/servic...."
    end
    
    lane :beta do |options|
        # Clean and build the Release version of the app.
        # Usage `fastlane android beta app:flavorName`
    
        gradle(task: "clean")
    
        gradle(task: "assemble",
               build_type: "Release",
               flavor: options[:app])
    
        # If user calls `fastlane android beta` command, it will build all projects and push them to Crashlytics
        if options[:app].nil?
            lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS].each do | apk |
    
                puts "Uploading APK to Crashlytics: " + apk
    
                begin
                    crashlytics(
                      api_token: "[API_TOKEN]",
                      build_secret: "[BUILD_SECRET]",
                      groups: "[GROUP_NAME]",
                      apk_path: apk,
                      notifications: "true"
                    )
    
                    slack(
                      message: "Successfully deployed new build for #{/([^\/]*)$/.match(apk)} #{get_version_name} - #{get_version_code}",
                      success: true,
                      default_payloads: [:git_branch, :lane, :test_result]
                    )
                rescue => ex
                    # If the app is inactive in Crashlytics, deployment will fail. Handle it here and report to slack
                    slack(
                        message: "Error uploading => #{/([^\/]*)$/.match(apk)} #{get_version_name} - #{get_version_code}: #{ex}",
                        success: false,
                        default_payloads: [:git_branch, :lane, :test_result]
                    )
                end
            end
    
            after_all do |lane|
                # This block is called, only if the executed lane was successful
                slack(
                    message: "Operation completed for #{lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS].size} app(s) for #{get_version_name} - #{get_version_code}",
                    default_payloads: [:git_branch, :lane, :test_result],
                    success: true
                )
            end
        else
            # Single APK upload to Beta by Crashlytics
            crashlytics(
                api_token: "[API_TOKEN]",
                build_secret: "[BUILD_SECRET]",
                groups: "[GROUP_NAME]",
                notifications: "true"
            )
    
            after_all do |lane|
                # This block is called, only if the executed lane was successful
                slack(
                    message: "Successfully deployed new build for #{options[:app]} #{get_version_name} - #{get_version_code}",
                    default_payloads: [:git_branch, :lane, :test_result],
                    success: true
                )
            end
        end
    
        error do |lane, exception|
            slack(
                message: exception.message,
                success: false,
                default_payloads: [:git_branch, :lane, :test_result]
            )
        end
    end
end