开通与登录
核对订单和主机凭据,完成首次 SSH 连接,添加自己的登录公钥。
查看首次连接步骤先确认能连接,再锁定工具链,最后接入 CI。这里按实际操作顺序,带你把一台独享物理 Mac 配成可重复执行的打包节点。非虚拟机,macOS 图形界面与命令行均可使用。
已有主机,从下方「开通与登录」开始;尚未选型,可先用单任务验证构建,再决定并发规模。
没有找到匹配章节。试试「连接」「证书」或「账单」,也可以清除搜索查看全部步骤。涉及具体主机的问题,请登录控制台提交工单。
下面是建议的操作顺序,不是开通或处理时限承诺。先在控制台确认服务已开通,再使用该实例实际返回的地址、端口与用户名。不要根据示例猜测主机凭据。
登录控制台,在对应服务详情中核对机型、节点与租期。记录主机编号;后续排查、续费与工单都以这个编号关联。连接地址与初始凭据只在授权账户内查看。
将控制台返回的信息填入本地连接参数。首次连接时核对主机密钥指纹;若没有可信的指纹来源,先通过工单确认,不要直接跳过校验。连接成功后运行系统与用户检查。
在交互式 SSH 会话中执行 passwd,按提示修改当前用户密码。密码不要写进命令参数、仓库、聊天记录或构建日志。保持当前会话,另开会话确认新凭据可用。
在自己的电脑生成专用密钥,只把公钥加入主机。确认公钥登录成功后,再调整密码登录策略;涉及 SSH 服务设置前保留可用会话,避免把自己锁在主机外。
ssh -p "$MAC_SSH_PORT" "$MAC_USER@$MAC_HOST"
whoami
sw_vers
uname -m
xcode-select -p
df -h
passwd
连接前,在本地设置 MAC_SSH_PORT、MAC_USER、MAC_HOST,值取自控制台。其余命令在登录后的主机中执行;xcode-select -p 用于检查当前开发工具路径。
install -d -m 700 "$HOME/.ssh"
touch "$HOME/.ssh/authorized_keys"
chmod 600 "$HOME/.ssh/authorized_keys"
printf '%s\n' "$LOGIN_PUBLIC_KEY" >> "$HOME/.ssh/authorized_keys"
先将 LOGIN_PUBLIC_KEY 设置为你的完整公钥文本,再执行追加命令。不要上传私钥,也不要重复追加同一公钥。连接超时、认证失败和主机密钥变化是不同问题,提交工单时应区分描述。
先记录项目需要的 Xcode、SDK 与 runtime,而不是直接升级到最新版本。系统与 Xcode 的兼容性决定了可安装范围;已有项目应先沿用本地成功构建的组合,再单独验证升级。
如主机尚未安装 xcodes,先按团队认可的软件安装流程准备该工具。安装指定版本时,使用合法取得、与项目要求一致的本地 Xcode 安装包;下面的 XCODE_VERSION 与 XCODE_XIP 分别表示已核对的版本号和安装包绝对路径。不要把安装过程中的交互步骤放进无人值守的构建任务。
xcodes installed
xcodes install "$XCODE_VERSION" --path "$XCODE_XIP"
xcodes installed
export DEVELOPER_DIR="$XCODE_APP/Contents/Developer"
xcodebuild -version
xcodebuild -showsdks
xcrun simctl list runtimes
XCODE_APP 应指向安装后的实际应用路径。对 CI,优先在任务环境中设置 DEVELOPER_DIR,避免多个任务争抢全局选择。如果确实要切换系统默认工具链,再执行 sudo xcode-select --switch "$XCODE_APP/Contents/Developer",随后重新核对 xcodebuild -version。
第一次启动所选 Xcode,完成必要的组件准备。图形界面可通过远程连接操作;随后在 Xcode 的组件设置中安装目标 runtime。执行 xcrun simctl list devices available,选择与测试目标匹配的模拟器,先交互式启动一次并等待启动完成,再跑一个最小测试任务。归档真机包与执行模拟器测试是不同步骤,不要把缺少 runtime 误判为归档工具链故障。
把工具链检查放在 CI 日志开头:至少输出 Xcode 版本、SDK 列表和代码提交号。更换 Xcode 后重新生成缓存键,并验证第三方依赖、签名与导出流程;只修改 runner 标签而不核对实际工具路径,无法保证构建环境一致。
同一台物理节点上的任务会共享 CPU、内存、磁盘和用户环境。起步时每台只执行 1 个构建任务;确认归档、签名和清理都稳定后,再根据实际峰值占用增加并发,或增加独立节点。
在项目的 runner 设置中创建项目 runner,准备对应的认证 token,并设置 macos、arm64、ios-archive 三个标签。将实例地址与认证 token 临时放入 GITLAB_URL、GITLAB_RUNNER_TOKEN,在专用构建用户下注册 shell executor。完成后清理临时 token 变量。
gitlab-runner register \
--non-interactive \
--url "$GITLAB_URL" \
--token "$GITLAB_RUNNER_TOKEN" \
--executor "shell" \
--description "armrdp-ios-archive"
unset GITLAB_RUNNER_TOKEN
gitlab-runner verify
在该 runner 实际使用的 config.toml 中,将全局 concurrent = 1,并为对应 runner 设置 limit = 1。按所安装版本的服务管理方式启动 runner;交互式验证成功不等于后台服务已运行。
ios_archive:
tags:
- macos
- arm64
- ios-archive
script:
- xcodebuild -version
- xcodebuild archive -workspace "$IOS_WORKSPACE" -scheme "$IOS_SCHEME" -destination 'generic/platform=iOS' -archivePath "$CI_PROJECT_DIR/output/App.xcarchive"
artifacts:
paths:
- output/App.xcarchive
expire_in: 7 days
在项目变量中设置实际的 IOS_WORKSPACE 和 IOS_SCHEME,并先完成下一节的签名准备。这里仅归档,不包含导出或上传步骤;产物保存 7 天是示例配置,可按团队保留策略修改。不要将证书、私钥或临时 Keychain 放进 artifacts。
从仓库设置提供的 runner 安装步骤取得适用于 macOS ARM64 的程序,进入解压目录。设置 REPOSITORY_URL 为当前仓库地址,RUNNER_TOKEN 为本次注册 token。标签必须同时出现在注册配置和工作流中,才能避免任务被路由到错误工具链。
./config.sh \
--url "$REPOSITORY_URL" \
--token "$RUNNER_TOKEN" \
--name "armrdp-ios-archive" \
--labels "macos,arm64,ios-archive" \
--work "_work"
unset RUNNER_TOKEN
./run.sh
name: iOS archive
on:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ios-archive
cancel-in-progress: false
jobs:
archive:
runs-on: [self-hosted, macos, arm64, ios-archive]
env:
DEVELOPER_DIR: ${{ vars.DEVELOPER_DIR }}
IOS_WORKSPACE: ${{ vars.IOS_WORKSPACE }}
IOS_SCHEME: ${{ vars.IOS_SCHEME }}
steps:
- uses: actions/checkout@v4
- name: Archive
run: |
xcodebuild -version
xcodebuild archive \
-workspace "$IOS_WORKSPACE" \
-scheme "$IOS_SCHEME" \
-destination 'generic/platform=iOS' \
-archivePath "$RUNNER_TEMP/App.xcarchive"
先设置仓库变量中的工具路径、workspace 与 scheme。该示例使用手动触发,便于先验证环境;不要直接向不受信任的外部代码开放带签名凭据的 runner。一个 runner 进程同时接一项任务,concurrency 还会约束同组工作流的执行;它不是主机级资源限额。
验证通过后,按下载程序提供的服务脚本配置常驻运行,并确认服务用户与手动测试用户一致。若把签名准备在一个用户下、服务却运行在另一个用户下,常见结果就是交互式构建成功、CI 找不到证书或描述文件。
分发证书、对应私钥和描述文件必须与项目使用的团队及 Bundle Identifier 匹配。先在受控任务中验证签名,再接入无人值守流程;不要用关闭签名检查来掩盖导出失败。
为自动化任务使用单独的构建 Keychain,密码由 CI 的受保护秘密变量注入。导入证书后,只授予确有需要的签名工具访问权限,不要允许所有应用访问私钥。下面的检查命令用于确认当前用户能看到有效签名身份;它不会证明描述文件、导出配置和项目设置已经完全匹配。
security list-keychains -d user
security find-identity -v -p codesigning
printf '%s\n' "$HOME/Library/MobileDevice/Provisioning Profiles"
printf '%s\n' "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"
不同 Xcode 版本使用的描述文件位置可能不同,以当前工具链实际读取的路径为准。导入后检查有效期、应用标识和签名类型。归档成功但导出失败时,重点对照导出配置里的方式、团队标识及描述文件映射,而不是反复重新安装 Xcode。
团队已使用 fastlane match 时,沿用现有的加密证书仓库和访问策略。在验证阶段使用 bundle exec fastlane match appstore --readonly,先读取已有签名材料,避免构建节点意外修改团队证书。仓库访问凭据、解密密码和 Keychain 密码分别管理;生产签名变量只向受保护分支或受控手动任务开放。
任务结束后清理临时文件并锁定临时 Keychain。日志只保留必要的错误码和步骤结果,不输出私钥内容、证书密码、注册 token 或完整的秘密变量。独享物理机提供资源隔离,但项目内的凭据权限仍应按最小授权管理。
可加购 +1TB SSD 或 +2TB SSD。先在订单与主机侧确认扩展已经完成,再安排数据迁移;卷名、挂载路径和文件系统以实际交付信息为准,不要直接照抄其他主机的磁盘标识。
执行 diskutil list 和 df -h,核对容量及挂载点。不要对不明磁盘执行抹除或分区命令。为构建用户创建有写入权限的缓存目录,并用小文件测试读写;确认重启后的挂载行为后,再让常驻 runner 使用新路径。
迁移前暂停接收新任务,等待正在运行的归档和签名完成。DerivedData 是可重建缓存,优先在新位置重新生成,而不是复制可能处于写入中的旧缓存。下面使用明确的 -derivedDataPath,无需把整个用户目录迁到扩展卷。
diskutil list
df -h
test -d "$BUILD_VOLUME" && test -w "$BUILD_VOLUME"
mkdir -p "$BUILD_VOLUME/DerivedData/$CACHE_KEY"
xcodebuild archive \
-workspace "$IOS_WORKSPACE" \
-scheme "$IOS_SCHEME" \
-destination 'generic/platform=iOS' \
-derivedDataPath "$BUILD_VOLUME/DerivedData/$CACHE_KEY" \
-archivePath "$BUILD_VOLUME/Archives/$BUILD_ID/App.xcarchive"
执行前,把 BUILD_VOLUME 设为已确认可写的挂载目录。CACHE_KEY 应区分仓库、Xcode 版本与构建配置;BUILD_ID 使用当前任务的唯一标识,避免不同任务覆盖归档。并行任务不要共用同一个可写 DerivedData 目录。
先完成一次无缓存构建,再观察后续任务的缓存命中和磁盘增长。为归档、模拟器数据和依赖缓存分别设置保留策略;删除前确认没有任务仍在使用。构建产物应另外保存到团队控制的产物存储,不能把主机缓存当作唯一备份。租期结束前完成导出,并验证备份能读取。
涉及主机、订单或支付的问题,请登录控制台提交工单,便于关联实际服务。无法登录时,可发邮件至 support@armrdp.com。这两种方式都是正式联系入口。
| 字段 | 建议填写内容 | 用途 |
|---|---|---|
| 主机或订单编号 | 控制台中的对应编号,以及当前节点 | 定位具体服务,避免查错实例 |
| 发生时间 | 开始与结束时间、时区、是否仍持续 | 对齐服务记录与任务日志 |
| 问题类别 | 连接超时、认证失败、构建失败、签名失败或账单状态 | 区分网络、工具链和结算问题 |
| 复现步骤 | 执行顺序、最小命令、预期结果与实际结果 | 减少来回确认所需的上下文 |
| 环境与日志 | Xcode 版本、runner 服务用户、错误前后的脱敏日志 | 确认是否与版本或权限相关 |
| 业务影响 | 单个任务还是整台主机受影响,是否有可用的替代构建路径 | 说明影响范围和当前处置情况 |
工单处理进度与回复时间以控制台内的实际记录为准,不把首次回复等同于故障解决。连接问题可能需要核对主机状态与访问链路,构建问题通常还需要任务日志和复现步骤,支付问题则需要关联订单及交易记录;这些情况不能共用一个固定解决小时数。
等待期间,建议把新增证据补充到同一工单,注明已等待时长和影响是否扩大。不要重复执行可能改变现场的重装、清盘或批量清理操作。若错误只出现在 CI,保留同一用户下交互式执行与服务执行的差异;若涉及签名,仅提供脱敏后的错误信息。
服务按天、周、月、季预付,查看订单时应同时核对机型、节点、周期起止与附加项。续费、是否启用自动续费及付款结果,都以控制台当前设置和实际返回为准;提交付款并不等于订单已经开通,不要仅凭支付页面截图判断服务状态。
仅支持 USDT-TRC20 与 Visa / Mastercard / Amex(经 Stripe),全部以美元结算,实际可用网关以后端返回为准。使用链上支付时核对网络、收款信息和金额;需要排查时提供订单编号与交易标识,不提供钱包私钥或完整银行卡信息。
到期前先停止新增构建,导出代码变更、归档产物及必要配置,并在自己的存储中核对可恢复性。若准备继续使用,完成续费后再次确认新的到期时间;若准备结束租用,不要把到期后的主机当作长期存档位置。
从单台、单任务开始,验证工具链、签名和产物,再扩展到多台 runner。独享物理 Mac 按天起租,入口价 $21.1/天;具体可用状态以控制台实时返回为准。