mcpField
L
limrun-xcode

limrun-xcode

github.com/limrun-inc云与 DevOps243.2k 次安装1 天前更新
代码仓库

关于 limrun-xcode

limrun-xcode 是用于在 Limrun 远程 Xcode 环境构建 Apple 项目的技能,面向需要从不同操作系统或容器进行构建和测试的开发者。它通过 lim 同步源码并运行构建,也可选择 Xcode 版本、复用磁盘快照及在模拟器运行 XCTest。

主要功能

  1. 01远程同步源码并构建项目
  2. 02选择或固定 Xcode 版本
  3. 03复用磁盘快照加快后续构建
  4. 04在模拟器运行 XCTest
  5. 05执行远程命令并下载文件

适用场景

  1. 01从非 macOS 环境构建 Apple 项目
  2. 02在 CI 中运行 XCTest 并检查结果
  3. 03为不同构建任务复用工作区快照
  4. 04在远程环境执行项目生成命令

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/limrun-inc/skills --skill limrun-xcode

安装后在 Claude Code 中输入/limrun-xcode确认已加载。

详细介绍

远程 Xcode 构建

在 Limrun 的远程 Xcode 上构建 Apple 项目,支持从任何环境(Linux、 Windows、macOS、VM、容器)进行构建。lim xcode build 会将源代码同步到远程 Xcode 实例,在那里进行构建,并在连接了模拟器时安装并重新启动应用。此工作流在远程实例上构建;本地 Xcode、本地模拟器和本地构建工具都不在其范围内。构建完成后,应用会在 Limrun 模拟器上运行并通过验证。

若要在应用运行后操控它(点按、输入、查看元素树、截图、 录制),请使用 limrun-ios-simulator 技能。对于 Bazel 工作区,请使用 limrun-bazel,而不是此技能。

身份验证和 CLI

如有需要,请安装:npm install --global lim。身份验证方式为 lim login 或 LIM_API_KEY(即使 .env 和 shell 中没有显示,用户的环境中也可能已设置此变量;在询问前请先检查)。CLI 是事实依据: 此技能中的命令均已验证;但如果某个标志报错,或你需要使用此处未列出的标志,请查看 --help,不要猜测:

lim xcode --help
lim xcode build --help
lim xcode run --help

构建

请使用以下命令构建,而不是使用 xcodebuild:

lim xcode build .

此命令会创建或复用已记住的 Xcode 目标,同步当前目录, 并通过 stdout 和 stderr 输出构建日志。

如果项目包含多个 scheme 或使用 workspace 文件,请使用 --scheme 和 --workspace:

lim xcode build . --scheme MyApp --workspace MyApp.xcworkspace

如需指定 Xcode 配置,请使用 --configuration Debug 或 --configuration Release。如果省略此选项,Limrun 会使用 limbuild 根据项目类型设定的默认值:原生 Xcode 构建使用 Debug, React Native / Expo 构建使用 Release。

lim xcode build . --configuration Debug
分离构建和日志

使用 --detach 可在构建被接受后立即返回;webhook 为可选项。 logs 无需 exec ID 即可读取最新构建的日志,包括实例删除后持久保存的日志;添加 --follow 可等待构建完成。

lim xcode build . --detach
lim xcode logs
lim xcode logs --follow
选择 Xcode 版本

沙盒使用其节点的默认 Xcode 构建(目前为 26.4)。集群提供每个主版本的一个正式发布版(GA)Xcode,以及 Apple 发布种子版本期间提供的一个 Beta 版:目前有 26.4 GA、27.0 GA 和 27.1 Beta。可通过以下两种选择器指定版本:

  • 仅指定主版本号(27)时,会绑定该主版本的最新 GA 版,绝不会选择 Beta 版,并会自动跟随 Apple 发布的次要版本更新。适用于 App Store 构建。
  • 指定主版本号和次版本号(27.1)时,会固定到该确切版本。选择 Beta 版时使用这种方式。

为工作区设置一次首选版本后,之后的每次构建、测试、RBE 会话和新沙盒都会沿用该设置;命令行标志则会覆盖该设置,仅对单条命令生效:

lim xcode version list      # Select is the value to type, Channel is ga or beta; * marks the one in use
lim xcode use xcode@27      # prefer the Xcode 27 GA for this workspace; switches the remembered sandbox now
lim xcode build .           # builds with 27
lim xcode version           # "27.0 (27A266a)" shows the sandbox's current Xcode
lim xcode version set 27.1  # pin the 27.1 beta instead
lim xcode build . --xcode-version 26   # one-off override, not remembered
lim xcode version unset     # forget the preference; the sandbox goes back to the node default

使用 lim xcode use xcode@27 node@24 组合选择 Xcode 和 mise 版本。

用于脚本时,lim xcode version list --quiet 会逐行打印一个选择器(26、27、27.1),而 --json 会返回 { installed, bound, preferred }(installed[].channel 的值为 ga 或 beta)。表格会用 * 标记当前使用的 Xcode。lim xcode version set 不会记录节点上不存在的版本(错误信息会列出可用版本),但如果沙盒只是处于忙碌状态,则会保留该版本设置。

如果沙盒使用的 Xcode 与工作区首选版本不同,下一次构建时会提示这一点,并先切换版本。切换会使使用其他版本生成的构建缓存失效(下一次构建会从头开始),且在构建、同步或 lim xcode rbe 堆栈运行期间无法切换。使用持久化磁盘快照(--snapshot-key)时,请为每个 Xcode 版本线使用不同的密钥,例如 myapp-27 和 myapp-27.1:归档按密钥存储,使用不同 Xcode 恢复时会被清除。

主版本号和次版本号固定的版本会一直有效,直到集群将该版本退役;此后,lim xcode build 会报出守护进程的消息,并提示运行 lim xcode version set 27 或 lim xcode version unset。Beta 版转为 GA 版时,同一主版本号和次版本号选择器会改为指向 GA 版(需要进行一次冷构建);仅指定主版本号时,则会跟随该主版本的最新正式发布版,因此节点上的 27.1 成为 GA 版后,会立即切换到 27.1。

Apple 会拒绝从 Beta 版 Xcode 上传的 App Store 内容,因此请将 --upload-to-appstore 与仅指定主版本号的固定版本搭配使用(27,而不是 27.1)。请依据 channel 判断,而不是 betaSeed:Apple 发布的 27.1 种子版本没有种子编号。

--dev-server-url 仅适用于 React Native / Expo 构建中的 --configuration Debug。这是一个安装后启动 URL:limbuild 会验证它是否为可解析的绝对 URL,然后在连接的模拟器上安装应用后,原样打开该 URL。框架专属技能会构造正确的 URL。

lim xcode build . --configuration Debug --dev-server-url '<absolute-url>'

如果应用启动时未使用预期的 URL,请显式打开它,以区分构建/安装问题和 URL 路由问题:

lim ios open-url --id <ios-instance-id> '<absolute-url>'

磁盘快照

在多个 Xcode 实例间复用源文件、依赖项和 DerivedData。

CLI 0.35.1 及更早版本使用 --cache-* 而非 --snapshot-*,并使用 --wait-cache 而非 --wait-snapshot。快照重命名后,旧标志仍保留为别名。

在项目目录中,使用快照键创建实例,执行构建,然后删除实例:

XCODE_ID=$(lim xcode create --snapshot-key myapp-main --quiet)
lim xcode build . --id "$XCODE_ID" --scheme MyApp
lim xcode delete "$XCODE_ID" --wait-snapshot

首次运行时没有缓存;后续运行会恢复已保存的快照。成功构建且之后未进行同步时,实例终止会保存快照,并替换该键下的上一个快照。--wait-snapshot 会等待保存完成并报告结果。在 CI 中,即使构建失败,也要在清理步骤中执行删除操作。

不设置 --snapshot-paths 可保存整个工作区。多次运行时,项目文件夹名称必须保持不变。为每个项目、Xcode 版本和并发 CI 作业使用不同的键。

若要回退到其他分支的快照,请在创建时添加 --snapshot-restore-keys "myapp-pr51,myapp-main"。系统会依次尝试每个条目:先精确匹配,再匹配此前缀相同且最新的键,然后才尝试下一个条目。如果未指定此标志,保存键也会用作恢复键。若要复用快照而不保存,请只传入恢复键。

创建时配置快照。恢复键和路径之后都不能更改。 对于现有实例,只有在已启用快照的情况下,build --snapshot-key 才能绑定尚未分配的保存键;它不会恢复快照或启用快照。

请参阅磁盘快照指南,了解跳过保存、冷启动构建和 SDK 用法。

私有依赖凭据

使用 --additional-file 复制现有凭据文件;sync 也支持此参数:

lim xcode build . \
  --additional-file "$HOME/.npmrc=~/.npmrc" \
  --additional-file "$HOME/.netrc=~/.netrc"

远程路径中的 ~/ 指向沙盒主目录;其他目标路径均相对于工作区。后续同步时也要重复传入这些标志,以保留文件。对于配置引用的环境变量,请传入 --env。

开发者工具版本

同步后,lim xcode use 会在沙盒中选择工具并安装缺失的版本。 对于已同步项目所选用的工具,请运行 lim xcode tools install(详情)。使用主版本号;对于 Ruby、Flutter 和 Mint 等 1.0 之前的工具,使用主版本号.次版本号。

lim xcode tools
# Node includes npm/npx, Ruby includes gem, Flutter includes Dart, CocoaPods includes cocoapods-patch.
lim xcode use node@24 pnpm@10 yarn@4 bun@1 [email protected] bundler@4 cocoapods@1 \
  cmake@3 java@jetbrains-21 corretto@21 [email protected] [email protected] \
  xcodegen@2 xcbeautify@3 zsign@1
lim xcode tools install
lim xcode use --cwd apps/mobile node@24
lim xcode tools install --cwd apps/mobile
lim xcode run -- mise use --pin [email protected]

运行项目命令

如果仓库需要在 xcodebuild 之前或之外运行远程 macOS 命令,请使用 lim xcode run [relative-cwd] -- <command>。CLI 会先同步当前目录。工作目录相对于同步后的根目录,默认为 .:

lim xcode run -- make api
lim xcode run apps/api -- make generate

在分隔符之前传入环境变量。仅当同一实例已包含所需源文件状态时,才使用 --no-sync:

lim xcode run --env API_ENV=development -- npm run generate
lim xcode run --no-sync -- make api

沙盒包含 Node、Ruby、CMake、Mint、mise 和 Homebrew。使用 mise、Mint 或 Homebrew 安装的工具会保留在实例的沙盒主目录中,之后在该实例上运行的命令仍可使用这些工具:

lim xcode run -- 'mise trust && mise install'
lim xcode run -- 'mint install apollographql/apollo-ios-cli'
lim xcode run -- brew install tree

命令为一次性运行,且不支持交互。没有 TTY 或 stdin 通道。

下载沙盒文件

使用 lim xcode pull-file <remote-path> [destination] --id <instance-ID>。 路径可以是绝对路径,也可以相对于已同步项目的根目录。 切勿使用构建或运行日志传输文件,包括文本、二进制或 base64 内容。 请等待写入文件的命令完成。先归档目录,再下载文件,然后删除实例。

生成 Xcode 项目(XcodeGen)

如果仓库中有 project.yml,且 .xcodeproj 被 git 忽略,请勿在本地运行 xcodegen,也不要将缺少项目视为错误。远程沙盒会在构建前根据 project.yml 生成项目:

lim xcode build .

配置位于仓库根目录或下一层目录中(例如 ios/),无需传入标志。每次构建都会重新生成项目,因此只需重新构建,project.yml 的更改就会生效。已提交或强制同步的 .xcodeproj 始终优先:只有同步时未提供项目,沙盒才会生成项目。

如果仓库的代码生成步骤会生成构建所需、但被 git 忽略的输入(例如生成的本地 Swift 包或由配置派生的源文件),请先在本地运行该步骤,再使用 --include 强制同步其输出:

make generate   # or whatever the repo's codegen step is
lim xcode build . --include '^ios/GeneratedKit/'

--include 接受正则表达式,类似 --ignore,而不是 gitignore 语法。要访问整个目录都被忽略的目录中的文件,模式还必须匹配目录路径本身,如上所示。

在模拟器上运行

lim xcode build 会执行构建并安装。只有在用户需要查看或操作应用时,才连接模拟器。检查 / 连接:

lim xcode get             # is a simulator already attached?
lim ios create --attach   # attach one (installs the last build immediately)

如果没有浏览器可供用户查看,请添加 --no-open;它会跳过在本地打开流 URL,但仍会输出该 URL,方便分享。

如果连接输出中包含已签名的流 URL,请将其作为 Markdown 链接分享给用户,例如 [实时模拟器](<signed-stream-url>)。

连接模拟器后,每次 lim xcode build 成功都会自动重新安装并重新启动应用,无需单独安装。要点按、输入、读取元素树、截屏或录制,请切换到 limrun-ios-simulator。

运行测试(XCTest)

lim xcode test 会在沙盒上构建方案中的测试目标,在已连接的模拟器上运行测试(包括单元测试和 UI 测试目标),并为每个测试用例输出一行结果。只要有测试失败,exec 就会以非零状态退出,因此可用作 CI 门禁。

lim xcode test .
lim xcode test ./MyProject --scheme MyApp

它会像 lim xcode build --ios 一样自动获取由模拟器支持的目标,并在重复运行时复用实例,因此迭代很快。方案必须配置测试操作(当项目包含测试目标时,Xcode 中的共享方案会配置此操作)。--xcode-version 27 会使用该主版本的 GA 版本构建测试(27.1 选择 beta 版);模拟器仍使用设备池的默认运行时,因此会发出警告并继续运行(可能出现依赖运行时的故障)。

使用 xcodebuild 的标识符格式 Target[/Class[/method]] 选择部分测试;多个条目可重复传入此标志。以下两个标志不能同时使用:

lim xcode test . --only-testing MyAppTests/LoginTests/testValidLogin
lim xcode test . --skip-testing MyAppUITests

只写目标名称即可选择或跳过整个目标。--only-testing 条目若指定了构建未生成的目标,运行将失败,而不会静默地运行所有测试。

如需供机器处理,--json 会以 NDJSON 格式输出原始的每个用例事件,并以 {"exitCode": N} 记录结束:

lim xcode test . --json > results.ndjson

--build-only 会编译测试目标,但不获取模拟器;生成的产物会保留在沙盒中,供之后运行。

如果 UI 测试在某个已连续运行多套测试的实例上首次交互时就失败,请优先在下次运行时使用 --inactivity-timeout 30m 获取全新实例。

已签名的设备构建(IPA)

如果用户拥有 App Store Connect 团队 API 密钥,优先使用 Apple 云签名。 Apple 会创建或复用云托管证书和描述文件, 因此用户无需提供 p12 或 .mobileprovision。密钥 ID、 签发者 ID 和 .p8 文件由用户在自己的机器上配置为 标志或环境变量;切勿在对话中询问这些值:

lim xcode build . --sdk iphoneos --configuration Release \
  --signing-method release-testing --team-id "$APPLE_TEAM_ID" \
  --asc-key-id "$ASC_KEY_ID" --asc-issuer-id "$ASC_ISSUER_ID" \
  --asc-key AuthKey.p8 \
  --upload myapp.ipa

签名方式:

  • debugging:为已注册的开发设备生成开发签名 IPA。
  • release-testing:为已注册的测试设备生成分发签名 IPA。
  • app-store-connect:为 App Store Connect 生成分发签名 IPA。

云签名需要设备 SDK(--sdk iphoneos 或 --sdk watchos)、带有签发者 ID 的 团队 API 密钥,以及与该密钥的 Apple Developer 团队匹配的 --team-id。对于分发方式, API 密钥必须是 Admin 密钥,或启用 Access to cloud-managed distribution certificates 权限。Cloud signing permission error 表示缺少该权限。No Account for Team 表示团队 ID 与 API 密钥不匹配。 Failed Registering Bundle Identifier 表示 Bundle ID 属于其他团队,无法自动注册。

云签名只会从 --entitlements 获取权利;绝不会从项目的 .entitlements 文件获取:归档文件未签名,而导出过程只会保留现有代码签名中的权利。任何使用 功能(HealthKit、CloudKit、应用组、推送)的应用都必须传入该标志, 否则该功能会在 IPA 中被静默移除。单独的路径指定应用;<bundleId>=<path> 指定嵌入式 Bundle(小组件、Watch 应用); 每个 Bundle 都要分别重复指定:

lim xcode build . --sdk iphoneos --configuration Release \
  --signing-method release-testing --team-id VMBY3VYW4U \
  --asc-key-id 2X9R4HXF34 --asc-issuer-id "$ASC_ISSUER_ID" \
  --asc-key AuthKey.p8 \
  --entitlements ./MyApp/MyApp.entitlements \
  --entitlements com.example.myapp.widgets=./Widgets/Widgets.entitlements \
  --upload myapp.ipa

plist 值必须完全展开(不能使用 $(AppIdentifierPrefix);请写入具体前缀), 必须省略由导出管理的键(application-identifier、 com.apple.developer.team-identifier、get-task-allow、 beta-reports-active),并且每项功能都必须在开发者门户的 App ID 上启用,否则导出会失败并指出该功能。

如果用户已有 p12 和描述文件,仍可使用手动签名:

lim xcode build . --sdk iphoneos --configuration Release \
  --certificate-p12 dist.p12 --certificate-password "$P12_PASSWORD" \
  --provisioning-profile app.mobileprovision \
  --upload myapp.ipa

上传输出中包含已签名 IPA 的下载 URL。构建状态为 SUCCEEDED 表示签名已在服务器上通过 Apple 验证,因此除非用户提出要求,否则不要自行 重新验证 IPA。签名无效时,构建会明确失败,而不会生成损坏的构件。

如果应用嵌入了扩展(WidgetKit 小组件、共享表单、意图)或 Watch 应用,App Store 签名需要每个 Bundle ID 对应一个描述文件,并且这些描述文件都必须由同一分发证书签发。每个 Bundle 都要重复指定 --provisioning-profile; 系统会根据描述文件内的 application-identifier 将其与对应 Bundle 匹配,因此顺序无关:

lim xcode build . --sdk iphoneos --configuration Release \
  --certificate-p12 dist.p12 --certificate-password "$P12_PASSWORD" \
  --provisioning-profile app.mobileprovision \
  --provisioning-profile widgets.mobileprovision \
  --upload myapp.ipa

使用多个描述文件时,每个描述文件都必须包含明确的(非通配符)Bundle ID。signing preflight failed: no provisioning profile covers ... 错误会指出缺少描述文件的嵌入式 Bundle;请向用户索要 Bundle ID 完全匹配的描述文件。

请使用包含完整 CA 链的 p12,而不只是叶证书。如有需要,可重新导出并包含证书链:

openssl pkcs12 -export -inkey dist.key -in dist.pem -certfile wwdr.pem -out dist-chain.p12

构建输出中需要识别的失败字符串:

  • Unknown issuer hash:p12 缺少 CA 链;请按上述方法重新导出并包含证书链。
  • code signature verification failed:平台的签名后检查拒绝了该构件。这不是用户代码的问题;请重试,如果问题持续存在则报告。
  • p12 密码错误:--certificate-password 与文件不匹配;用户应在自己的机器上更正该值。

上传到 App Store Connect

要将已签名的 IPA 上传到 App Store Connect,以供 TestFlight 或 App Store 分发,请在已签名的设备构建中传入 --upload-to-appstore 和 App Store Connect API 密钥 标志:

lim xcode build . --sdk iphoneos --configuration Release \
  --certificate-p12 dist.p12 --certificate-password "$P12_PASSWORD" \
  --provisioning-profile app.mobileprovision \
  --upload-to-appstore --asc-key-id "$ASC_KEY_ID" --asc-issuer-id "$ASC_ISSUER_ID" \
  --asc-key AuthKey.p8

云端签名可以使用同一 API 密钥进行签名和上传:

lim xcode build . --sdk iphoneos --configuration Release \
  --signing-method app-store-connect --team-id "$APPLE_TEAM_ID" \
  --asc-key-id "$ASC_KEY_ID" --asc-issuer-id "$ASC_ISSUER_ID" \
  --asc-key AuthKey.p8 \
  --upload-to-appstore --auto-build-number

--upload-to-appstore 需要使用云端签名或手动签名标志,以及 --asc-key-id 和 --asc-key。如果用户还希望将 IPA 存入 Asset Storage,请与 --upload <asset-name> 一起使用。

设备 IPA 会包含应用的符号文件(Payload/ 旁的 Symbols/),因此 App Store Connect 无需单独上传 dSYM,即可对崩溃报告进行符号化处理。这要求构建生成 dSYM:默认情况下,--configuration Release 会生成;Debug 不会,因此 IPA 将不包含符号文件。

用户在自己的计算机上通过标志或环境变量提供这些信息,CLI 会在本地读取;用户不会将其粘贴到对话中。这三项信息均位于 App Store Connect 的 Users and Access 页面中,具体在 Integrations 标签页下的 App Store Connect API 区域:

  • --asc-key-id:API 密钥旁的 Key ID。如果用户没有密钥,请引导其使用 Developer 角色创建 Team Keys:这是能够上传构建的最低权限角色。创建团队密钥需要 Admin 账户。
  • --asc-issuer-id:Integrations 页面顶部的 Issuer ID(团队级信息,不针对单个密钥)。云端签名需要团队密钥和此标志。手动签名并上传时,如果使用个人 API 密钥,则省略此项。
  • --asc-key:下载的 .p8 文件路径。Apple 不会保留副本,离开页面后下载链接便会失效;如果用户丢失了文件,必须生成新密钥。切勿提交 .p8 文件或将其内容粘贴到文件中;请传入文件系统路径。

默认情况下,构建会在上传完成后立即返回,将 Apple 的处理结果留给 App Store Connect(处理通常需要很多分钟)。传入 --asc-wait-timeout <seconds>(最长 1800)即可等待结果后再返回。请从最后几行读取结果:

  • App Store Connect: upload accepted.:完成;Apple 处理完毕后,构建会显示在 TestFlight 中。
  • App Store Connect: uploaded, still processing on Apple's side (upload <id>).:退出代码为 0,上传已成功;Apple 仍在处理中。请勿重试此构建。
  • App Store Connect upload failed; the build and signing succeeded.:退出代码为 1,日志前面会显示 Apple 的错误文本。仅交付失败。

需要识别的失败信息:

  • Apple 提示 bundle 版本已被使用:递增 CFBundleVersion(Expo:在 app.json 中设置 expo.ios.buildNumber)并重新构建。
  • HTTP 401:Key ID、Issuer ID 与 .p8 不匹配,或密钥已被撤销。
  • HTTP 403:密钥的角色无权上传构建;需要 Developer 角色或更高权限。
  • no App Store Connect app with bundle id:应用记录不存在;用户必须在 App Store Connect 中手动创建(API 无法创建)。
  • 构建之后在 TestFlight 中卡在 "Missing Compliance":应用在构建时未回答出口合规问题。在 Info.plist 中将 ITSAppUsesNonExemptEncryption 设为 NO(Expo:在 app.json 中设置 expo.ios.config.usesNonExemptEncryption: false)并重新构建。

如需自动向测试人员交付,应用的内部 TestFlight 群组必须启用自动分发(仅创建时可设置),并且必须设置上述合规密钥;这样上传后便无需任何后续操作。

预览构建

对于 Pull Request 的可重复预览,建议使用打包好的 iOS 预览操作。 它会构建并上传应用、更新 PR 预览评论,并清理构建器;输入参数和工作流示例请参阅仓库。

仅当用户要求预览构建或你要创建 PR 时,才创建可复用的预览资源。构建并上传:

ASSET_NAME="<bundle id / pr number / or any session identifier>.zip"
lim xcode build . --upload ${ASSET_NAME}
# Debug preview build:
lim xcode build . --configuration Debug --upload ${ASSET_NAME}

构建上传的默认 TTL 为 14 天:每次上传都会将资源的过期时间延后至上传时间起 14 天。传入 Go 时长(例如 720h;1d 无效)以更改此设置,使用 --upload-ttl。

然后构造预览链接,并在最后一条消息中附上该链接(如果你要创建 PR,也要在 PR 中附上):

https://console.limrun.com/stream?asset=${ASSET_NAME}&platform=ios

注意事项

  • 构建错误也是工作的一部分。 如果构建失败,请阅读错误输出、修复代码并重新构建,然后再汇报。
  • 项目的 mise 文件安装了构建过程中不会用到的工具。 在沙盒中首次构建或运行时,会对同步的 mise 文件中每个 [tools] 条目运行 mise install,因此,包含大量数据库和云 CLI 的 monorepo 根目录 mise.toml 会拖慢构建,甚至导致失败。项目文件可用时,请继续使用它。如果不可用,请在同一目录中添加 mise.limrun.toml,仅列出构建所需的工具(例如 node 和 pnpm);在该目录中,Limrun 会读取此文件,而不是其他 mise 文件。
  • 内嵌的 Xcode 沙盒已移除。 TypeScript SDK(0.54.0+)和 lim(0.35.0+)不再在 iOS 实例中创建 Xcode 沙盒。升级后可能出现以下症状:调用 iosInstances.create 时提示 'sandbox' does not exist in type 'Spec',读取 status.sandbox.xcode.url 的代码提示 Property 'sandbox' does not exist on type 'Status',或者 lim xcode 命令提示 Expected an Xcode instance (sandbox_...), got ios_...。请单独创建 Xcode 沙盒并附加模拟器:使用 lim ios create --xcode,或为现有模拟器运行 lim xcode create --attach --simulator-id <ios-instance-id>;在 SDK 中,对客户端调用 xcodeInstances.create,然后调用 attachNewSimulator() 或 attachSimulator(iosInstance)。lim xcode 命令传入 sandbox_ ID,lim ios 命令传入 ios_ ID。详情: https://docs.limrun.com/docs/ios/build-with-xcode#moving-off-the-embedded-xcode-sandbox
  • lim ios 命令的实例 ID。 这些命令会根据当前工作目录所属的 git 工作树解析当前实例,如果未提供实例 ID 且没有最近使用过的 iOS 实例,可能会失败并提示 No instance ID provided and no recent ios instance found。使用 lim xcode get 获取 ID 并传入 --id <ios-instance-id>;完整操作步骤见 limrun-ios-simulator 的“Targeting the right instance”部分。
  • 查找 Bundle ID。 如果不知道 Bundle ID,请检查 Xcode 项目文件,或在构建成功后运行 lim ios list-apps。
  • 认证错误出现在需要认证的命令上,表示会话已过期或 LIM_API_KEY 有误;在用户的机器上运行 lim login 可续期会话。
  • 构建设置会覆盖 Limrun 的默认值。 --build-setting KEY=VALUE 接受任意环境变量格式的键,并替换同名的托管值。设备构建已使用标准架构(内嵌的 watch app 保留 arm64_32),并禁用覆盖率检测,因此上传 App Store 无需额外设置。
  • 构建成功后未找到构建产物。 服务端会自行解析已构建的 .app,即使 scheme 名称与产品名称不同也一样(例如 scheme“我的 App 开发版”构建出 MyApp-dev.app)。如果上传仍提示 built artifact not found,请显式传入完整的 Bundle 文件名,使用 --artifact-name MyApp-dev.app(包含 .app 扩展名);随后服务端会从构建产物中原样获取该名称。
  • 同步文件应保持精简。 单个约 2MB 或更大的文件可能会在构建开始前导致客户端同步出现 ENOMEM;请压缩大型资源。
  • 符合条件的符号链接会同步。 目标为绝对路径的符号链接会被跳过并发出警告;如果构建需要它,请将其重新创建为相对路径目标。指向同步文件夹之外的相对链接会导致同步失败;请使用 --ignore 忽略它,或从包含目标文件的仓库根目录进行同步。
  • 签名失败会明确报错。 Unknown issuer hash 表示 p12 缺少 CA 链,请连同证书链重新导出;code signature verification failed 表示平台的签名后检查拒绝了构建产物,这不是代码问题,请重试或报告此问题。

评论

支持 Markdown