亚马逊AWS官方博客

新功能 — 将您的 Swift 包添加到 AWS CodeArtifact



即日起,为 Apple 平台( iOS iPadOS macOStvOSwatchOSVisionOS )或在服务器端运行的 Swift 应用程序编写代码的 Swift 开发人员可以使用 AWS CodeArtifact 安全地存储和检索其包依赖项。CodeArtifact 与 XcodexcodebuildSwift Package Managerswift package 命令)等标准开发人员工具集成。

简单的应用程序通常包含数十个包。大型企业应用程序可能有数百个依赖项。这些包提供可解决常见编程难题(例如网络访问、加密函数或数据格式操作)的代码,从而帮助开发人员加快开发和测试过程。开发人员还嵌入软件开发工具包(例如 AWS SDK),用于访问远程服务。这些包可能由组织中的其他团队制作或由第三方(例如开源项目)维护。管理包及其依赖项是软件开发过程不可或缺的一部分。现代编程语言包括下载和解析依赖项的工具:Java 中的 Maven、C# 中的 NuGet、JavaScript 中的 npmyarn 以及 Python 中的 pip 等等。Apple 平台的开发人员使用 CocoaPodsSwift Package Manager(SwiftPM)。

下载和集成包是应用程序开发人员的例行操作。但是,它给组织带来了至少两个重大挑战。

第一个挑战是法律方面的。组织必须确保第三方包的许可证与您的特定项目许可证的预期用途兼容,并且该包不会侵犯他人的知识产权(IP)。第二个挑战则是安全方面的。组织必须确保随附的代码可以安全使用,并且不包含意图在应用程序中引入安全漏洞的后门或故意漏洞。在热门开源项目中注入漏洞的方式被称为供应链攻击,近年来已变得越来越普遍。

为了应对这些挑战,组织通常在本地或云端安装私有包服务器。开发人员只能使用经过其组织安全和法律团队审查并通过私有存储库提供的包。

AWS CodeArtifact 是一项托管服务,您可以通过该服务安全地将包分发给内部开发人员团队。无需安装、管理或扩展底层基础设施。我们会为您处理这些工作,让您将更多时间投入在开发应用程序,而不是处理软件开发基础设施上。

我很高兴地宣布,除了 npmPyPIMavenNuGet通用包格式之外,CodeArtifact 现在还支持原生 Swift 包。Swift 包是打包和分发可重用 Swift 代码元素的热门方式。要学习如何创建您自己的 Swift 包,可以按照本教程的说明进行操作。社区还创建了 6000 多个 Swift 包,供您在 Swift 应用程序中使用。

您现在可以从 AWS Cloud 中的 CodeArtifact 存储库发布和下载 Swift 包依赖项。CodeArtifact SwiftPM 可与现有的开发人员工具配合使用,例如 XcodeVSCodeSwift Package Manager 命令行工具。将包存储在 CodeArtifact 中后,您可以在项目的 Package.swift 文件或 Xcode 项目中引用它们,就像使用 Git 端点访问公共 Swift 包一样。

配置完成后,您的网络监视构建系统将从 CodeArtifact 存储库下载包,从而确保在应用程序的构建过程中仅使用经过批准和受控的包。

如何开始使用
像往常一样,我将在这篇博客中向您介绍它的工作原理。想象一下,我正在开发一款使用 Amazon DynamoDB 作为数据库的 iOS 应用程序。我的应用程序嵌入了适用于 Swift 的 AWS SDK作为依赖项。为了遵守我所在组织的政策,该应用程序必须使用特定版本的适用于 Swift 的 AWS SDK,该版本由内部编译并经我所在组织的法律和安全团队批准。在此演示中,我将向您展示如何准备环境,将包上传到存储库,以及如何使用该特定包版本作为我的项目的依赖项。

对于本次演示,我将重点介绍特定于 Swift 包的步骤。您可以阅读我的同事 Steven 撰写的教程,了解如何开始使用 CodeArtifact

我使用的 AWS 账户已经配置了包存储库 MySwiftRepo)和stormacq-test)。

CodeArtifact 存储库

为了便于 SwiftPM 访问我的 CodeArtifact 存储库,我首先从 CodeArtifact 中收集身份验证令牌。

export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token \
                                     --domain stormacq-test              \
                                     --domain-owner 012345678912         \
                                     --query authorizationToken          \
                                     --output text`

请注意,身份验证令牌将在 12 小时后过期。我必须在 12 小时后重复此命令以获得新的令牌。

然后,我请求存储库端点。我传递了 domain 名和 domain owner(AWS 账户 ID)。请注意 --format swift 选项。

export CODEARTIFACT_REPO=`aws codeartifact get-repository-endpoint  \
                               --domain stormacq-test               \
                               --domain-owner 012345678912          \
                               --format swift                       \
                               --repository MySwiftRepo             \
                               --query repositoryEndpoint           \
                               --output text`

现在,我已经获得了存储库端点和身份验证令牌,接下来,我使用 AWS 命令行界面(AWS CLI) 在计算机上配置 SwiftPM。

SwiftPM 可以在用户级别(在文件 ~/.swiftpm/configurations 中),也可以在项目级别(在文件 <your project>/.swiftpm/configurations 中)存储存储库配置。默认情况下,CodeArtifact 登录命令会创建一个项目级别配置,允许您为不同的项目使用不同的 CodeArtifact 存储库。

我使用 AWS CLI 在我的构建计算机上配置 SwiftPM。

aws codeartifact login          \
    --tool swift                \
    --domain stormacq-test      \
    --repository MySwiftRepo    \
    --namespace aws             \
    --domain-owner 012345678912

该命令使用正确的选项调用 swift package-registry login,进而使用给定的存储库名称(MySwiftRepo)和作用域名称(aws)创建所需的 SwiftPM 配置文件。

现在,我的构建计算机已经准备就绪,我准备了组织批准的适用于 Swift 的 AWS SDK 版本,然后将其上传到存储库。

git clone https://github.com/awslabs/aws-sdk-swift.git
pushd aws-sdk-swift
swift package archive-source
mv aws-sdk-swift.zip ../aws-sdk-swift-0.24.0.zip
popd

最后,我将这个包版本上传到存储库。

在使用 Swift 5.9 或更高版本时,我可以使用 SwiftPM 命令将我的包上传到我的私有存储库:

swift package-registry publish           \
                       aws.aws-sdk-swift \
                       0.24.0            \
                       --verbose

5.9 之前的 Swift 版本不提供 swift package-registry publish 命令。所以,我改用了 curl 命令。

curl  -X PUT 
      --user "aws:$CODEARTIFACT_AUTH_TOKEN"               \
      -H "Accept: application/vnd.swift.registry.v1+json" \
      -F source-archive="@aws-sdk-swift-0.24.0.zip"       \
      "${CODEARTIFACT_REPO}aws/aws-sdk-swift/0.24.0"

请注意存储库 URI 后面的包名称的格式:<scope>/<package name>/<package version>。包版本必须遵循语义版本控制方案。

我可以使用 CLI 或控制台来验证包在存储库中是否可用。

CodeArtifact 列表包

aws codeartifact list-package-versions      \
                  --domain stormacq-test    \
                  --repository MySwiftRepo  \
                  --format swift            \
                  --namespace aws           \
                  --package aws-sdk-swift
{
    "versions": [
        {
            "version": "0.24.0",
            "revision": "6XB5O65J8J3jkTDZd8RMLyqz7XbxIg9IXpTudP7THbU=",
            "status": "Published",
            "origin": {
                "domainEntryPoint": {
                    "repositoryName": "MySwiftRepo"
                },
                "originType": "INTERNAL"
            }
        }
    ],
    "defaultDisplayVersion": "0.24.0",
    "format": "swift",
    "package": "aws-sdk-swift",
    "namespace": "aws"
}

现在该包已可用,我可以像往常一样在我的项目中使用它。

Xcode 使用我刚刚创建的 SwiftPM 工具和配置文件。为了将包添加到我的 Xcode 项目中,我在左侧窗格中选择项目名称,然后选择包依赖项选项卡。我可以看到已经成为我项目一部分的包。为了添加私有包,我选择 下的“+”符号。

Xcode 将包作为依赖项添加到项目中

在右上角的搜索字段中,我输入 aws.aws-sdk-swift (即 <作用域名称>.<包名称>)。一两秒钟后,包名称就会出现在列表中。在右上角,您可以验证源存储库(位于注册表选项卡旁边)。在选择添加包按钮之前,先选择包的版本,方法处理选择公开可用的包一样。

在 Xcode 上添加来自 CodeArtifactic 的私有包

或者,对于我的服务器端或命令行应用程序,我在 Package.swift 文件中添加依赖项。我还使用格式(<作用域>.<包名称>)作为 .package(id:from:) 函数的第一个参数。

    dependencies: [
        .package(id: "aws.aws-sdk-swift", from: "0.24.0")
    ],

当我键入 swift package update 时,SwiftPM 会从 CodeArtifact 存储库下载该包。

注意事项
在上传您的第一个 Swift 包之前,有几点需要注意。

  • 在尝试上述说明中显示的任何命令之前,请务必更新到最新版本的 CLI
  • 必须使用 Swift 5.8 或更高版本才能使用 CodeArtifact 和 swift package 命令。在 macOS 上,Swift 工具链附带 Xcode。Swift 5.8 已在 macOS 13(Ventura)和 Xcode 14 上提供。在 Linux 和 Windows 上,您可以从 swift.org 下载 Swift 工具链
  • 对于 iOS、iPadOS、tvOS 或 watchOS 应用程序,必须使用 Xcode 15。我使用 Xcode 15 beta8 进行了测试。
  • swift package-registry publish 命令适用于 Swift 5.9 或更新版本。当您使用 Swift 5.8 时,可以使用 curl 上传包,如我在演示中所示(或使用您选择的任何 HTTP 客户端)。
  • Swift 包具有作用域的概念。作用域为包存储库中的相关包提供命名空间。作用域映射到 CodeArtifact 命名空间
  • 身份验证令牌将在 12 小时后过期。我们建议编写脚本来自动续订或使用计划的 AWS Lambda 函数,并将令牌安全地存储在例如 AWS Secrets Manager 等位置。

故障排除
如果 Xcode 找不到您的私有包,请仔细检查 ~/.swiftpm/configurations/registries.json 中的注册表配置。特别要检查作用域名称是否存在。还要确认密钥链中是否存在身份验证令牌。条目的名称是存储库的 URL。您可以使用 /Application/Utilities/Keychain Access.app 应用程序或使用 security 命令行工具来验证密钥链中的条目。

security find-internet-password                                                  \
          -s "stormacq-test-012345678912.d.codeartifact.us-west-2.amazonaws.com" \
          -g

下面是我的计算机上的 SwiftPM 配置。

cat ~/.swiftpm/configuration/registries.json

{
  "authentication" : {
    "stormacq-test-012345678912.d.codeartifact.us-west-2.amazonaws.com" : {
      "loginAPIPath" : "/swift/MySwiftRepo/login",
      "type" : "token"
    }
  },
  "registries" : {
    "aws" : { // <-- this is the scope name!
      "url" : "https://stormacq-test-012345678912.d.codeartifact.us-west-2.amazonaws.com/swift/MySwiftRepo/"
    }
  },
  "version" : 1
}

用于 Codeartifact 身份验证令牌的密钥链项目

定价和可用性
Swift 包的 CodeArtifact 费用与已经获得支持的其他包格式的费用相同。CodeArtifact 账单取决于三个指标:存储空间(以每月 GB 为单位)、请求数量以及向互联网或其他 AWS 区域传输的数据。向同一区域的 AWS 服务传输数据不收费,这意味着您可以在 Amazon EC2 Mac 实例上运行 CICD 作业,而无需为 CodeArtifact 数据传输付费。与往常一样,定价页面包含详细信息。

适用于 Swift 的 CodeArtifact 包在所有 13 个提供 CodeArtifact 的区域提供。

立即构建您的 Swift 应用程序并将您的私有包上传到 CodeArtifact!

— seb

附言:您知道可以使用 Swift 编程语言编写 Lambda 函数吗? 请查看快速入门指南或按照这个 35 分钟的教程进行操作。