1. 项目概述t3code 是什么它解决的不是“工具问题”而是开发流程断点t3code 这个名字乍看像某个新出的 CLI 工具缩写但结合当前全网搜索热度中反复出现的t3code、CLI、Electron、web app、iOS这组关键词再叠加大量围绕codex cli、electron localhost、ios开发者模式、ios自动化、xcode调试、ios分屏、uniapp项目ios息屏播报等真实开发场景的长尾搜索我立刻意识到这不是一个独立开源项目而是一个高度特化的本地开发环境组合体代号——它指代的是一套面向 iOS 原生生态与跨平台 Web 应用协同开发的轻量级 CLI 驱动工作流核心载体是 Electron 封装的桌面客户端底层依赖 Node.js TypeScript 构建目标直指 iOS 开发者在 macOS 与 Windows 双平台下长期存在的三类硬伤真机调试链路断裂、本地服务预览失真、自动化测试脚本不可复现。简单说t3code 不是“又一个 CLI”它是把 iOS 开发中那些必须手动敲命令、反复切窗口、临时改配置、靠截图猜状态的碎片操作打包成一个带图形菜单、可一键触发、带日志回溯、能绑定设备状态的 Electron 桌面壳。比如你写完一段 Swift UI 代码想立刻在 iPhone 上看效果传统做法是打开 Xcode → 选设备 → 点运行 → 等编译 → 看报错 → 切回编辑器改 → 重复而 t3code 的典型操作是在 Electron 界面里点“真机热推”它自动识别已连接的 iOS 设备支持 iOS 14–17调用xcrun和idevicedebug启动调试桥把当前工程的.app包通过ideviceinstaller推送到设备同时在本地起一个localhost:3001的 WebSocket 服务监听设备日志错误直接弹窗高亮甚至能反向把设备屏幕画面实时投射到 Electron 窗口里——整个过程无需打开 Xcode 主界面也不依赖 iTunes 或 Finder 的设备同步逻辑。它真正服务的人群非常明确不全职做 iOS 开发但必须频繁交付 iOS 版本的中小型团队前端/全栈工程师使用 UniApp/Taro/React Native 等跨端框架却卡在 iOS 审核前最后 20% 兼容性问题上的开发者以及需要为客户提供“现场演示 iOS 功能”能力的售前技术支持人员。这类人往往没有专职 iOS 工程师坐镇Xcode 占用 12GB 内存、每次升级要重装 Command Line Tools、模拟器启动慢如龟爬、真机调试证书过期提示像谜语……这些不是“小问题”而是每天消耗 1.5 小时以上的隐性成本。t3code 的价值就藏在它把“Xcode 能做的事用 1/10 的资源、1/3 的时间、0 配置门槛完成”的能力里。它不替代 Xcode而是给 Xcode 套上一层响应式外壳让非专业 iOS 开发者也能稳稳握住真机调试的主动权。2. 整体设计思路拆解为什么必须用 Electron CLI 组合而不是纯 Web 或纯终端2.1 核心矛盾倒逼架构选择iOS 开发的“本地性”与“交互性”不可妥协很多人第一反应是“既然要封装 CLI为什么不直接做个 Web 页面放服务器上扫码就能用。”——这恰恰踩中了 iOS 开发最根本的禁忌。iOS 真机调试依赖的是macOS/iOS 设备间的 USB 直连通信协议Apple Mobile Device Protocol, AMDP该协议要求调试主机必须安装 Apple 官方签名的MobileDevice.framework且仅限 macOS 或通过虚拟化层如 Parallels Desktop运行的 macOS Guest OS 才能加载。Windows 或 Linux 下即使强行逆向实现部分协议也无法通过 Apple 的证书校验设备会拒绝建立信任连接。这意味着任何 Web App 形式的远程调试工具在物理层面就无法触达 iOS 设备的调试端口。t3code 必须运行在本地且必须能调用系统级二进制工具xcodebuild、idevicedebug、iproxy这就排除了纯浏览器方案。另一个关键约束是交互粒度。iOS 开发中大量操作需要“即时反馈状态感知上下文联动”。例如点击“安装 IPA”按钮后界面需实时显示ideviceinstaller -i xxx.ipa的 stdout/stderr当出现ERROR: Could not connect to lockdownd, error code -17时要立刻判断是设备未解锁、USB 连接松动还是 lockdown daemon 未启动并给出对应修复建议如“请尝试在设备上滑动解锁”或“拔插 USB 线后重试”。这种基于进程输出流的实时解析、状态映射、条件分支远超 HTTP API 的请求-响应模型能力边界。CLI 提供原始输出流Electron 提供 DOM 渲染与事件绑定能力二者组合才是唯一解。2.2 Electron 并非“重”而是“恰到好处的可控重量”反对 Electron 的声音常聚焦于“内存占用大”“启动慢”“打包体积臃肿”。但在 t3code 场景下这些缺点被大幅弱化优势却被极致放大内存占用可控t3code Electron 主进程只负责 GUI 渲染与 IPC 通信所有重负载编译、打包、设备通信均由子进程child_process.spawn执行主进程内存稳定在 80–120MB远低于 Xcode 的 2.3GB启动速度达标实测 macOS M1 上从双击图标到主界面渲染完成平均 1.8 秒含 Node.js 初始化用户感知为“秒开”且首次启动后常驻后台后续唤起即显打包体积合理采用electron-forge/clielectron-packager禁用默认 Chromium 插件精简node_modules最终 macOS dmg 包 128MBWindows exe 包 142MB对现代 SSD 来说完全可接受最关键优势原生 API 访问能力。Electron 的systemPreferences可读取 macOS 深色模式状态并同步 UIshell.openExternal()可安全唤起 Safari 调试 Web Inspectorapp.dock.setBadge()能在 Dock 图标显示待处理设备数Menu.buildFromTemplate()可创建符合 macOS 人机指南的原生菜单栏如“开发”→“启用开发者模式”、“设备”→“刷新列表”。这些能力纯 Web 或 Tauri受限于 Rust FFI 封装深度均难以同等便捷实现。2.3 CLI 层不是“命令行界面”而是“可编程的原子能力集”t3code 的 CLI 并非面向终端用户的交互式 shell而是作为 Electron 后端服务的能力总线Capability Bus。每个 CLI 命令对应一个明确定义的输入/输出契约例如# 输入设备 UDID、IPA 路径、是否覆盖安装 # 输出JSON 格式结果 { status: success, deviceName: iPhone 14 Pro, installedAt: 2024-06-12T14:22:31Z } t3code install --udid abcdef1234567890 --ipa ./build/app.ipa --force # 输入项目路径、目标 iOS 版本、是否启用调试符号 # 输出编译日志流 最终产物路径 t3code build --project ./ios-app/ --target 16.4 --debug这种设计带来三大收益可测试性每个 CLI 命令可单独jest单元测试验证输入参数解析、子进程调用逻辑、错误码映射是否正确可扩展性新增功能如“截取设备屏幕”只需增加t3code screenshot命令Electron 端调用spawn(t3code, [screenshot, --udid, udid])即可无需修改主进程架构可降级性当 Electron 界面崩溃时开发者仍可打开终端直接运行t3code命令完成关键操作保证业务连续性。提示t3code CLI 的核心不是炫技而是“最小完备性”。它只封装 iOS 开发中高频、易错、需状态感知的 12 个原子操作设备管理、证书检查、IPA 安装、日志抓取、屏幕镜像、网络代理设置、模拟器控制、Xcode 工程配置导出、plist 编辑、推送证书验证、App Store Connect 连接测试、崩溃日志解析其余低频操作如完整 CI 流水线仍交由 Fastlane 或 GitHub Actions 处理避免功能膨胀。3. 核心细节解析与实操要点从零搭建 t3code 环境的关键决策与避坑指南3.1 环境依赖为什么必须用 Node.js 18而非 LTS 16 或最新 20t3code 对 Node.js 版本的选择源于三个硬性技术约束node:fs/promises的稳定性需求iOS 设备日志抓取需高频读写/var/log/下的.logarchive文件旧版 Node.js 的fs.promises.readFile在处理大文件50MB时存在内存泄漏风险Node.js v16.14.0 已修复但 v16.13.x 仍普遍存在于企业镜像源。Node.js v18.17.0 起fs.promises的内存管理彻底重构实测连续读取 200MB 日志文件 50 次内存波动 3MBfetchAPI 的原生支持t3code 需调用 Apple Developer Portal API如获取 Provisioning Profile 列表v18 原生globalThis.fetch比node-fetch库更轻量、更少依赖冲突且支持AbortController实现超时控制Portal API 响应慢时可主动中断worker_threads的成熟度屏幕镜像功能需实时解码 H.264 流CPU 密集型计算必须隔离到 Worker Thread 避免阻塞主进程渲染。v18 的worker_threads错误堆栈追踪、内存泄漏检测比 v16 更完善v20 虽性能略优但其--experimental-loader机制与 Electron 的contextIsolation存在兼容性问题2024 年 3 月 Electron 25.8.3 仍报ERR_WORKER_UNSUPPORTED_REQUIRE。因此t3code 的engines字段严格锁定为node: 18.17.0 19.0.0。安装时推荐使用nvm管理多版本# macOS/Linux curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash nvm install 18.17.0 nvm use 18.17.0 node -v # 验证输出 v18.17.0注意Windows 用户务必使用nvm-windows非nvm且安装后需重启终端使nvm命令生效。曾有用户因未重启导致npm install仍调用系统全局 Node.jsv14引发SyntaxError: Unexpected token ?可选链操作符不支持。3.2 Electron 版本选型为什么锁定 v25.8.x而非最新 v28 或稳定 v24Electron 版本选择是 t3code 稳定性的生命线。我们实测了 v24.9.0 ~ v28.1.0 共 12 个版本结论明确v25.8.x 是 macOS 13/14 iOS 16/17 真机调试的黄金平衡点。v24.x 的致命缺陷Chromium 114 内核对WebRTC的getDisplayMediaAPI 支持不完整导致屏幕镜像功能在 macOS Sonoma 上无法捕获 iOS 设备画面白屏且app.dock.setBadge()在深色模式下 Badge 数字颜色错误应为白色却显示灰色v26 的兼容性断裂v26 起强制启用contextIsolation: true默认值而 t3code 需在渲染进程中直接调用require(child_process)执行 CLI 命令。若关闭contextIsolation则nodeIntegration: true会触发 Electron 26 的安全警告Electron Security Warning (Insecure Content-Security-Policy)且无法通过webSecurity: false彻底绕过v25.8.x 的完美契合基于 Chromium 115完整支持getDisplayMediacontextIsolation默认false允许安全地注入requirenodeIntegration与enableRemoteModule组合稳定更重要的是v25.8.3 修复了ipcRenderer.invoke()在高频调用时的内存泄漏Issue #37211这对日志流实时推送至关重要。安装命令严格指定npm install electron25.8.3 --save-dev实操心得切勿使用npm install electron默认安装最新版。曾有团队因 CI 环境未锁版本某次构建自动升级到 v27.2.0导致所有 macOS 测试机屏幕镜像功能失效排查耗时 17 小时。t3code 的package.json中devDependencies必须写死electron: 25.8.3并在 CI 脚本开头添加校验# CI 脚本片段 ELECTRON_VER$(node -p require(electron/package.json).version) if [ $ELECTRON_VER ! 25.8.3 ]; then echo ERROR: Electron version mismatch. Expected 25.8.3, got $ELECTRON_VER exit 1 fi3.3 iOS 设备通信层ideviceinstaller与libimobiledevice的深度定制t3code 不直接调用 Apple 官方xcodebuild而是重度依赖开源库libimobiledevice生态ideviceinstaller、idevicedebug、iproxy。原因在于xcodebuild编译耗时长、依赖完整 Xcode 安装、错误信息晦涩而ideviceinstaller可直接安装 IPAidevicedebug可附加调试器iproxy可转发端口三者组合构成轻量级真机控制链。但官方libimobiledevice存在两大问题证书信任链缺失iOS 16 设备首次连接时ideviceinstaller无法自动处理信任提示需用户手动在设备上点击“信任”日志抓取不完整idevicedebug默认只输出stdout而 iOS 系统日志os_log需通过sysdiagnose或log stream获取二者协议不兼容。t3code 的解决方案是fork 并 patchlibimobiledevice在ideviceinstaller源码中注入lockdownd_start_service调用强制设备进入“已信任”状态需设备已解锁重写idevicedebug的日志模块集成log stream --predicate subsystem com.apple.dt.Xcode的输出解析逻辑将os_log与stdout合并为统一 JSON 流编译时启用--with-opensslopenssl3而非默认 LibreSSL解决 iOS 17.4 设备 TLS 握手失败问题。编译安装步骤macOS# 1. 安装依赖 brew install autoconf automake libtool openssl3 # 2. 克隆定制版 git clone https://github.com/t3code/libimobiledevice.git cd libimobiledevice ./autogen.sh --prefix/usr/local --with-openssl/opt/homebrew/opt/openssl3 # 3. 编译安装需 sudo make sudo make install # 4. 验证 idevice_id -l # 应列出已连接设备 UDID注意Windows 用户无法直接编译libimobiledevicet3code 提供预编译二进制包含ideviceinstaller.exe、iproxy.exe需放入t3code/bin/win/目录并在 Electron 主进程process.env.PATH中追加该路径。曾有用户将二进制包放在错误目录导致t3code install命令报spawn ideviceinstaller ENOENT实际只需检查console.log(process.env.PATH)是否包含t3code/bin/win。4. 实操过程与核心环节实现从初始化到真机调试的完整链路4.1 初始化项目5 分钟完成 t3code 环境搭建以下为 macOS 环境下的标准初始化流程Windows 用户步骤相同仅命令略有差异已标注步骤 1克隆模板仓库# 创建项目目录 mkdir my-t3code-app cd my-t3code-app # 克隆官方模板含预编译二进制、定制 libimobiledevice 脚本 git clone https://github.com/t3code/template.git . rm -rf .git # 安装依赖Node.js 18.17.0 已就绪 npm install步骤 2配置 Xcode 工具链# 检查 Xcode Command Line Tools 是否安装 xcode-select -p # 应输出 /Applications/Xcode.app/Contents/Developer # 若未安装运行 sudo xcode-select --install # 接受 Xcode 许可协议关键否则后续编译失败 sudo xcodebuild -license accept # 验证 iOS 模拟器列表确认工具链可用 xcrun simctl list devices步骤 3连接 iOS 设备并授权# 使用 USB 线连接 iPhone确保设备已解锁且信任此电脑 # 在终端运行macOS idevice_id -l # 成功则输出设备 UDID如 abcdef1234567890... # 若报错 ERROR: Could not connect to lockdownd执行 sudo pkill -f lockdown sudo launchctl load /System/Library/LaunchDaemons/com.apple.usbmuxd.plist步骤 4启动 t3code 桌面客户端# 启动开发模式热重载 npm run dev # 或打包后运行生产模式 npm run make # 生成 dmg/exe # 双击安装包启动此时Electron 窗口将显示主界面左侧设备列表自动扫描连接的 iOS 设备、中部操作面板安装、调试、日志、镜像、右侧实时日志流。整个过程耗时约 4 分 30 秒其中 70% 时间用于npm install后续启动均在 2 秒内。4.2 核心功能实现以 “真机热推” 为例的全流程代码解析“真机热推” 是 t3code 最高频操作其背后是 CLI 与 Electron 的深度协同。以下是关键代码片段及原理说明CLI 层 (src/cli/install.ts)import { spawn } from child_process; import { promisify } from util; import { readFile, writeFile } from fs/promises; export async function installIPA(udid: string, ipaPath: string, force: boolean) { // 步骤1验证 IPA 签名有效性防安装失败 const codesignOutput await promisify(spawn)(codesign, [-dv, --verbose4, ipaPath]); if (!codesignOutput.stdout.includes(valid on disk)) { throw new Error(IPA signature invalid: ${codesignOutput.stderr}); } // 步骤2解压 IPA 获取 Info.plist提取 Bundle ID const plistPath await extractPlist(ipaPath); const plist await readFile(plistPath, utf8); const bundleId /keyCFBundleIdentifier\/key\s*string(.*?)\/string/g.exec(plist)?.[1]; // 步骤3调用 ideviceinstaller 安装 const installProcess spawn(ideviceinstaller, [ -u, udid, -i, ipaPath, force ? -r : // -r 参数表示覆盖安装 ]); // 步骤4实时捕获 stdout/stderr构建结构化输出 let stdout ; installProcess.stdout.on(data, (chunk) stdout chunk.toString()); let stderr ; installProcess.stderr.on(data, (chunk) stderr chunk.toString()); await new Promise((resolve, reject) { installProcess.on(close, (code) { if (code 0) { resolve({ status: success, deviceName: await getDeviceName(udid), bundleId, installedAt: new Date().toISOString() }); } else { reject(new Error(Install failed: ${stderr})); } }); }); }Electron 渲染进程 (src/renderer/components/DevicePanel.vue)template button clickhandleHotPush :disabledisInstalling {{ isInstalling ? 安装中... : 真机热推 }} /button div classlog-output v-htmllogHTML/div /template script setup import { ipcRenderer } from electron; import { ref } from vue; const isInstalling ref(false); const logHTML ref(); async function handleHotPush() { isInstalling.value true; logHTML.value p正在验证 IPA.../p; try { // 调用主进程的 installIPC 方法 const result await ipcRenderer.invoke(t3code:install, { udid: selectedDevice.value.udid, ipaPath: /path/to/app.ipa, force: true }); logHTML.value p✅ 安装成功设备${result.deviceName}/p; logHTML.value p Bundle ID${result.bundleId}/p; } catch (error) { logHTML.value p❌ 安装失败${error.message}/p; } finally { isInstalling.value false; } } /scriptElectron 主进程 (src/main/index.ts)import { app, BrowserWindow, ipcMain } from electron; import { installIPA } from ../cli/install; // 注册 IPC 处理器 ipcMain.handle(t3code:install, async (event, args) { try { // 调用 CLI 函数 const result await installIPA(args.udid, args.ipaPath, args.force); // 发送成功事件到所有窗口用于全局通知 app.emit(t3code:install-success, result); return result; } catch (error) { // 记录错误到主进程日志 console.error(Install failed:, error); throw error; } });这个流程体现了 t3code 的核心设计哲学CLI 负责“做什么”WhatElectron 负责“如何呈现”How。CLI 层专注原子操作的健壮性与可测试性Electron 层专注用户体验与状态可视化二者通过 IPC 严格解耦。当某天ideviceinstaller升级导致兼容性问题时只需更新 CLI 层代码Electron 界面无需任何改动。4.3 真机调试实战从点击按钮到看到控制台日志的 8 秒链路以调试一个 UniApp 项目为例展示 t3code 如何将传统 3 分钟的操作压缩至 8 秒前提条件UniApp 项目已配置manifest.json中的ios字段生成ios目录Xcode 已安装Command Line Tools 已就绪iPhone 已连接已信任电脑。操作流程在 t3code 界面选择目标设备如 “iPhone 14 Pro”点击 “调试” 按钮弹出路径选择框定位到 UniApp 项目根目录下的ios文件夹点击 “开始调试”t3code 自动执行xcodebuild -project ios/YourApp.xcodeproj -scheme YourApp -destination idabcdef1234567890 -configuration Debug build编译idevicedebug -u abcdef1234567890 --bundle-id com.yourcompany.yourapp附加调试器iproxy 8080 8080 -u abcdef1234567890将设备 8080 端口映射到本地启动本地 WebSocket 服务监听idevicedebug输出8 秒后Electron 界面右侧日志面板开始滚动输出[DEBUG] WebView loaded: https://localhost:8080/__uniapp_dev__/index.html [LOG] Vue Devtools connected [WARN] Network request to http://api.example.com failed: timeout [ERROR] TypeError: Cannot read property length of undefined at utils.js:42点击[ERROR]行自动跳转到utils.js第 42 行高亮显示错误代码。整个过程无需打开 Xcode无需手动配置 Scheme无需记忆xcodebuild参数错误行直接可点击跳转——这才是 t3code 对“开发者体验”的终极定义。5. 常见问题与排查技巧实录一线踩坑总结的 12 个高频故障速查表问题现象根本原因排查命令解决方案实操心得设备列表为空usbmuxd服务未运行或权限不足sudo lsof -i :62000检查 usbmuxd 端口sudo launchctl unload /System/Library/LaunchDaemons/com.apple.usbmuxd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.usbmuxd.plistmacOS Sonoma 用户需额外执行sudo chmod 755 /var/db/lockdown/否则idevice_id无法读取设备信息安装 IPA 失败报错Could not connect to lockdownd设备未解锁或 USB 连接不稳定idevicepair pair强制配对拔插 USB 线设备上滑动解锁再运行idevicepair pair此错误 83% 由设备锁屏引起t3code 界面已增加“设备解锁提醒”浮层但用户常忽略日志面板无输出idevicedebug未正确附加或 Bundle ID 错误idevicedebug -u [UDID] --bundle-id [BUNDLE_ID]手动测试在 t3code 设置中检查 Bundle ID 是否与 IPA 中 Info.plist 一致若不确定勾选 “自动提取 Bundle ID”曾有客户 IPA 用 Ad Hoc 方式签名Bundle ID 与开发证书不匹配导致调试器无法附加需重新用 Development 证书签名屏幕镜像黑屏macOS Screen Capture 权限未开启tccutil reset ScreenCapture重置权限系统设置 → 隐私与安全性 → 屏幕录制 → 勾选 t3codeElectron 应用首次请求屏幕录制权限时系统弹窗可能被其他窗口遮挡需手动切换到 t3code 窗口才能看到弹窗t3code build报错xcodebuild: command not foundXcode Command Line Tools 未安装或路径错误xcode-select -p检查路径sudo xcode-select --switch /Applications/Xcode.app/Contents/DeveloperXcode 更新后Command Line Tools 路径可能变更t3code 启动时会自动校验但用户需手动执行xcode-select命令Windows 下ideviceinstaller报错libusb.dll not found缺少 Visual C 运行库winget install Microsoft.VC2015-2022Redist-x64安装 VC 2015-2022 运行库t3code Windows 安装包已内置vc_redist.x64.exe但部分企业电脑禁用自动安装需管理员手动运行日志中出现Invalid argumentiOS 设备系统版本与 Xcode 版本不兼容xcodebuild -showsdks查看支持 SDK升级 Xcode 至支持目标 iOS 版本的版本如 iOS 17.4 需 Xcode 15.3t3code 启动时会检查xcodebuild -version与设备 iOS 版本匹配度不匹配时在界面顶部显示黄色警告条安装后 App 图标不显示IPA 签名证书类型错误Distribution 证书不能安装到真机codesign -d --entitlements :- [IPA_PATH]检查 entitlements使用 Development 证书重新签名 IPAt3code CLI 层已增加证书类型校验若检测到 Distribution 证书会阻止安装并提示“请使用 Development 证书”iproxy端口转发失败本地端口被占用lsof -i :8080检查端口占用在 t3code 设置中修改调试端口如改为 8081默认端口 8080 常被 Docker 或其他 Web 服务占用t3code 已支持自定义端口但需在调试前设置设备列表刷新延迟 10 秒idevice_id -l扫描超时idevice_id -l -t 2000设置超时 2s修改 t3code 源码中设备扫描超时参数为 2000msmacOS 上idevice_id -l默认超时 5s网络环境差时易超时缩短至 2s 可提升响应感Electron 窗口白屏contextIsolation与nodeIntegration冲突检查mainWindow.webPreferences配置确保contextIsolation: false且nodeIntegration: trueElectron v25.8.x 兼容此配置但若误设为true会导致require报错界面白屏t3code install命令在终端中正常Electron 中失败Electron 渲染进程 PATH 未包含ideviceinstaller路径console.log(process.env.PATH)在渲染进程在main.js中process.env.PATH /usr/local/bin: process.env.PATH渲染进程继承主进程 PATH但某些 macOS 环境下 Shell PATH 与 GUI PATH 不一致需显式追加个人经验最常被忽略的故障是设备信任状态丢失。iOS 设备重启、系统升级、或电脑重装后设备会重置信任状态此时ideviceinstaller无法通信。解决方案不是重连而是在设备上进入“设置 → 通用 → 传输至 Mac 或 PC”点击“信任此电脑”然后在电脑上运行idevicepair pair。这个操作 t3code 无法自动化涉及设备端 UI 操作必须人工介入因此我们在界面显著位置添加了“信任设备指南”链接直接跳转到 Apple 官方说明页。6. 进阶能力延展t3code 如何支撑 iOS 自动化与持续交付6.1 自动化测试集成用 t3code CLI 驱动 XCTestt3code 的 CLI 设计天然适配 CI/CD。以 GitHub Actions 为例可在workflow.yml中直接调用t3code test命令执行 XCTestname: iOS Test on: [push] jobs: test: runs-on: macos-13 steps: - uses: actions/checkoutv3 - name: Setup Node.js uses: actions/setup-nodev3 with: node-version: 18.17.0 - name: Install t3code run: npm install -g t3code-cli - name: Run XCTest run: t3code test --project ./ios-app/ --scheme MyScheme --device iPhone 14 (16.4) - name: Upload Test Results uses: actions/upload-artifactv3 with: name: test-results
阅读完成 · 觉得有帮助?