从安装到使用认识fastlane

fastlane官方文档

docs.fastlane.tools/getting-sta...

fastlane的安装fastlane init在 Fastlane 中使用某些操作(如上传到 App Store Connect 或 TestFlight)时,确实需要提供 Apple ID 用户名(Apple ID Username) ,但 Fastlane 提供了多种安全的管理方式,避免硬编码敏感信息

比如以下 Fastlane 命令通常需要 Apple ID 认证:

  • sigh,签名,使用Apple ID 密码

  • deliver(上传 App Store)

    单独运行deliver时使用Apple ID

    密码gym之后运行deliver:

    则使用 altool 命令行工具

    需要应用专用密码

    不支持交互式二次验证

  • match(管理证书和描述文件),支持Apple ID 密码,和二次验证

ruby 复制代码
# deliver/lib/deliver/runner.rb 第 271-302 行
def transporter_for_selected_team
  # 创建 ItunesTransporter 实例
  generic_transporter = FastlaneCore::ItunesTransporter.new(
    options[:username], 
    nil, 
    false, 
    options[:itc_provider], 
    altool_compatible_command: true,  # 关键参数!
    api_key: api_key
  )
end

Would you like fastlane to manage your app's metadata? 什么意思你是否希望让 Fastlane 自动管理你应用的元数据(App Store 或 Google Play 上的信息)?

什么是"App Metadata"(应用元数据)?

指的是应用商店页面上展示的信息,比如:

  • 📱 应用名称(App Name)
  • 📝 描述(Description)
  • 🖼️ 截图和预览视频(Screenshots)
  • 🔍 关键词(Keywords)
  • 🏷️ 分类和子标题(Category/Subtitle)
  • 🌍 多语言支持(不同语言的翻译)

接下来编辑fastfile

ruby 复制代码
default_platform(:ios) # 声明默认平台是 iOS

platform :ios do # iOS 平台的专属配置区块
  desc "Push a new release build to the App Store" # 任务描述(命令行中会显示)
  lane :release do # 定义一个叫 "release" 的任务 可以通过 fastlane release 命令触发。
    increment_build_number(xcodeproj: "student-printer.xcodeproj") #自动增加 Xcode 项目中的 Build Number(CFBundleVersion)。
    #参数:xcodeproj:指定 Xcode 项目文件路径(这里是 student-printer.xcodeproj)。
    
    build_app(workspace: "student-printer.xcworkspace", scheme: "student-printer") #编译 iOS 应用,生成 .ipa 文件。
    #等效手动操作:在 Xcode 中选择 Product > Archive。

    upload_to_app_store #将编译好的应用上传到 App Store Connect,准备提交审核。会自动处理代码签名、上传元数据(如果配置了)。
  end
end

1. build_app 是一个 Lane 吗?

不是build_app 是 Fastlane 提供的一个内置 Action (动作),而不是 Lane。它的作用是封装了 Xcode 的编译和打包流程(底层调用 xcodebuild)。

  • Lane :是你自己定义的"任务"(比如 lane :release),由多个 Action 组成。
  • Action :是 Fastlane 提供的"最小操作单元"(如 build_appincrement_build_number)。

因为 Fastlane 的 核心 Actions 是全局可用的,无需额外定义。类似的内置 Action 还有:

  • upload_to_app_store
  • increment_build_number
  • match

它们像"积木"一样,可以直接在你的 Lane 中组合使用。

我们也可以自定义action,用于封装重复操作、集成第三方工具或扩展 Fastlane 的功能。

(1) 快速定义(直接在 Fastfile 中)

适用于简单的、项目专用的 Action:

ruby 复制代码
# fastlane/actions/custom_action.rb
module Fastlane
  module Actions
    class CustomActionAction < Action
      def self.run(params)
        # 你的自定义逻辑
        UI.message("执行自定义 action")

        # 示例:获取参数
        app_name = params[:app_name]
        version = params[:version]

        # 执行具体操作
        UI.success("应用: #{app_name}, 版本: #{version}")

        # 返回结果
        return {
          status: "success",
          message: "自定义 action 执行完成"
        }
      end

      def self.description
        "自定义 action 描述"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(
            key: :app_name,
            env_name: "CUSTOM_ACTION_APP_NAME",
            description: "应用名称",
            optional: false,
            type: String
          ),
          FastlaneCore::ConfigItem.new(
            key: :version,
            env_name: "CUSTOM_ACTION_VERSION", 
            description: "应用版本",
            optional: true,
            type: String,
            default_value: "1.0.0"
          )
        ]
      end

      def self.output
        [
          ['status', '执行状态'],
          ['message', '执行消息']
        ]
      end

      def self.authors
        ["你的名字"]
      end

      def self.is_supported?(platform)
        [:ios, :android].include?(platform)
      end
    end
  end
end

缺点 :只能在当前项目的 Fastfile 中使用

(2) 创建全局可复用的 Action

适用于跨项目共享的复杂操作,需放在 fastlane/actions 目录下。

path类似:/opt/homebrew/Cellar/fastlane/2.228.0/libexec/gems/fastlane-2.228.0/fastlane/lib/fastlane/actions

如何查看Fastlane 的全局安装目录

复制代码
sudo gem install fastlane

brew install fastlane

目前我试过之后发现,不论使用上述哪种方式安装,fastlane的核心文件都在opt/homebrew/celler中

自定义lane

fastlane/Fastfile 文件中,使用 lane 关键字定义

ruby 复制代码
lane :lane_name do |options|  # 执行的操作(Actions)end
  • :lane_name :Lane 的名称(符号类型,建议用下划线命名,如 :build:release)。
  • options:调用时传入的参数(可选)。

参数的使用方式如下:

ruby 复制代码
lane :build do |options|
  app_name = options[:app_name]
  UI.message("Building app: #{app_name}")
end

调用时

复制代码
fastlane build app_name:MyApp

或通过 Ruby 代码调用:

php 复制代码
build(app_name: "MyApp")  # 在其他 Lane 中调用

fastlane的源码稍微看一下

fast_file.rb 是 Fastlane 的核心源码文件之一,主要负责解析和执行用户定义的 Fastfile(自动化流程的入口文件)。以下是它的核心作用和工作原理:


1. 核心功能

  • 解析 Fastfile
    将用户编写的 Ruby DSL(领域特定语言)转换为可执行的代码块(lane)。
  • 管理 Lane 定义
    存储所有用户定义的 lane(任务)及其参数,提供调用入口。
  • 处理上下文
    Fastfile 中的代码提供执行环境(如 before_allafter_all 回调)。

before_all

在 Fastlane 中, before_all 是一个特殊的 Hook(钩子) ,用于在所有 Lane 执行之前自动运行指定的代码块。它通常用来执行一些全局的初始化操作(如检查环境变量、登录服务、清理临时文件等)。

Hook 是框架提供的 生命周期回调,允许你在特定阶段(如 Lane 执行前/后)插入自定义逻辑。

  • 自动触发:由 Fastlane 内部机制调用,无需手动执行。

  • 无直接输入/输出:不像 Action 或 Lane 能通过参数或返回值交互。

怎么理解这个hook?

before_all既不是一个 Action,也不是一个 Lane,这么说是因为从解析上,确实这三个是不同的解析方式,但是总归都是对方法的调用,所以称之为hook也行,hook主要是为了表明它的用意,它像是你认识的callback 或者closure,它甚至不需要名字,你知道它是干嘛的就完事儿了

总之fastlane会存储你自定义的lane或者你的callback,然后在合适的时机调用执行这些任务。

关于fastlane中的参数

1. Lane 中声明与使用

arduino 复制代码
lane :build_single do |options|  #多个参数的情况这个也适用  app_name = options[:app_name]  # 获取某个参数  UI.message("Building app: #{app_name}")end

调用方式

复制代码
fastlane build_single app_name:MyApp

fastlane安装插件

复制代码
fastlane add_plugin pgyer

关于项目中的Schemes

在 Xcode 的 Manage Schemes(管理方案) 界面中,Shared(共享) 是一个关键选项,它决定了 Scheme 是否被纳入版本控制并与团队成员共享

  • 勾选 Shared后, Scheme 会被保存到 .xcodeproj文件(点击显示包内容)的**xcshareddata/xcschemes/** 目录下的 .xcscheme 文件中
  • 该文件可以提交到 Git/SVN,团队所有成员同步获取相同的 Scheme 配置
  • 适合统一构建、测试、运行等流程。

Jenkins + Fastlane 做持续集成,如果没有这个文件,Jenkins 使用 fastlane 编译项目时会提示 No schemes found in Xcode project or workspace ,所以最好先加上。

Fastlane:通过 increment_version_numberincrement_build_number 自动更新version 和build

match和sigh的区别

在 Fastlane 工具链中,match 是一个专门用于 自动化管理 iOS/macOS 开发证书和描述文件(Provisioning Profiles) 的 Action

它通过 Git 仓库集中存储加密的证书和描述文件,解决团队协作中的签名一致性问题。

  • 🔐 自动生成/更新 开发证书描述文件
  • 🔑 将证书加密后存储到 私有 Git 仓库(或 Google Cloud/Amazon S3)。
  • 👥 团队成员通过密钥共享解密,保证一致性。
工具 管理对象 存储方式 适用场景
match 证书 + 描述文件 加密的 Git 仓库 团队协作、CI/CD
sigh 仅描述文件 本地文件 个人项目
cert 仅开发证书 本地文件 需单独管理证书时

开发证书和描述文件都是什么,他们之间什么关系

开发证书

是为了证明开发者的身份,后缀名.cer ,它的作用:允许开发者将应用安装到真机调试。用于签名(Signing)应用代码,确保来源可信。

描述文件

一个 .mobileprovision 文件,包含以下信息:

  • 哪些设备可以安装(通过 UDID 白名单)。
  • 哪个应用(Bundle ID)能用。
  • 哪个证书有权限签名。
  • 哪些能力(Capabilities)可用(如推送、iCloud)。
  • 没有匹配的描述文件,即使有证书也无法成功签名。

证书:证明「谁」有权限签名(开发者身份)。

描述文件:规定「哪个应用」能用「哪些设备」和「哪些功能」。

如何生成这两个文件呢

证书

diff 复制代码
开发者通过 Xcode 或 Apple Developer 网站申请。

Apple 用私钥签名后颁发证书。

证书下载到本地后,自动存入钥匙串(Keychain)。

- Development Certificate:用于开发阶段真机调试。
- Distribution Certificate:用于发布到 TestFlight 或 App Store。

描述文件

rust 复制代码
1、登录 Apple Developer 账户 -> 导航到 Certificates, Identifiers & Profiles

2、Xcode -> Settings -> accounts->选中appleid

Fastlane 底层调用 xcodebuild,而 Xcode 构建时必须:

  1. 找到匹配的签名证书(在钥匙串中)。
  2. 加载正确的描述文件(需在 Xcode 项目或打包参数中指定)。

sigh的前提

  • 需提前手动或通过 cert 生成证书(否则描述文件无效)。
  • 使用 Appfile 或环境变量中的 apple_idteam_id 自动登录开发者后台
  • 从当前 Xcode 项目的 GeneralBuild Settings 中读取 PRODUCT_BUNDLE_IDENTIFIER
  • 如果未指定 adhoc/development,默认生成 App Store 类型的描述文件(用于提交商店)。
  • Appfile 或钥匙串读取 Apple ID。
  • team_id:从 Xcode 项目设置或开发者账户自动检测。
  • 若证书过期或被吊销,需手动重新生成证书和描述文件

gym是什么

在 Fastlane 工具链中,gym 是一个专门用于 自动化构建和打包 iOS/macOS 应用 的核心 Action(现已被整合到 build_app 中,两者功能相同)

它的作用是将你的 Xcode 项目编译成 .ipa(iOS)或 .pkg(macOS)文件,简化了手动通过 Xcode 打包的繁琐流程

build_appgym 的别名,功能完全相同(Fastlane 推荐使用 build_app

deliver:自动上传 App 到 App Store 的「快递员」

想象你开发了一个 App,要把它传到苹果商店(App Store)。手动操作需要:

  1. 登录苹果后台,填一堆信息(版本号、截图、描述等)。
  2. 打包好的 .ipa 文件手动拖到网页上传。
  3. 等半天还可能传失败...

deliver 就是帮你全自动搞定这些事的工具!

它能帮你做什么?

  • 一键上传 IPA 文件, 不用手动点网页,命令行直接传。
  • 自动填 App 信息, 版本更新日志、关键词、截图等,全用配置文件管理。提前把信息写在 fastlane/metadata 文件夹里:
bash 复制代码
/metadata/
  ├── release_notes.txt  (写更新日志)
  ├── screenshots/       (放截图)
  └── description.txt    (App 介绍)
  • 跳过重复操作, 比如每次更新只改版本号,其他信息自动复用。

运行命令:

复制代码
fastlane deliver

deliver基础参数

运行fastlane action deliver命令可以查看

参数名 作用 示例值 说明
ipa 指定要上传的 IPA 文件路径 ipa: "./build/MyApp.ipa" 如果不传,会自动找最新打包的 IPA。
submit_for_review 是否直接提交审核 submit_for_review: true true=传完直接提交审核;false=只上传不提交(默认 false)。
force 跳过所有确认提示 force: true 适合自动化脚本,不会问你"确定吗?"。它的作用就一句话:所有需要你手动按"回车"或"输入 Y/N"的地方,全部自动选"是"
skip_screenshots 跳过截图上传 skip_screenshots: true 如果只想更新文字信息,不传截图时用。
skip_metadata 跳过文字信息更新 skip_metadata: true 如果只想传 IPA,不改描述、关键词等文字信息时用。
precheck_include_in_app_purchases 检查内购项目 false 如果你的 App 有内购,设为 false 避免自动检查失败。

deliver时都有哪些确认提示?

  1. "检测到新截图,要覆盖吗?"
    (如果你之前传过截图)
  2. "App 信息有改动,确定上传吗?"
    (比如改了版本描述)
  3. "真的要提交审核吗?"
    (如果 submit_for_review: true

gym 中提供的scheme没有找到时,gym会怎么处理呢?

自动探测 Scheme** **

  1. 查找主工程的所有 Scheme
    • 扫描 .xcodeproj.xcworkspace 中定义的 Scheme。
  2. 选择第一个非测试 Scheme
    • 通常优先选择与工程同名的 Scheme(如 YourApp.xcodeproj 对应 YourApp Scheme)。

所以这里虽然报错但还是能继续进行的

bundler 和bundle

  • bundler 是 Ruby 的「管家工具」,专门管理项目的依赖(比如 Fastlane、CocoaPods 等 Gem 包)。
  • bundle 是调用 bundler 工具的快捷命令(就像输入 ls 实际调用的是 /bin/ls)。

关系类比:
bundler = 奶茶店老板
bundle = 你对老板喊的"来杯奶茶!"

复制代码
如上提示的是bundler版本和ruby rubygems版本不一致

Gemfile 是 Fastlane 的「软件包说明书」,用来告诉电脑:

  • 安装哪个版本的 Fastlane
  • 需要哪些额外的插件和工具

就像你买乐高时附带的《零件清单》,Gemfile 就是 Fastlane 的零件清单。

想象你要做一杯奶茶:

  • Fastlane = 奶茶机(主设备)
  • Gemfile = 奶茶配方单(写明需要红茶、牛奶、珍珠等)
  • bundler (运行 bundle 的命令)= 你的助手,负责按配方单准备材料

如果没有配方单(Gemfile),助手(bundler)可能拿错材料(版本不对),奶茶机(Fastlane)就罢工了!

错误1

fastlane ruby -v /opt/homebrew/Cellar/ruby/3.4.4/lib/ruby/3.4.0/rubygems/specification.rb:1421:in 'block in Gem::Specification#activate_dependencies': Could not find 'nkf' (>= 0) among 181 total gem(s) (Gem::MissingSpecError)

nkf 是 Ruby 的网络汉字转换库(Network Kanji Filter),某些 Ruby gems(如 fastlane)依赖它。这个错误表明:

  • 你的 Ruby 环境缺少 nkf 这个基础 gem
  • 可能是 Ruby 安装不完整或 gem 环境损坏

注意这里安装nkf使用的gem 和fastlane对应的ruby要对应上,得是对应ruby的"应用商店"

错误2

如果设置了2次验证,altool需要使用app专用密码

  • 访问 appleid.apple.com
  • 登录你的 Apple ID
  • 进入"安全性" → "App 专用密码"
  • 点击"生成密码"
  • 复制生成的密码

可能会用到以下命令:

csharp 复制代码
fastlane fastlane-credentials remove --username "your appleid"fastlane fastlane-credentials add --username "your appleid"

我后期发现我这边遇到的问题其实是由于sigh和deliver用到的密码不同,一个appleid的密码一个由于有二次验证所以要用app专用密码在fastfile中添加环境变量

ENV['FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD']= "你的app专用密钥"就可以解决问题

错误三

precheck 会在上传二进制文件(IPA)之后提交审核之前由fastlane默认执 行(如果设置了 submit_for_review: true)。precheck 的失败 不会阻止 IPA 上传,只会警告你可能导致审核被拒的问题。

最后,Fastlane为什么可以工作呢?竟然可以自动上传ipa?

Fastlane 的能力来源于:

  1. 苹果提供的底层工具 (如 xcodebuild)。
  2. 对未公开 API 的逆向工程 (如 spaceship)。
  3. 开发者社区的持续维护(适应苹果的变更)。
  4. 苹果对自动化需求的默许(尤其在企业场景)。

可以说这是一种"灰色地带"的创新,它也正是开发者工具生态的活力所在。尽管存在风险(如苹果可能突然封禁某些 API),但 Fastlane 已成为 iOS 开发的事实标准,体现了开发者的智慧和对效率的追求

写文不易,关注我,还有更多干货分享

相关推荐
crasowas9 个月前
iOS问题记录 - 503 Service Temporarily Unavailable
ios·fastlane
de得得de10 个月前
鸿蒙 Fastlane 流水线搭建
前端·harmonyos·fastlane
一只公羊2 年前
PCIe的引脚和数据位宽和并行数据串行化【SERDES】
fastlane