工程实践

Swift 6.4 SwiftPM SBOM 怎么接入 macOS CI?2026

Swift 6.4 SwiftPM SBOM 怎么接入 macOS CI?2026

症状:流水线构建成功,却没有一份能追溯到该次构建的依赖清单。
最快解法:Swift 6.4 的 SwiftPM 已支持 SPDX 和 CycloneDX;要让 SBOM 尽量反映实际构建依赖,优先在 swift build 中生成,并将清单和构建标识一起归档。仅需包依赖图时,再考虑独立生成命令。

适合维护 Swift Package、iOS 或 macOS 项目的开发者、负责 Apple 平台 CI 的工程师,以及需要核验依赖清单交付范围的发布与安全负责人。若只想做漏洞扫描,或期待 SBOM 自动给出合规结论,这篇文章不能替代对应工具和审核流程。

最后更新于 2026 年 10 月 26 日;Swift 6.4 与 6.4.1 的发布信息、SBOM 命令及标志已对照 Swift 6.4 发布说明、Swift 6.4.1 发布公告和官方 SE-0509 提案核对。

里程碑一:先界定这份 SBOM 要描述什么

SBOM 是软件组件及依赖关系的清单,不是漏洞扫描结果,也不自动证明许可证合规或满足某项审计标准。接入前先确定交付对象:整个 Swift 包、其中一个产品,还是这次构建实际用到的依赖。范围选错,即使生成了结构有效的文件,也可能回答不了发布团队的问题。相关命令与依赖图边界以官方提案为准。

Swift 6.4 已将 SBOM 生成功能纳入 SwiftPM,支持 SPDX、CycloneDX;截至本文核对时,官方提案列出的对应规格是 SPDX 3.0 与 CycloneDX 1.7,输出为 JSON。Swift 6.4 于 2026 年 9 月 15 日发布;Swift 6.4.1 于 2026 年 10 月 13 日发布。团队应在实际 CI 工具链上确认可用功能,而不是仅凭本地电脑的版本推定流水线行为。

决策问题 建议做法 主要边界
要覆盖本次构建使用的依赖 在 swift build 中启用 SBOM,并使用 SwiftBuild 构建依赖图 需要在对应构建任务中生成;范围与该次构建有关
只需包依赖图,不能或不想再构建 使用 swift package generate-sbom 不运行构建,也不读取 SwiftBuild 构建依赖图
交付物属于某个产品 选产品级范围,并确认 CLI 支持的参数组合 不要误把产品清单当作整个仓库的包清单

若项目需要精确匹配流水线构建,构建命令通常比构建后独立生成更易建立对应关系。

里程碑二:检查工具链、工作目录与解析状态

先在目标 macOS CI 执行环境里核验 Swift 工具链。Swift 6.4.1 已发布,但持续集成使用的 Xcode、独立 Swift 工具链和 swift 命令未必来自同一安装位置。记录 swift --version、构建任务标识与提交标识,再检查当前目录确实包含预期的 Package.swift。可对照官方 macOS 工具链安装说明核对安装方式;正式接入前,还应在该环境直接查看命令帮助并试跑。

swift --version
pwd
ls
swift build --help
swift package generate-sbom --help

接着确认依赖解析文件与当前提交相符。Package.resolved 记录解析后的依赖版本;Swift 包作为 Apple 平台项目依赖时,该文件也可能位于 .xcodeproj 或 .xcworkspace 内。检查其路径并纳入版本控制,避免本地包根目录与 Xcode 工程中的锁定文件混为一谈。SwiftPM 的包管理器文档可用于核对包与依赖配置概念。

git status --short
swift package resolve
git status --short

如果解析命令改变了锁定文件,先查明变动来源,不要继续生成并把清单误标为原始构建的依赖记录。对独立 SBOM 子命令,还可使用 --disable-automatic-resolution,使解析文件过期时命令失败;这能减少生成时重新解析依赖造成的构建与清单错位。

注意:工作目录不对、锁定文件不匹配、构建后又发生依赖解析变化,都会让清单失去可追溯性。至少把提交 SHA、CI 任务标识、工具链版本和 Package.resolved 一起保留。

里程碑三:按范围选择生成命令和格式

SwiftPM 提供两条路径。构建命令可结合 SwiftBuild 的依赖图;独立子命令读取包依赖图,不会调用构建。若目标是产品或一次交付构建,优先从实际构建命令生成;若目标是包级依赖盘点,且无法再次构建,再使用独立子命令。

生成需求 命令示例 选择理由与注意事项
对整个包生成 CycloneDX,并结合 SwiftBuild 构建图 swift build --build-system swiftbuild --sbom-spec cyclonedx --sbom-output-dir artifacts/sbom 将清单生成绑定到构建;输出目录可纳入归档
对单个产品生成 SPDX swift build --build-system swiftbuild --product AppCore --sbom-spec spdx --sbom-output-dir artifacts/sbom 面向产品范围;不要与 --target 混用
构建后按包依赖图生成 CycloneDX swift package generate-sbom --disable-automatic-resolution --sbom-spec cyclonedx --sbom-output-dir artifacts/sbom 不再次构建;需接受它不使用 SwiftBuild 构建依赖图的边界

命令标志和示例以 SE-0509 及SwiftPM SwiftBuild 命令文档为准。独立生成命令会提示清单仅基于包图;而 swift build 使用 SBOM 标志时,默认生成失败会导致构建报错,可通过 --sbom-warning-only 改为警告。对必须随发布交付的清单,不宜无评估地降级为警告。

格式则按接收方的工具链和审计流程定。SwiftPM 当前支持的 JSON 输出版本可参考 CycloneDX 官方规格说明与 SPDX 官方规格列表;不要因为清单能生成,就假设接收方支持相同规格版本。

里程碑四:把生成与归档接入 macOS CI

在 CI 中,将生成步骤放在依赖已解析、目标构建完成的流程里,并明确输出目录。下面是供流水线脚本改造的命令序列,不绑定特定 CI 平台:

set -e
swift --version
swift build --build-system swiftbuild \
  --sbom-spec cyclonedx \
  --sbom-output-dir artifacts/sbom
ls -la artifacts/sbom

按项目发布策略决定生成失败是否阻断交付。若 SBOM 是发版必需品,保留默认失败即报错的行为;若只是观察性产物,才考虑把失败降为警告,并在流水线日志中显式记录。命令成功也不等于归档成功:CI 必须将 artifacts/sbom 作为构建产物上传或归档,并让清单与对应构建任务、提交标识关联。

先在目标工具链中复现上述流程,再将平台专属的产物上传语法加入现有流水线。需要远程操作 Mac 时,可先查看 NowMini 的连接方式说明;采用其他 macOS CI 环境的团队,也应将远程会话权限、凭证存放和归档权限纳入内部验收。

里程碑五:核验依赖范围与交付边界

生成后不能只看文件是否存在。先检查输出目录内是否有预期格式的 JSON,再核对 SBOM 中的根包或产品名称、依赖关系,以及解析文件里的依赖版本。对于发布给外部团队的清单,还应确认接收方要求的是包级信息还是产品级信息,并使用对应格式的验证器核验结构。

条件依赖尤其容易造成理解偏差。操作系统条件会在构建时评估,包依赖图本身不反映该次构建的条件筛选;SwiftBuild 构建图可以用于判断当前构建实际采用的依赖。换言之,独立子命令生成的包级清单,不能单独证明某个 macOS 构建包含或排除了哪些条件依赖。

在交付前逐项确认:

  • [ ] 在 CI 节点记录 swift --version,并确认它是预期工具链。
  • [ ] 确认工作目录、Package.swift 与 Package.resolved 属于本次构建。
  • [ ] 根据用途选择包级或产品级清单,并检查命令选项组合。
  • [ ] 若要求清单对应实际构建,使用 swift build 与 SwiftBuild 构建依赖图。
  • [ ] 检查 SBOM 的格式、根组件、依赖关系和输出目录。
  • [ ] 将清单、提交标识、任务标识及依赖解析文件一起归档。
  • [ ] 明确记录目标平台和生成路径,避免把包图结果解释为所有平台的实际构建结果。

SBOM 是组件清单,不自动证明没有漏洞、许可证义务已满足,或项目符合特定审计规范。它能为后续漏洞识别和许可证审查提供输入;结论仍取决于依赖数据、检测工具、适用规则与项目要求。

常见问题:接入前后的核对点

输出目录里找不到清单,是否说明 SBOM 功能不可用?
不一定。先确认 Swift 工具链版本和命令帮助,再核对运行时工作目录、输出路径及生成命令是否成功。对 swift build 而言,默认输出位置与显式指定目录不同;CI 还必须归档实际生成目录,而不是只归档应用二进制所在目录。

生成命令成功,能否直接视为依赖安全检查通过?
不能。SBOM 描述组件与依赖关系,本身不等同于漏洞扫描、许可证审查或完整合规证明。若发布流程要求这些判断,应将清单交给对应的扫描与审核步骤,并把其结果和适用策略分别保存。

完成接入后,macOS CI 的验收重点不是“命令跑通”,而是每份清单都能指向明确的构建、依赖解析状态和目标平台。若现有方案依赖临时本地机器、工具链版本不一致,或构建结果与归档分散在不同环境,就要额外处理可复现性和留存责任;稳定长期重负载或必须连接物理设备的工作,更适合评估自购 Mac。若只是阶段性 Apple 平台构建、验证或发布任务,不想先购置设备,可按项目工具链与持续构建方式评估 NowMini 的远程 Mac,并从远程 Mac 使用指南了解适用场景。

常见问题

SwiftPM 现在能输出哪些 SBOM 格式,生成命令怎么选?

Swift 6.4 起,SwiftPM 支持 SPDX 和 CycloneDX。若要让清单尽可能对应本次构建实际使用的依赖,应在 swift build 中启用 SBOM,并使用 SwiftBuild 构建依赖图;若只需描述已解析的包依赖,或不能再次运行构建,可使用 swift package generate-sbom。两种方法的覆盖范围不同,不能只按命令是否方便来选。

swift build 生成的清单和独立 SBOM 子命令有什么不同?

swift build 可结合 SwiftBuild 的构建依赖图,筛出该构建实际使用的依赖;若未启用 SwiftBuild,则只依据包依赖图并给出提示。独立子命令不会运行构建,也不使用 SwiftBuild 构建图,因此适合生成包级清单,但可能不能准确代表已交付构建。

如何让 SBOM 随 macOS CI 的构建结果一起留存?

在仓库根目录确认解析状态后,运行带 --sbom-output-dir 的生成命令,将输出写入仓库内明确的归档目录。随后检查目录中确有清单文件,并把该目录、Package.resolved、提交标识及构建任务标识一起交给 CI 的产物归档步骤。具体上传配置需按所用流水线平台编写,不能假定某个平台语法通用。

SwiftPM SBOM 会自动包含所有操作系统条件依赖吗?

不一定。独立子命令只读取包依赖图,而操作系统条件依赖是在构建时评估的。使用 SwiftBuild 构建图的构建命令,才可按该次构建计算出的依赖关系纳入或排除条目。因此,核验时要注明目标平台与构建方式;单看包级清单不能证明每个平台实际使用了完全相同的依赖。

延伸阅读

NowMini M4

用 NowMini 为 SwiftPM CI 准备稳定的 macOS 构建节点

租用独享的 M4 物理 Mac,在固定环境中生成并检查 SBOM,减少共享环境带来的构建差异。

立即租用云端 Mac