Jenkins 远程连接 Mac 打 iOS 包的踩坑
Jenkins 远程连接 Mac 打 iOS 包的踩坑
让 Jenkins 在 Mac 上打 iOS 包,有两条路:在 Mac 上直接搭 Jenkins,或 Jenkins 远程连 Mac 节点。这里用的是后者——Jenkins 用 SSH 连 Mac,只需 IP 和账号密码。连接本身很简单,坑都在后面:SMB 挂载会失效、Mac 终端 bash/zsh 不一致、Jenkins 里 python/p4 必须用全路径、codesign 要解锁钥匙串、Shader DDC 偶尔失效。
Mac 环境
需要装的东西:
| 环境 | 来源 | 备注 |
|---|---|---|
| Xcode | App Store | 需要 Apple ID |
| p4 | https://www.perforce.com/downloads/ | 除 p4v 外要单独下 Helix Command-Line Client,否则用不了 p4 命令 |
| JDK | jdk-8u333-macosx-x64.dmg |
Mac 息屏后容易断连导致报错,设成永不休眠。
SMB 共享目录挂载
Mac 不能直接访问 Windows 共享,要用 smbfs 挂载。
# 建挂载点(名字和位置随意)
mkdir ~/Desktop/build_package
# 挂载远程共享目录
mount -t smbfs //<nas>/<share> ~/Desktop/build_package
# 卸载
diskutil unmount ~/Desktop/build_package
开机自启的自动挂载脚本:
# nano automountsmb,写入:
#!/bin/bash
mount -t smbfs //<nas>/<share> ~/Desktop/build_package &
exit
# 保存退出后:
sudo chmod +x automountsmb
开机自启:系统偏好设置 → 用户与群组 → 登录项 → 加号添加脚本。
挂载会失效,流水线里要重挂
挂载会在一段时间后失效(把 Keychain Access 里对应 NAS 的 Access Control 设成 "Allow all applications to access this item" 也未必有用)。失效后重挂需要几秒才生效,否则会找不到共享文件夹而直接复制到本地,所以重挂后要 sleep(10)。这个 stage 建议写在最开头:
stage('Get smb'){
steps{
script{
mount_result = sh(returnStdout:true, script:"mount").trim()
if(! mount_result.contains('/Users/<user>/Desktop/build_package')){
sh"/Users/<user>/Desktop/automountsmb"
sleep(10)
}
}
}
}
Mac 终端的 bash 和 zsh
Mac 终端分 bash 和 zsh。同一命令在 Mac 终端没问题、在流水线报错时,先怀疑是 shell 类型问题:流水线里 sh 默认用 zsh,而在 Mac 上打开终端是 bash,跑打包脚本会报错。试过改 .command/.sh 文件调用没用,切到 bash 就解决:
sh"""
echo $SHELL # /bin/zsh
source ~/.bash_profile # 切到 bash
"""
pipeline 还是 freestyle
跑 xcodebuild 和打包脚本时,Mac 上能成功,pipeline 里报错。试过改 Platform 名、加 Configuration 参数都没解决:
// Mac 上正常
sh "xcodebuild -scheme <Project> -workspace ${ue4xcworkspace} build"
// 加 Configuration 参数也不行
sh "xcodebuild -Configuration='Development Editor' -scheme <Project> -workspace ${ue4xcworkspace} build"
把命令写成 freestyle 就能跑通。所以建议打包脚本用 freestyle。
python 和 p4 必须用全路径
Jenkins 的环境变量 Path 用的是 /usr/bin,而 Mac 有 /usr/local/bin 和 /usr/bin 两个路径,里面的命令不同,且没权限改 /usr/bin。
python
/usr/bin 下的 python 是 3.8.9,用全路径才能定位到装好的 3.10.8:
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3
若用全路径后还报错,清掉 python 的环境变量再重连节点:
vim ~/.bash_profile # 删掉 python 的 Path
source ~/.bash_profile
# 重连 Jenkins 节点(不行就重启 Mac)
p4
p4 命令不能在 P4V 里用,要把 helix-core-server.tgz 解压到 Application。想把 p4 拷进 /usr/bin 会被 Rootless(SIP)挡住,设 root 权限也不行。
关 SIP 的流程:
- 重启时一直按 Command+R 进恢复模式,打开 Terminal,
csrutil disable - 关终端重启。恢复默认用
csrutil enable - 重启后
csrutil status确认,显示System Integrity Protection status: disabled即关闭成功
但即便关了 SIP,/usr/bin 还是 Read-only file system 改不了。改用 /usr/local/bin:
sudo cp /Applications/helix-core-server/p4 /usr/local/bin
sudo vim /etc/profile
# 加 PATH=/usr/local/bin:$PATH,保存
source /etc/profile
# 重连 Jenkins 节点
此时 Mac 终端能用 p4,但 Jenkins 还是 p4: command not found(因为 Jenkins 的 Path 用 /usr/bin)。所以 Jenkins 里还是得用全路径:
sh "/Applications/helix-core-server/p4 revert //..."
结论:这类操作尽量用全路径。
codesign 密码验证
打包时遇到需要密码验证、报 codesign 相关错误:
可能是钥匙串系统账号和登录账号里的证书冲突了——查系统账号下有没有重复证书,删掉重复的。
把相关证书的 Access Control 设成 "Allow all applications to access this item"。
在脚本前加解锁钥匙串的命令(
"password"是电脑登录密码):security unlock-keychain -p "password" ~/Library/Keychains/login.keychain
加了这条之后可免去密码验证。
Shader 缓存 DDC
正常编译会访问共享文件夹的 DDC 缓存,但 Mac 不能直接访问共享文件夹,所以缓存在本地。用 Jenkins 打包偶尔会出现 DDC 问题导致项目重编一遍 shader,耗时太久。一般停掉 job 重跑一遍即可。
p4v 拉数据报错
Mac 拉数据报 Translation of file content failed near line *** //depot/file 时,检查 p4v 版本,不是最新就升到最新再试。