fastlane 实现 iOS全流程自动化脚本实战指南

210 阅读9分钟

fastlane 实现 iOS全流程自动化脚本实战指南

fastlane 作为移动开发领域的自动化工具集,能将构建、分发、错误监控等重复性工作转化为可执行脚本,极大提升开发效率。本文基于 iOS 项目场景,详解从环境搭建到全流程自动化的实现方案。

1. 安装 fastlane

fastlane 支持 macOS、Linux、Windows 系统,推荐在 macOS 环境下使用,以下为完整安装流程:

1.1 前置环境准备

  • 安装Xcode

  • Ruby 环境:要求 Ruby 2.7 + 版本,验证命令:

ruby -v # 输出示例:ruby 3.2.2p53 (2023-03-30 revision e51014f9c0)

若版本过低,可通过gem update --system升级 RubyGems。

1.2 安装 Bundler

gem install bundler

1.3 安装 fastlane

推荐使用 bundle 方式安装 fastlane,因为项目中有 Gemfile,这样可以统一和管理依赖,避免全局依赖冲突。

在项目根目录下执行:

bundle install

初始化过程中需完成:

  1. 选择用途(推荐选 "4. 🛠️ Automate App Store distribution")
  2. 输入 App Store Connect 账号
  3. 等待依赖安装完成

初始化后生成核心文件:

  • fastlane/Fastfile:工作流配置核心文件
  • fastlane/Appfile:应用元数据配置(Bundle ID、团队 ID 等)
  • Gemfile:Ruby 依赖管理文件

2. 使用 build_app 构建 App

build_app是 fastlane 的核心构建动作(底层封装 xcodebuild),支持自定义构建参数,满足不同环境需求。

2.1 基础构建配置

Fastfile中定义构建 lane,包含清理缓存、指定 scheme、输出路径等配置:

default_platform(:ios)

platform :ios do

  # 开发环境构建
  lane :dev_build do
    # 清理之前的构建产物
    clean
    
    # 构建核心配置
    build_app(
      scheme: "MyApp-Dev", # Xcode中的scheme名称
      workspace: "MyApp.xcworkspace", # 若使用CocoaPods需指定
      export_method: "development", # 导出方式(开发环境)
      output_directory: "./builds/dev", # 构建产物存放路径
      output_name: "MyApp_Dev_#{Time.now.strftime('%Y%m%d_%H%M')}", # 带时间戳的文件名
      clean: true, # 构建前清理项目
      include_bitcode: false # 开发环境无需Bitcode
    )
    
    puts "✅ 开发环境构建完成,路径:./builds/dev"
  end
end

2.2 执行构建

终端执行以下命令触发构建:

fastlane dev_build

构建成功后,在./builds/dev目录下生成.ipa文件。

2.3 进阶配置

  • 指定设备与配置
build_app(
  configuration: "Release", # 构建配置(Release/Debug)
  
  device: "iPhone 15", # 模拟设备
  
  xcargs: "ARCHS=x86_64 ONLY_ACTIVE_ARCH=NO" # 额外编译参数
)
  • 版本号自增

    build_app前添加版本号管理动作:

increment_build_number # 自增构建号

increment_version_number(version_number: "1.2.0") # 指定版本号

3. upload_to_app_store 上传包到 App Store

upload_to_app_store可一键上传构建产物至 App Store Connect,支持自动提交审核。

3.1 前置准备

  1. Appfile中配置应用元数据:
app_identifier "com.example.myapp" # 应用Bundle ID

apple_id "developer@example.com" # App Store Connect账号

team_id "AB12XYZ345" # 开发团队ID(Apple开发者后台获取)
  1. 配置 App Store Connect 认证:

    推荐使用 API 密钥认证(替代账号密码),在 Apple 开发者后台创建密钥后,在项目根目录创建.env文件存储密钥:

APP_STORE_CONNECT_KEY_ID=ABC123

APP_STORE_CONNECT_ISSUER_ID=def456

APP_STORE_CONNECT_KEY_FILEPATH=./AuthKey_ABC123.p8

3.2 上传配置

Fastfile中添加发布 lane:

lane :appstore_release do

  # 1. 构建生产环境包

  build_app(
    scheme: "MyApp",
    export_method: "app-store", # 生产环境导出方式
    output_directory: "./builds/release",
    include_bitcode: true, # App Store必须开启Bitcode
    export_options: {
      signingStyle: "automatic", # 自动签名
      uploadBitcode: true,
      uploadSymbols: true
    }
  )

  # 2. 上传至App Store Connect
  upload_to_app_store(
    submit_for_review: false, # 暂不提交审核
    automatic_release: false, # 不自动发布
    skip_screenshots: true, # 跳过截图上传
    skip_metadata: true # 跳过元数据上传
  )

puts "✅ 已上传至App Store Connect"

end

3.3 执行上传

fastlane appstore_release

上传成功后可在 App Store Connect 的 "测试 Flight" 或 "构建版本" 中查看。

4. 使用 fastlane-plugin-pgyer 上传到蒲公英

蒲公英作为国内常用的测试分发平台,通过 fastlane 插件可实现自动上传与分发。

4.1 安装蒲公英插件

终端执行插件安装命令:

fastlane add_plugin pgyer

安装过程中若提示 "是否允许修改 Gemfile",输入y确认。

4.2 获取蒲公英密钥

登录蒲公英平台,在 "应用管理 - API 设置" 中获取:

  • api_key:接口密钥

  • user_key:用户密钥

将密钥存入.env文件:

PGYER_API_KEY=your_api_key

PGYER_USER_KEY=your_user_key

4.3 配置上传 lane

Fastfile中添加蒲公英分发 lane:

lane :pgyer_upload do

  # 先执行开发环境构建
  dev_build

  # 上传至蒲公英

  res = pgyer(

    api_key: ENV["PGYER_API_KEY"],

    user_key: ENV["PGYER_USER_KEY"],

    ipa: "path/name.ipa", # 读取构建产物路径

    update_description: "✅ 测试版本更新\n- 修复登录bug\n- 新增支付功能", # 更新描述

    password: "123456" # 安装密码(可选)

  )

end

4.4 执行分发

fastlane pgyer_upload

执行完成后,可通过输出的链接或二维码下载测试包。

5. upload_symbols_to_crashlytics 上传 dSYM 文件

dSYM 文件包含符号表信息,是 Firebase Crashlytics 解析崩溃日志的关键,通过 fastlane 可实现自动上传。

5.1 前置配置

  1. 集成 Firebase Crashlytics:按官方文档在 Xcode 项目中集成 SDK

  2. 获取 Google 服务配置:下载GoogleService-Info.plist放入项目目录

  3. 安装 Crashlytics 插件(部分版本需手动安装):

fastlane add_plugin crashlytics

5.2 配置 dSYM 上传

在构建 lane 中添加上传动作,确保构建后自动执行:

lane :dev_build do

  # 构建动作(同上)

  build_app(...)

  # 上传dSYM至Crashlytics
  upload_symbols_to_crashlytics(
  
    dsym_path: lane_context[SharedValues::DSYM_OUTPUT_PATH] # 读取dSYM路径
    
    binary_path: "path/upload_symbols", #指定工具路径
  )

end

5.3 验证上传

上传成功后,可在 Firebase 控制台的 "Crashlytics" 页面查看 "符号表状态",显示 "已处理" 即为成功。若失败,可检查:

  • dSYM 文件路径是否正确

  • GoogleService-Info.plist 配置是否完整

  • 网络连接是否正常

6. 添加 Webhook 实现飞书机器人通知

通过 Webhook 可将构建、分发结果自动推送至飞书群,支持自定义消息格式。

6.1 创建飞书机器人

  1. 打开飞书群聊,进入 "设置 - 群机器人 - 添加机器人 - 自定义机器人"

  2. 填写机器人名称(如 "构建通知机器人"),复制 "Webhook 地址"

  3. 将 Webhook 地址存入.env文件:

FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxx

6.2 配置通知脚本

Fastfile中定义通知方法,支持构建成功 / 失败两种场景:

# 飞书通知工具方法

def send_feishu_notification(title, content, is_success = true)

  # 消息颜色:成功(绿色),失败(红色)

  color = is_success ? "green" : "red"

  # 消息图标:成功(✅),失败(❌)

  icon = is_success ? "✅" : "❌"

  # 构建飞书消息体(支持Markdown)
  payload = {

    msg_type: "interactive",
    
    card: {
    
      config: { wide_screen_mode: true },
      
      header: {
      
        title: { content: "#{icon} #{title}", tag: "plain_text" },
        
        color: color
        
      },
      
      elements: [
      
        { tag: "div", text: { content: content, tag: "lark_md" } },
        
        { tag: "div", text: { content: "⏰ 时间:#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}", tag: "plain_text" } }
        
      ]
      
    }

  }


  # 发送POST请求

  response = HTTParty.post(

    ENV["FEISHU_WEBHOOK_URL"],

    body: payload.to_json,

    headers: { "Content-Type" => "application/json" }

  )

  

  puts response.success? ? "📨 飞书通知发送成功" : "❌ 飞书通知发送失败"

end

6.3 集成到工作流

在构建、分发 lane 中添加通知逻辑,包含错误捕获:

lane :pgyer_upload do

  begin

    # 执行构建与上传

    dev_build

    pgyer(...)

    

    # 构建成功通知

    content = <<\~MARKDOWN

    \*\*构建信息\*\*:

    - 应用名称:MyApp-测试版

    - 构建号:#{lane_context[SharedValues::BUILD_NUMBER]}

    - 版本号:#{lane_context[SharedValues::VERSION_NAME]}

    \*\*分发信息\*\*:

    - 下载链接:[点击下载]\(#{lane_context[:PGYER_APP_URL]})

    - 安装密码:123456

    MARKDOWN

    send_feishu_notification("测试版本分发完成", content)

    

  rescue => ex

    # 构建失败通知

    send_feishu_notification("测试版本构建失败", "错误信息:#{ex.message}", false)

    raise ex # 保留错误状态

  end

end

6.4 扩展:钉钉 / 邮件通知

  • 钉钉通知:替换飞书 Webhook 为钉钉机器人 Webhook,调整消息体格式(支持 Markdown)

  • 邮件通知:使用 fastlane 的mail动作,配置 SMTP 信息:

mail(

  to: "team@example.com",

  subject: "构建通知",

  body: content,

  smtp: {

    address: "smtp.example.com",

    port: 465,

    user_name: "notifier@example.com",

    password: "smtp_password",

    enable_starttls_auto: true

  }

)

7. 完整工作流示例

整合上述所有功能,最终Fastfile完整配置如下:

default_platform(:ios)

require "httparty" # 用于HTTP请求

platform :ios do

  # 环境变量加载

  dotenv_load(".env")

  # 飞书通知工具方法

  def send_feishu_notification(title, content, is_success = true)

    color = is_success ? "green" : "red"

    icon = is_success ? "✅" : "❌"

    

    payload = {

      msg_type: "interactive",

      card: {

        config: { wide_screen_mode: true },

        header: {

          title: { content: "#{icon} #{title}", tag: "plain_text" },

          color: color

        },

        elements: [

          { tag: "div", text: { content: content, tag: "lark_md" } },

          { tag: "div", text: { content: "⏰ 时间:#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}", tag: "plain_text" } }

        ]

      }

    }

    

    HTTParty.post(

      ENV["FEISHU_WEBHOOK_URL"],

      body: payload.to_json,

      headers: { "Content-Type" => "application/json" }

    )

  end

  # 开发环境构建

  lane :dev_build do

    clean
    
    build_app(
      scheme: "MyApp-Dev",

      workspace: "MyApp.xcworkspace",

      export_method: "development",

      output_directory: "./builds/dev",

      output_name: "MyApp_Dev_#{Time.now.strftime('%Y%m%d_%H%M')}",

      clean: true,

      include_bitcode: false

    )

    # 上传dSYM
    upload_symbols_to_crashlytics(

      gsp_path: "./MyApp/GoogleService-Info.plist",

      dsym_path: lane_context[SharedValues::DSYM_OUTPUT_PATH]

    )

  end

  # 蒲公英分发

  lane :pgyer_upload do

    begin

      dev_build

      

      pgyer(

        api_key: ENV["PGYER_API_KEY"],

        user_key: ENV["PGYER_USER_KEY"],

        ipa: lane_context[SharedValues::IPA_OUTPUT_PATH],

        update_description: "✅ 测试版本更新\n- 修复登录bug\n- 新增支付功能",

        install_type: 1,

        password: "123456"

      )

      

      content = <<\~MARKDOWN

      \*\*构建信息\*\*:

      \- 应用名称:MyApp-测试版

      \- 构建号:#{lane_context[SharedValues::BUILD_NUMBER]}

      \- 版本号:#{lane_context[SharedValues::VERSION_NAME]}

      \*\*分发信息\*\*:

      \- 下载链接:[点击下载]\(#{lane_context[:PGYER_APP_URL]})

      \- 安装密码:123456

      MARKDOWN

      send_feishu_notification("测试版本分发完成", content)

      

    rescue => ex

      send_feishu_notification("测试版本构建失败", "错误信息:#{ex.message}", false)

      raise ex

    end

  end

  # App Store发布

  lane :appstore_release do

    begin

      build_app(

        scheme: "MyApp",

        export_method: "app-store",

        output_directory: "./builds/release",

        include_bitcode: true,

        export_options: {

          signingStyle: "automatic",

          uploadBitcode: true,

          uploadSymbols: true

        }

      )

      

      upload_to_app_store(

        submit_for_review: false,

        automatic_release: false,

        price_tier: 1

      )

      

      send_feishu_notification(

        "App Store构建上传完成",

        "\*\*版本\*\*:#{lane_context[SharedValues::VERSION_NAME]}\n\*\*构建号\*\*:#{lane_context[SharedValues::BUILD_NUMBER]}"

      )

      

    rescue => ex

      send_feishu_notification("App Store上传失败", "错误信息:#{ex.message}", false)

      raise ex

    end

  end

end

8. 最佳实践与问题排查

8.1 安全规范

  • 敏感信息(密钥、账号)务必存入.env文件,切勿硬编码

  • .env添加到.gitignore,避免提交至代码仓库

  • 使用 fastlane 的match工具管理证书,实现团队共享

8.2 常见问题解决

  1. 安装失败
  • 网络问题:替换 Gem 源为国内镜像(如 Ruby China)
  1. 构建失败
  • 签名问题:检查export_method与证书类型是否匹配

  • Scheme 问题:确保 Xcode 中 Scheme 已勾选 "Shared"

  1. 上传失败
  • 网络问题:配置代理或使用 VPN

  • 权限问题:检查 App Store Connect 账号是否有上传权限

8.3 持续集成扩展

可将 fastlane 脚本集成到 Jenkins、GitHub Actions 等 CI/CD 平台,示例 GitHub Actions 配置(.github/workflows/build.yml):

name: Build and Deploy

on: [push]

jobs:

  build:

    runs-on: macos-latest

    steps:

      \- uses: actions/checkout@v3

      \- name: Set up Ruby

        uses: ruby/setup-ruby@v1

        with:

          ruby-version: '3.2'

          bundler-cache: true

      \- name: Install dependencies

        run: |

          bundle install

          pod install

      \- name: Run fastlane

        env:

          PGYER_API_KEY: \${{ secrets.PGYER_API_KEY }}

          FEISHU_WEBHOOK_URL: \${{ secrets.FEISHU_WEBHOOK_URL }}

        run: bundle exec fastlane pgyer_upload

(注:文档部分内容可能由 AI 生成)