New – Add Your Swift Packages to AWS CodeArtifact


Spoken by Polly

Start today, Fast Developers who write code for Apple platforms (iOS, iPadOS, Mac OS, tvOS, watchOSor visionOS) or for Swift Applications running on the server side Can use AWS CodeArtifact to securely store and retrieve their package dependencies. CodeArtifact integrates with standard developer tools, such as: Xcode, xcodebuildand that Swift package manager (The swift package Command).

Simple applications regularly include dozens of packages. Large enterprise applications can have hundreds of dependencies. These packages help developers speed up the development and testing process by providing code that solves common programming problems such as network access, cryptographic functions, or data format manipulation. Developers also embed SDKs-like that AWS SDKs–to access remote services. These packages can be created by other teams in your organization or maintained by third parties, such as open source projects. Managing packages and their dependencies is an integral part of the software development process. Modern programming languages ​​include tools for downloading and resolving dependencies: Maven in Java, NuGet in C#, npm or yarn in JavaScript and pip in Python, to name a few. Use developers for Apple platforms Cocoa pods or the Swift package manager (SwiftPM).

Downloading and integrating packages is a routine process for application developers. However, it presents companies with at least two major challenges.

The first challenge is legal. Organizations must ensure that licenses for third-party packages are compatible with the expected usage of licenses for your specific project and that the package does not infringe someone else’s intellectual property (IP). The second challenge is security. Companies must ensure that the included code is safe to use and does not contain backdoors or intentional vulnerabilities designed to introduce security holes in your app. Injecting vulnerabilities into popular open source projects is known as a Attack on the supply chain and has become increasingly popular in recent years.

To address these challenges, companies typically install private package servers on-premises or in the cloud. Developers can only use packages that have been reviewed by their organization’s security and legal teams and made available through private repositories.

AWS CodeArtifact is a managed service that allows you to securely distribute packages to your internal development teams. There is no need to install, manage, or scale the underlying infrastructure. We do it for you, giving you more time to work on your apps instead of on the software development infrastructure.

I’m happy to announce that CodeArtifact now supports native Swift packages in addition to npm, PyPI, Maven, NuGetAnd generic Package formats. Swift packages are a popular way to package and distribute reusable Swift code elements. To learn how to create your own Swift package, you can follow this tutorial. The community also created more than 6,000 Swift packages that you can use in your Swift applications.

You can now publish and download your Swift package dependencies from your CodeArtifact repository on the AWS Cloud. CodeArtifact SwiftPM works with existing developer tools like Xcode, VSCodeand that Swift Package Manager command line tool. After your packages are saved to CodeArtifact, you can reference them in your projects Package.swift File or in your Xcode project, similarly use Git endpoints to access public Swift packages.

After configuration is complete, your network-jailed build system downloads the packages from the CodeArtifact repository, ensuring that only approved and controlled packages are used during your application’s build process.

How to get started
As usual in this blog, I’ll show you how it works. Imagine I’m working on an iOS application that uses Amazon DynamoDB as a database. My application embeds this AWS SDK for Swift as a dependency. To comply with my organization’s policies, the application must use a specific version of the AWS SDK for Swift that has been assembled internally and approved by my organization’s legal and security teams. In this demo, I’ll show you how I prepare my environment, upload the package to the repository, and use this particular package build as a dependency for my project.

In this demo, I’ll focus on the specific steps for Swift packages. You can read the tutorial written by my colleague Steven to get you started with CodeArtifact.

I’m using an AWS account that includes a package Repository (MySwiftRepo) And domain (stormacq-test) already configured.

CodeArtifact repository

In order for SwiftPM to access my CodeArtifact repository, I first collect an authentication token from CodeArtifact.

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

Note that the authentication token expires after 12 hours. I need to repeat this command after 12 hours to get a new token.

Then I request the repository endpoint. I’ll hand this over domain name and domain owner (the AWS account ID). Note the --format swift Possibility.

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

Now that I have the repository endpoint and an authentication token, that’s what I’ll use AWS Command Line Interface (AWS CLI) to configure SwiftPM on my computer.

SwiftPM can store the repository configurations at User level (in the file ~/.swiftpm/configurations) or at Project level (in the file <your project>/.swiftpm/configurations). By default, the CodeArtifact login command creates a project-level configuration so that you can use different CodeArtifact repositories for different projects.

I use the AWS CLI to configure SwiftPM on my build machine.

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

The command calls swift package-registry login with the correct options, which in turn creates the required SwiftPM configuration files with the specified repository name (MySwiftRepo) and area name (aws).

Now that my build machine is ready, I prepare my organization’s approved version of the AWS SDK for Swift package and then upload it to the repository.

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

Finally, I upload this package version to the repository.

If I’m using Swift 5.9 or newer, I can upload my package to my private repository using the SwiftPM command:

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

Versions of Swift prior to 5.9 do not provide any swift package-registry publish Command. So I use that curl command instead.

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"

Note the format of the package name after the repository URI: <scope>/<package name>/<package version>. The package version must correspond to Semantic versioning to plan.

I can use the CLI or the console to check if the package is available in the repository.

CodeArtifact list packages

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"
}

Now that the package is available, I can use it in my projects as usual.

Xcode uses SwiftPM tools and configuration files that I just created. To add a package to my Xcode project, I select the project name in the left pane and then select the Package dependencies Tab. I can see the packages that are already part of my project. To add a private package, I select the + sign below Packages.

Xcode adds a package as a dependency to a project

I enter in the search field at the top right aws.aws-sdk-swift (that is <scope name>.<package name>). After a second or two, the package name will appear in the list. At the top right you can check the source repository (next to Registration Label). Before selecting the Add package Click the button and select the version of the package, just like you do with publicly available packages.

Add a private package from Codeartifact on Xcode

Alternatively, for my server-side or command-line applications, I add the im dependency Package.swift File. I also use the format (<scope>.<package name>) as the first parameter of .package(id:from:)Function.

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

When I type swift package updateSwiftPM downloads the package from the CodeArtifact repository.

things to know
Before you upload your first Swift packages, there are a few things you should keep in mind.

  • Be sure to update to the latest version of the CLI before trying any of the commands shown in the previous instructions.
  • You must be using Swift version 5.8 or newer to use CodeArtifact with the swift package Command. On macOS, the Swift toolchain ships with Xcode. Swift 5.8 is available for macOS 13 (Ventura) and Xcode 14. This is possible under Linux and Windows Download the Swift toolchain from Swift.org.
  • You must use Xcode 15 for your iOS, iPadOS, tvOS or watchOS applications. I tested this with Xcode 15 Beta8.
  • The swift package-registry publish The command is available with Swift 5.9 or later. If you are using Swift 5.8 you can use curlto upload your package as I showed in the demo (or use any HTTP client of your choice).
  • Swift packages have the concept of Scope. A scope provides a namespace for related packages within a package repository. Areas are assigned to CodeArtifact Namespaces.
  • The authentication token expires after 12 hours. We recommend writing a script to automate its renewal or use a planned AWS Lambda function and secure storage of the token AWS Secrets Manager (For example).

Troubleshooting
If Xcode cannot find your private package, double-check the registry configuration ~/.swiftpm/configurations/registries.json. In particular, check whether the scope name exists. Also make sure the authentication token is present in the keychain. The entry name is the URL of your repository. You can check the entries in the keychain with /Application/Utilities/Keychain Access.app Application or use of the security Command line tool.

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

Here is the SwiftPM configuration on my machine.

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
}

Code artifact authentication token keychain element

Prices and availability
The CodeArtifact cost for Swift packages is the same as the other package formats already supported. CodeArtifact billing depends on three metrics: storage (measured in GB per month), number of requests, and data transfer to the Internet or other AWS regions. Data transfer to AWS services in the same region is not charged, so you can run your CICD jobs on them Amazon EC2 Mac Instances without incurring a fee for CodeArtifact data transfer. As usual, the pricing page has the details.

CodeArtifact for Swift packages is available in all 13 regions where CodeArtifact is available.

Build your Swift applications and upload your private packages to CodeArtifact now!

— seb

PS: Did you know that you can write Lambda functions in the Swift programming language? Check the quick guide or follow this 35 minute tutorial.