从 Git 仓库中克隆出指定 tag 处的指定文件

背景

项目中的一个模块从源码打包成了动态库 pod,这个模块迭代了十来年,打包出来的 Framework 对应的 dSYM 压缩后的体积也达到了 150MB。为方便管理,我们将 dSYM 和动态库放到同一个 git 仓库中,并通过 git-lfs 来管理体积大的二进制文件和 dSYM 文件。

目标

日常开发时,Framework 的调用方通过 pod 'xxxx' 引入此动态库,要尽量节省每次 pod update 的耗时,同时也希望在 AdHoc 打包内测时,能快速获取到此 dSYM 以便能上传到 firebase 解析后续可能发生在动态库中的闪退信息。

解决

一开始我们模仿 FirebaseCrashlytics.podspec 的写法,使用 preserve_paths 夹带私货,让 dSYM 跟随 Framework 一起在 pod update 时被下载,同时又不被集成到 Xcode 里面。FirebaseCrashlytics 自家的用来上传符号文件的程序 upload-symbols 就是这样做的。但我们的 dSYM 太大了,下载比较耗时。

后来了解到 GitLab 有一种大文件独立下载的特性,具体来说就是允许单独下载特定分支(或 tag)特定路径的文件,而不用全盘 clone 到本地。所以我们在动态库的 .podspec 中排除了 dSYM 的引入,让调用方只关注 Framework 本身,然后在打包脚本中应用 GitLab 此特性先下载到 dSYM 然后再上传,这样下载的耗时只发生在打包过程中。完整处理代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# !/bin/sh
# 输入:
# $1 动态库仓库的一个 tag
# 处理: 存放于本地的该 tag 对应的 dsym 文件。并根据语言环境上传到 firebase

FASTLINE_ROOT=$(pwd)
TEMPDIR=$(mktemp -d)
cd ${TEMPDIR}

echo "要拉取的 dsym 的 tag:$1"

git clone --filter=blob:none --sparse git@git.xxx.com:xxx/dynamic.git
cd dynamic
git sparse-checkout init --cone
git fetch origin tag $1 --no-tags
git checkout $1
git sparse-checkout add path/to/dSYM.zip

DSYM_FILE_PATH="${TEMPDIR}/dynamic/path/to/dSYM.zip"

UPLOAD_BIN_PATH="${FASTLINE_ROOT}/../Pods/FirebaseCrashlytics/upload-symbols"
PLIST_PATH="${FASTLINE_ROOT}/../GoogleService/GoogleService-Info.plist"

UPLOAD_CMD="$UPLOAD_BIN_PATH -gsp $PLIST_PATH -p ios $DSYM_FILE_PATH"
echo "exec cmd : ${UPLOAD_CMD}"
eval ${UPLOAD_CMD}

Ref


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!