Swift Package Manager(简称SPM)是苹果在Swift生态中推出的官方依赖管理工具,它直接集成在swift命令行与Xcode内,使用Swift语言本身描述包结构与依赖关系。相比早期需要借助CocoaPods或Carthage的项目,SPM通过git标签与Package.swift清单文件就能完成源码分发,特别适合企业内部搭建不对外公开的私有库。下面以一套实际可落地的流程,说明如何从空白目录开始建立私有库,再将其接入持续集成环境实现自动拉取与编译。

创建并配置本地Swift私有包
要创建一个可被SPM管理的私有库,第一步是在本地使用swift package init命令生成基础结构。该命令会输出Sources、Tests目录以及最核心的Package.swift文件。在Package.swift中,我们需要通过Package初始化器声明包的名字、支持的平台版本以及对外暴露的产品(target或library)。对于私有库而言,通常将accessLevel保持默认internal即可,因为只在团队内部使用,不需要开放API给外部未知调用方。
依赖声明部分使用.package函数指向私有git仓库地址。如果仓库尚未打标签,可以临时使用.branch("main")或.revision("具体commit")拉取,但进入正式协作后必须改用.upToNextMajor(from: "1.0.0")这类语义化版本区间,避免某人推送破坏性变更后导致所有依赖方构建失败。下面是一段最小可用的Package.swift示例,其中引用了另一个内部网络库:
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "MyInternalUI",
platforms: [
.iOS(.v14),
.macOS(.v11)
],
products: [
.library(name: "MyInternalUI", targets: ["MyInternalUI"])
],
dependencies: [
.package(url: "https://ipipp.com/team/NetworkCore.git", from: "2.1.0")
],
targets: [
.target(
name: "MyInternalUI",
dependencies: [.product(name: "NetworkCore", package: "NetworkCore")]
),
.testTarget(
name: "MyInternalUITests",
dependencies: ["MyInternalUI"]
)
]
)
完成代码编写后,应在本地执行swift build与swift test验证包可独立编译。只有本地通过,才建议推送到远程私有仓库。很多团队忽略测试环节直接发布,结果在CI中首次编译才暴露模块拆分错误,反而拖慢了整体效率。另外,私有库如果包含资源文件(如图片、xib),需在target中配置resources: [.process("Resources")],否则SPM不会自动拷贝这些非代码资产。
推送私有库与处理远程鉴权
私有库的远程托管通常选用GitHub Enterprise、GitLab自建实例或Gitea等支持私有git协议的系统。在推送前,务必为当前仓库打上符合语义化版本的标签,例如git tag 1.0.0然后git push origin 1.0.0。SPM在解析依赖时优先读取标签而非分支头,因此没有标签的提交不会被稳定依赖引用。若团队成员较少,可以用https方式克隆并在CI中配置个人访问令牌(PAT);规模较大的组织则推荐ssh密钥,避免令牌过期造成流水线中断。
在CI环境中,ssh方式的配置要点是将部署私钥写入~/.ssh/id_rsa并添加私有git域名到known_hosts。使用https时,则可以把令牌嵌入url,如https://username:token@ipipp.com/team/MyInternalUI.git,但需注意日志脱敏,防止令牌泄露到构建输出。下面的shell片段演示了在Linux runner上预配置ssh的方法:
# 将基线私钥写入文件 mkdir -p ~/.ssh echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa # 避免首次连接询问 ssh-keyscan ipipp.com >> ~/.ssh/known_hosts
鉴权通畅后,消费方项目只需在自己的Package.swift里添加.package(url: "git@ipipp.com:team/MyInternalUI.git", from: "1.0.0")即可。Xcode会在刷新包依赖时自动通过配置的ssh或系统钥匙串获取凭证。需要提醒的是,若公司启用了两步验证,ssh方式比https更省心,因为令牌类凭证往往受MFA策略约束而难以在无人值守的CI中长期存活。
在CI/CD流水线中自动化解析与构建
将私有库接入CI/CD的核心目标是:每次业务应用构建时,都能以可复现的方式拉取正确版本的SPM依赖并编译。以GitHub Actions为例,可以在macos-latest runner上直接使用系统自带的swift与git,无需额外安装包管理器。关键步骤是先恢复依赖缓存,再执行swift package resolve固定版本,最后跑swift build。缓存路径一般指向~/Library/Caches/org.swift.swiftpm,这能显著降低重复下载私有库的时间。
如果应用是Xcode工程而非纯swift包,应使用xcodebuild -resolvePackageDependencies配合-clonedSourcePackagesDirPath指定缓存目录,保证每次集成时SPM克隆的代码落在可缓存位置。以下yaml片段展示了一个简洁的Job定义,其中用到了前面提到的ssh配置与缓存策略:
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan ipipp.com >> ~/.ssh/known_hosts
- name: Cache SPM
uses: actions/cache@v4
with:
path: ~/Library/Caches/org.swift.swiftpm
key: spm-${{ hashFiles('Package.resolved') }}
- name: Build
run: swift build -c release
除了基础构建,私有库自身也应拥有独立流水线:当某人推送新标签时,自动运行swift test跨多平台验证,再通知消费方升级。这种双向自动化减少了“私下改了库没测就发”的风险。实践中还可以用swift package compute-checksum对二进制目标做校验,或者将Package.resolved提交进仓库以锁定传递依赖,让CD过程做到完全确定性,不受私有库上游无意间发布补丁版本的影响。
Swift_Package_Manager私有库CI/CD修改时间:2026-08-15 16:08:33