让CI里的Swift Package Manager HTTP鉴权也能666的避坑指南

前述

本文是一次探【Mo】索【Yu】过程的记述,为了节约您的宝贵时间,需要执行步骤的,请直接查阅步骤总结,您的一键三连是我持续分享的最大动力,拜谢🙏!

遇到问题

众所周知,Swift Package Manager是Apple官方出品的一套包管理工具,内置于Xcode,其具有较好的离散型,编译时再拉取依赖的特性使得宿主工程更轻便,相较传统cocoapod有亲爹支持,又轻量的优点。我司在整体切换到xcframework后也开始转投Swift Package Manager的怀抱。

然而使用过程中我们发现CI在拉取依赖时会发生鉴权问题,这在Xcode健全的GUI界面下,本不应该是个棘手的问题,然而,在根据Apple官方文档中的描述我们发现,SPM的CI鉴权方式,Apple只提供了SSH和Xcode Server两条路子,(Xcode Server用的人太少,不在本文讨论范围)。也就是说如果我们使用Jenkins进行自动化构建,此时又使用了需要鉴权的SPM,若不巧又碰上因特殊原因SSH不能被CI机器访问,那么你就跟我一样遇到了一个尴尬的无法让Jenkins通过鉴权拉取SPM依赖的问题,如下图所示

鉴权失败

作出假设

在遇到该问题时,我们首先考虑的是事先将密码扔给Git,因为我们知道理论上,需要鉴权的Git仓库,在我们的每一次操作时都需要进行用户名和密码的鉴权,是Git工具缓存了我们的鉴权凭证,使得在我们的日常使用中,只需要在首次clone Git仓库的时候需要进行鉴权。也就是说,如果提前将需要鉴权的Git仓库的凭据设置到Git工具,让Git在每次拉取的时候自动把鉴权的用户名和密码填上,就能解决HTTP链接下Git仓库的鉴权问题,这TM不就是半小时的事情,Nice😏【事实上 这是个Flag】

疯狂踩坑

  1. 远程连接没有命令回显

使用SSH远程连接CI机器时,在终端执行git credential-osxkeychain相关指令是没有回显的,但实际上它已经执行成功了,所以千万不要在这种状态下执行git credential-osxkeychain get来查看保存的凭证,否则你会怀疑人生。

正确的做法是使用GUI工具如VNC或者Mac自带的屏幕共享工具连接CI机器,再到机器上打开终端执行指令。这样就能看到正确的回显以使得工作得以正常进行。

  1. 设置了凭据也验证设置成功了,Git命令行依然需要输入凭据

设置的凭据需要保证host路径、protocol协议与Git仓库高度一致,打错了即使能保存进去也是用不了的。

特别的,如果Git仓库路径上带端口,那么host需要写全域名和端口号,如

host=xxx.xxx.xxx:1234

  1. 钥匙串访问设置账号密码无效

直接在钥匙串访问上Git工具也是无法用来鉴权的,还是需要通过执行git credential-osxkeychain store来保存

  1. 把SPM放到工程仓库本地企图更改SPM cache路径

在Fastlane中可以使用cloned_source_packages_path参数将依赖放到工程中,然后再自定义SPM以来包路径,理论上可以实现使用工程文件夹下的SPM依赖包来进行编译,但实际上经过多次后尝试发现,它会报出一个invalid错误,如下图所示

SPM缓存失效

并且这样的操作把依赖拉到了工程目录下,违背了我们使用SPM减少cocoapods对项目工程的侵入这一初衷,所以不建议大家尝试,如果读者知道为何这个自定义的本地SPM路径不能正常编译欢迎评论或给我留言。

  1. 密码已成功配置,但Xcode自带的SPM获取不到鉴权信息

经过正确的设置后,我们已经可以直接用git clone指令拉取SPM依赖,而不需要输入鉴权信息了。但在xcode中使用其自带的包管理工具添加SPM依赖时,还是会提示输入鉴权信息,这是因为用xcode打开工程时,它默认使用了Xcode自带的Git来进行操作,读取的是它自己维护的鉴权信息,而我们保存的凭据是保存在了系统的Git工具上,Xcode GUI无法读取到,因为它是两个不同的Git,使用两套不同的鉴权信息。

成效初显

从前面的五个大坑里爬出来后,终于在命令行下使用git clone指令可以直接把Http的依赖库拉取到本地,而不需要再输入用户名和密码了。🌈🌈🌈

克隆成功

完美交差

经过一顿猛如虎的操作,终于在Jenkins的控台上出现了拉取SPM依赖成功的Log🫂

Jenkins拉取SPM依赖成功

步骤总结

  • 检查Mac启用的鉴权协助工具

使用命令git config -l | grep credential.helper查看,Mac是否使用了osxkeychain,如果没有请使用度娘将这里配置为osxkeychain

  • 设置xcodebuild/Fastlane使用CI机器的Git

由于xcode自带Git,默认xcodebuild命令使用的是xcode自带的Git,然而它并不会从系统的osxkeychain中获取鉴权信息。因此这里需要在xcodebuild命令后加上-scmProvider system,指定xcode使用CI机器的Git而不是xcode自带的。

如果CI使用Fastlane,则需要在gym里加上use_system_scm: true如:

gym(
      toolchain: "xxx",
      scheme: "#{SCHEME}",
      export_method: "#{EXPORT_METHOD}",
      configuration: option[:configuration],
      output_directory: "#{OUTPUT_DIRECTORY}",
      include_symbols: true,
      include_bitcode: false,
      xcargs: 'DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"',
      output_name: "#{IPA_NAME}",
      export_xcargs: "-allowProvisioningUpdates",
      use_system_scm: true
    )
  • 将Git凭据设置到CI机器

这里可以使用交互式命令git credential-osxkeychain store将Git凭据保存到CI机器,如:

$git credential-osxkeychain store
host=xxx.xxx.xxx:xxx
protocol=http
username=xxxx
password=xxxx

$git credential-osxkeychain get
host=xxx.xxx.xxx:xxx

>password=xxxx
>username=xxxx
注意:这里store的时候password=xxxx后面需要按两次回车,以确认前面的输入。同理,get的时候host=xxx.xxx.xxx:xxx后面也是需要两个回车,当看到命令行输出了正确的password和username即为保存成功。另外,如果这里Git仓库路径有端口号,请在host中输入带端口号、带全域名的url,不然会掉入前文所述的坑中,切记!

第一次操作credential-osxkeychain store时,可能会弹出Git读取Keychain的许可对话框,建议选择永远允许,并输入CI机器的管理员密码,之后执行所有Git操作时,需要读取Keychain中保存的凭据便不会再弹出对话框

如果这里想用CI命令保存用户名和密码,那么可以将下方信息保存到一个文件中,如Password

host=xxx.xxx.xxx:xxx
protocol=http
username=xxxx
password=xxxx

然后在对应路径执行cat Password | git credential-osxkeychain store即可

如果在使【Da】用【Gong】过程中发现除了上述坑点以外的大坑,或依照本指南无法完成CI和SPM的配置,欢迎与取得联系,我将给予一定的帮助,并把遗漏坑点补充到这篇指南中。再次感谢各位大佬对我【Da Gong Ren】的支持,期望本指南能为您节省宝贵的时间。

参考文献

  1. https://developer.apple.com/documentation/swift_packages/building_swift_packages_or_apps_that_use_them_in_continuous_integration_workflows
  2. https://blog.miniasp.com/post/2018/05/28/Git-Credential-Howto
  3. https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%87%AD%E8%AF%81%E5%AD%98%E5%82%A8
  4. https://uptech.team/blog/swift-package-manager
  5. https://docs.github.com/cn/github/using-git/caching-your-github-credentials-in-git
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容