团队构建接入手册

接入 runner,按这一页来

整台 Apple Silicon M4 Mac mini 只运行你团队的任务。先核对实例与连接,再注册 runner,最后固定 Xcode 工具链;把问题停在对应环节,不必重做整条流水线。

已有订单从控制台核对状态;注册令牌、SSH 密码和签名材料不要放进公开日志。

从订单到连接

按四个检查点接管节点

付款确认后,到取得并核对连接凭据,通常按约 4 分钟安排。以下耗时是流程参考,不含支付网关确认、网络重试、安装依赖或 runner 注册;实际进度以控制台返回为准。

  1. 核对已确认订单

    参考 30 秒

    在控制台确认订单已付款,检查机型、周期和节点是否与购买内容一致。Merge M4 S 为 16GB RAM / 256GB SSD,Merge M4 L 为 24GB RAM / 512GB SSD,两档均使用 Apple Silicon M4。

    卡在这里:先看账单状态,不要因页面暂未更新重复支付;保留订单编号,再到本页账单部分核对付款记录。

  2. 查看物理节点分配

    参考 2 分钟

    打开订单关联的实例详情,等待系统返回实例状态与连接信息。每台机器只分配给一个客户,非虚拟机;同一团队的任务调度由你配置的 runner 管理。

    卡在这里:记录实例 ID、订单编号和当前状态,通过控制台工单提交。不要把“账单已付款”直接当成“实例凭据已生成”。

  3. 读取连接凭据

    参考 1 分钟

    从实例详情读取 SSH 地址、端口、用户名及 VNC 连接信息。按字段逐项使用,不要猜测默认端口,也不要沿用旧实例的地址或密码。

    卡在这里:确认当前登录的账号拥有该订单,再检查是否打开了正确实例。工单只需要实例 ID 和缺少的字段名称,不要发送完整密码。

  4. 验证一次远程连接

    参考 30 秒

    SSH 用于命令行构建、注册 runner 和同步文件;VNC 用于 Xcode 图形界面、模拟器及交互式配置。macOS 图形界面与命令行均可使用,两种方式可以配合工作。

    ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST"
    uname -m
    sw_vers

    首次连接先核实主机指纹,成功后检查架构输出为 arm64。超时先查地址、端口及本地网络;认证失败先查用户名和凭据。不要通过关闭主机身份校验绕过指纹异常。

    VNC 客户端使用实例详情提供的对应字段,而不是直接复用 SSH 端口。连接成功但画面迟缓时,先降低分辨率;自动构建可继续通过 SSH 执行。

沿用团队现有 CI

把任务明确派给这台 M4

先从 CI 平台的新增 runner 或 agent 页面取得安装包和注册命令,再在节点上执行。下面只列注册要点;令牌、组织地址和工作目录由你的平台生成,不能直接照抄示例变量。安装后先跑一条不含签名材料的测试任务。

GitHub Actions

在仓库或组织设置中新增 self-hosted runner,选择 macOS 与 ARM64 包。解压后在 runner 目录执行平台给出的配置命令,再启动进程。

./config.sh \
  --url "$RUNNER_URL" \
  --token "$RUNNER_TOKEN" \
  --labels macos-m4
./run.sh

工作流指定 runs-on: [self-hosted, macOS, ARM64, macos-m4],确认标签与注册结果一致。标签用于路由,不代表机器会自动隔离不同任务。

验证点:平台显示在线,测试任务的 uname -m 输出为 arm64。需要常驻时,按安装包提供的服务说明配置,并用同一构建用户运行。

建议标签:macos-m4

GitLab Runner

在项目或组中创建 runner,取得当前版本使用的认证令牌。安装 ARM64 版本后注册,选择 shell executor,让任务在该构建用户的 macOS 环境中执行。

gitlab-runner register
gitlab-runner verify
gitlab-runner run

在平台为 runner 设置 macos-m4 标签,并在作业的 tags 中填写同名值。交互式注册时输入平台提供的地址与令牌,不要把令牌写入仓库。

验证点:runner 已关联正确项目,作业能进入执行状态。若一直等待,检查标签、受保护分支设置和 runner 的项目授权,再查机器负载。

执行方式:shell

Jenkins agent

创建专属节点,设置远程工作目录与 macos-m4 标签。按控制器提示安装兼容 Java,下载该控制器提供的 agent 文件,并采用其生成的启动参数。

java -jar agent.jar \
  -url "$JENKINS_URL" \
  -secret "$AGENT_SECRET" \
  -name "$AGENT_NAME" \
  -webSocket \
  -workDir "$AGENT_WORKDIR"

流水线指定 agent { label 'macos-m4' }。工作目录需要构建用户可写;Java 版本应与控制器要求一致,不能只检查本地终端能否启动 Java。

验证点:控制器显示节点在线,工作区位于预期目录。先用单个 executor 建立基线,再根据内存、磁盘与测试负载评估并发。

先验证单任务基线

独享整机消除了与其他客户争用 CPU 的问题,不会替你取消团队内部队列。若同一 runner 同时承接多条任务,仍需自行安排并发、工作区和签名材料的隔离。

固定可复现的环境

让本地与 CI 指向同一套 Xcode

“终端能编译,runner 却失败”常见于工具链路径或运行用户不同。先记录当前版本,再选择工具链,最后补齐所需模拟器运行时;不要把重装 Xcode 当成第一步。

切换前先记录版本

多版本 Xcode 可以分别存放在不同应用路径。先用以下命令记录系统、当前开发目录与构建工具版本,再把结果与项目要求比对。

sw_vers
xcode-select -p
xcodebuild -version
xcrun --find swift

需要改变整台机器的默认值时,使用 xcode-select。切换前确认没有其他构建正在运行,并在 CI 运行用户下复查结果。

sudo xcode-select --switch \
  /Applications/Xcode.app/Contents/Developer
xcodebuild -version

按作业选择,按项目下载

团队需要不同 Xcode 版本时,优先为各作业设置 DEVELOPER_DIR,减少全局切换的相互影响。将示例路径换成节点上实际存在的版本目录。

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
xcodebuild -version
xcrun simctl list runtimes
xcrun simctl list devices available
df -h

在 Xcode 设置中按项目目标下载模拟器运行时。运行时、模拟器数据与 DerivedData 都会占用磁盘;安装前检查剩余空间,只保留团队实际使用的版本。

命令可用不等于项目依赖已齐全。用同一用户检查 Ruby、CocoaPods、包管理器与项目锁文件,首次安装提示应先在交互环境完成确认。

提交首条构建前,在 runner 执行环境内完成三项核对
核对对象检查命令或位置通过条件
工具链路径xcode-select -p 与作业环境变量指向项目约定的 Xcode,且版本输出与预期一致
运行身份whoami、printf '%s\n' "$HOME"构建用户、主目录和钥匙串所属用户一致
工作区与磁盘pwd、df -h工作区可写,依赖、临时文件和归档有足够空间

统一团队用词

八个术语,对应八个边界

把机器、连接方式和任务调度分开理解,提交问题时就能准确描述卡在哪一层。

物理节点
实际承载 macOS 与构建任务的 Mac mini 设备,实例详情中的连接信息对应你租用的节点。
独享
整台机器只分配给一个客户,不与其他客户分 CPU,但团队自身仍需管理任务并发。
非虚拟机
交付的是独享物理 Mac 的使用环境,而不是从共享宿主机划分出的虚拟实例。
VNC
远程查看和操作 macOS 图形界面的连接方式,适合 Xcode、模拟器和交互式配置。
SSH
加密的命令行连接方式,可用于执行构建命令、管理进程及通过相关工具传输文件。
self-hosted runner
由团队在自己的节点上注册和管理的 CI 执行程序,负责从 CI 平台领取并运行任务。
Apple Silicon
Mac 使用的 Apple 芯片架构,本服务两档机型均为 M4,选择依赖与 runner 安装包时应核对 arm64 支持。
Thunderbolt 5 并联
目录中按每台计费的连接附加项,不会自动把多台机器的 CPU 或内存合成单台,工作负载仍需自行编排。

保留日志,再改环境

按错误所在层恢复构建

先保存失败命令、退出码与首个有效错误,再只改一个变量重跑。不要一边切 Xcode、一边删除缓存、一边重注册 runner,否则无法判断是哪一步解决了问题。

签名失败:先检查运行用户与钥匙串

先区分“编译失败”和“签名失败”。只有归档或签名阶段报错时,才检查签名证书、对应私钥、描述文件及其有效期;这些材料需要由团队按项目要求配置。

whoami
security list-keychains -d user
security find-identity -v -p codesigning

若图形界面可签名而 CI 失败,检查 runner 是否由同一用户启动、目标钥匙串是否在搜索列表,以及非交互式进程是否具有所需访问权限。钥匙串需解锁时,通过 CI 的受保护密钥注入凭据,禁止把密码写进脚本、命令历史或日志。

证书导入后还应核对描述文件对应的团队、应用标识与构建配置。提交工单时保留脱敏错误,不上传私钥、证书密码或完整签名材料。

缓存异常:缩小到单个项目再清理

先重跑相同提交并记录 Xcode 版本。若仅一项依赖解析失败,先核对锁文件、依赖版本与下载错误;网络失败不能通过反复清空全部缓存解决。

为项目配置独立 DerivedData 路径,便于只重建该项目的产物。以下命令用于已有的独立工作区;执行前将变量替换为真实路径和共享 scheme。

xcodebuild \
  -workspace "$WORKSPACE" \
  -scheme "$SCHEME" \
  -derivedDataPath "$PROJECT_DERIVED_DATA" \
  clean build

clean 会增加下一次构建工作量。多个作业不要共用同一可写缓存目录;先停掉占用该目录的任务,再执行清理或迁移。

磁盘不足:先区分缓存、运行时与产物

先查看剩余空间,再检查 DerivedData、归档和模拟器数据的实际占用。不要直接对整个用户目录执行递归删除,也不要在归档上传期间清除产物。

df -h
du -sh "$HOME/Library/Developer/Xcode/DerivedData"
du -sh "$HOME/Library/Developer/Xcode/Archives"
du -sh "$HOME/Library/Developer/CoreSimulator"

停止相关作业后,清理不再使用的项目缓存,在 Xcode 中移除不需要的运行时,并把已备份的历史归档按团队保留规则处理。工程、签名材料和发布产物必须单独备份。

长期空间需求可在下单配置中考虑 +1TB SSD 或 +2TB SSD 附加项。增加存储不等于增加内存;应先确认瓶颈来自磁盘,而不是任务并发。

runner 离线:按连接、进程、授权逐层检查

先通过 SSH 确认节点可访问,再检查 runner 进程与日志。节点在线但 CI 平台显示离线,通常需要继续核对进程是否退出、到 CI 控制器的网络是否可达,以及令牌或节点授权是否变更。

在前台启动 runner 验证一次,保留首条连接错误;前台能运行但退出终端后掉线,说明需要按该 runner 的说明配置常驻服务。服务运行用户必须与工具链、工作目录和钥匙串配置一致。

重启前确认没有正在执行的归档或上传任务,避免截断产物。若平台显示在线但作业仍排队,检查标签、分支权限及并发限制,而不是反复删除并注册 runner。

多个实例组池时,为节点增加可辨识标签,例如 macos-m4-build 与 macos-m4-release,让发布任务只路由到配置了相应签名环境的节点。

先核对交易,再重试

把付款记录与订单一一对应

按天、周、月或季计费,统一以美元(USD)结算。仅支持 USDT-TRC20,以及经 Stripe 处理的 Visa / Mastercard / Amex;实际可用网关以后端接口返回为准。

USDT-TRC20 已转出,订单仍待确认

逐项核对订单支付页给出的网络、收款地址与金额。转出记录不等于订单已确认;需要同时查看链上交易状态和控制台账单状态。

不要重复转账来催促确认,也不要把其他订单的支付信息用于当前订单。保留订单编号、交易哈希、金额和转出时间,在控制台工单中提交这些信息;不要发送钱包密钥或恢复短语。

如果支付页面已退出,先返回同一订单查看当前状态,再决定是否继续支付,避免为同一服务创建重复付款。

卡支付未完成,先查验证与发卡行结果

检查卡片资料和账单信息是否正确、额度是否足够,以及发卡行验证是否完成。若跳转页面被拦截,允许当前支付流程所需的页面打开后再核对订单。

看到拒绝信息时,保存错误摘要并联系发卡行确认交易限制。不要连续快速提交;若银行显示扣款而订单未确认,先通过工单核对,不要立即再次支付。

工单附订单编号、发生时间和脱敏错误截图即可。本站不需要你的完整卡号、安全码或银行验证代码。

续费前先确认实例、周期与到期时间

从控制台进入已有实例对应的订阅或账单,核对实例 ID、到期时间与应付周期后再付款。新建订单和续费现有实例是两件事,不要仅凭机型名称判断。

续费是否完成以账单和实例状态为准,不要假定已自动续费。到期前备份工程、缓存策略和发布产物;实例释放后的磁盘擦除不能当成可恢复备份。

节点全年 365 天正常运行。若问题涉及服务可用性,提交实例 ID、受影响时间段及连接错误,以便核查;不要把用户主动停止进程与节点不可用混为一谈。

带上可复现的信息

把失败现场交给支持

已有实例的问题,从控制台提交工单:附实例 ID、发生时间与时区、失败步骤、预期结果和脱敏日志。批量开机或 runner 池规划,通过联系页整理需求,或发邮件至 support@vpsmerge.com。

不要发送密码、注册令牌、私钥或完整支付凭据。保留首个有效错误,比整屏重复日志更便于定位。