

# Using CodeArtifact with Swift
<a name="using-swift"></a>

These topics describe how to use the Swift Package Manager with CodeArtifact to install and publish Swift packages.

**Note**  
CodeArtifact supports Swift 5.8 and later and Xcode 14.3 and later.  
CodeArtifact recommends Swift 5.9 and later and Xcode 15 and later.

**Topics**
+ [Configure Swift with CodeArtifact](configure-swift.md)
+ [

# Consuming and publishing Swift packages
](swift-publish-consume.md)
+ [

# Swift package name and namespace normalization
](swift-name-normalization.md)
+ [

# Swift troubleshooting
](swift-troubleshooting.md)

# Configure the Swift Package Manager with CodeArtifact
<a name="configure-swift"></a>

To use the Swift Package Manager to publish packages to or consume packages from AWS CodeArtifact, you'll first need to set up credentials to access your CodeArtifact repository. The recommended method for configuring the Swift Package Manager CLI with your CodeArtifact credentials and repository endpoint is by using the `aws codeartifact login` command. You can also configure the Swift Package Manager manually.

## Configure Swift with the login command
<a name="configure-swift-login-command"></a>

Use the `aws codeartifact login` command to configure the Swift Package Manager with CodeArtifact.

**Note**  
To use the login command, Swift 5.8 or later is required and Swift 5.9 or later is recommended.

The `aws codeartifact login` command will do the following:

1. Fetch an authentication token from CodeArtifact and store it in your environment. How the credentials are stored depends on the operating system of the environment:

   1. **macOS:** An entry is created in the macOS Keychain application.

   1. **Linux and Windows:** An entry is created in the `~/.netrc` file.

   In all operating systems, if a credentials entry exists, this command replaces that entry with a new token.

1. Fetch your CodeArtifact repository endpoint URL and add it to your Swift configuration file. The command adds the repository endpoint URL to the project level configuration file located at `/path/to/project/.swiftpm/configuration/registries.json`.

**Note**  
The `aws codeartifact login` command calls `swift package-registry` commands that must be run from the directory that contains the `Package.swift` file. Because of this, `aws codeartifact login` command must be run from within the Swift project.

**To configure Swift with the login command**

1. Navigate to the Swift project directory that contains your project's `Package.swift` file.

1. Run the following `aws codeartifact login` command.

   If you are accessing a repository in a domain that you own, you don't need to include `--domain-owner`. For more information, see [Cross-account domains](domain-overview.md#domain-overview-cross-account).

   ```
   aws codeartifact login --tool swift --domain my_domain \
   --domain-owner 111122223333 --repository my_repo \
   [--namespace my_namespace]
   ```

The `--namespace` option configures the application to only consume packages from your CodeArtifact repository if they're in the designated namespace. [CodeArtifact namespaces](codeartifact-concepts.md#welcome-concepts-package-namespace) are synonymous with scopes, and are used to organize code into logical groups and to prevent name collisions that can occur when your code base includes multiple libraries.

The default authorization period after calling `login` is 12 hours, and `login` must be called to periodically refresh the token. For more information about the authorization token created with the `login` command, see [Tokens created with the `login` command](tokens-authentication.md#auth-token-login).

## Configure Swift without the login command
<a name="configure-swift-without-login-command"></a>

While it is recommended that you [configure Swift with the `aws codeartifact login` command](#configure-swift-login-command), you can also configure the Swift Package Manager without the login command by manually updating the Swift Package Manager configuration.

In the following procedure, you will use the AWS CLI to do the following:

1. Fetch an authentication token from CodeArtifact and store it in your environment. How the credentials are stored depends on the operating system of the environment:

   1. **macOS:** An entry is created in the macOS Keychain application.

   1. **Linux and Windows:** An entry is created in the `~/.netrc` file.

1. Fetch your CodeArtifact repository endpoint URL.

1. In the `~/.swiftpm/configuration/registries.json` configuration file, add an entry with your repository endpoint URL and authentication type.

**To configure the Swift without the login command**

1. In a command line, use the following command to fetch a CodeArtifact authorization token and store it in an environment variable.
   + Replace *my\$1domain* with your CodeArtifact domain name.
   + Replace *111122223333* with the AWS account ID of the owner of the domain. If you are accessing a repository in a domain that you own, you don't need to include `--domain-owner`. For more information, see [Cross-account domains](domain-overview.md#domain-overview-cross-account).

------
#### [ macOS and Linux ]

   ```
   export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain my_domain --domain-owner 111122223333 --query authorizationToken --output text`
   ```

------
#### [ Windows ]
   + Windows (using default command shell):

     ```
     for /f %i in ('aws codeartifact get-authorization-token --domain my_domain --domain-owner 111122223333 --query authorizationToken --output text') do set CODEARTIFACT_AUTH_TOKEN=%i
     ```
   + Windows PowerShell:

     ```
     $env:CODEARTIFACT_AUTH_TOKEN = aws codeartifact get-authorization-token --domain my_domain --domain-owner 111122223333 --query authorizationToken --output text
     ```

------

1. Get your CodeArtifact repository's endpoint by running the following command. Your repository endpoint is used to point the Swift Package Manager to your repository to consume or publish packages.
   + Replace *my\$1domain* with your CodeArtifact domain name.
   + Replace *111122223333* with the AWS account ID of the owner of the domain. If you are accessing a repository in a domain that you own, you don't need to include `--domain-owner`. For more information, see [Cross-account domains](domain-overview.md#domain-overview-cross-account).
   + Replace *my\$1repo* with your CodeArtifact repository name.

------
#### [ macOS and Linux ]

   ```
   export CODEARTIFACT_REPO=`aws codeartifact get-repository-endpoint --domain my_domain --domain-owner 111122223333 --repository my_repo --format swift --query repositoryEndpoint --output text`
   ```

------
#### [ Windows ]
   + Windows (using default command shell):

     ```
     for /f %i in ('aws codeartifact get-repository-endpoint --domain my_domain --domain-owner 111122223333 --repository my_repo --format swift --query repositoryEndpoint --output text') do set CODEARTIFACT_REPO=%i
     ```
   + Windows PowerShell:

     ```
     $env:CODEARTIFACT_REPO = aws codeartifact get-repository-endpoint --domain my_domain --domain-owner 111122223333 --repository my_repo --format swift --query repositoryEndpoint --output text
     ```

------

   The following URL is an example repository endpoint.

   ```
   https://my_domain-111122223333.d.codeartifact.us-west-2.amazonaws.com/swift/my_repo/
   ```
**Note**  
To use a dualstack endpoint, use the `codeartifact.region.on.aws` endpoint.
**Important**  
You must append `login` onto the end of the repository URL endpoint when used to configure the Swift Package Manager. This is done for you in the commands of this procedure.

1. With these two values stored in environment variables, pass them to Swift using the `swift package-registry login` command as follows:

------
#### [ macOS and Linux ]

   ```
   swift package-registry login ${CODEARTIFACT_REPO}login --token ${CODEARTIFACT_AUTH_TOKEN}
   ```

------
#### [ Windows ]
   + Windows (using default command shell):

     ```
     swift package-registry login %CODEARTIFACT_REPO%login --token %CODEARTIFACT_AUTH_TOKEN%
     ```
   + Windows PowerShell:

     ```
     swift package-registry login $Env:CODEARTIFACT_REPO+"login" --token $Env:CODEARTIFACT_AUTH_TOKEN
     ```

------

1. Next, update the package registry used by your application so that any dependency will be pulled from your CodeArtifact repository. This command must be run in the project directory where you are trying to resolve the package dependency:

------
#### [ macOS and Linux ]

   ```
   $ swift package-registry set ${CODEARTIFACT_REPO} [--scope my_scope]
   ```

------
#### [ Windows ]
   + Windows (using default command shell):

     ```
     $ swift package-registry set %CODEARTIFACT_REPO% [--scope my_scope]
     ```
   + Windows PowerShell:

     ```
     $ swift package-registry set $Env:CODEARTIFACT_REPO [--scope my_scope]
     ```

------

   The `--scope` option configures the application to only consume packages from your CodeArtifact repository if they're in the designated scope. Scopes are synonymous with [CodeArtifact namespaces](codeartifact-concepts.md#welcome-concepts-package-namespace), and are used to organize code into logical groups and to prevent name collisions that can occur when your code base includes multiple libraries.

1. You can confirm the configuration has been set up correctly by viewing the contents of the project level `.swiftpm/configuration/registries.json` file by running the following command in your project directory:

   ```
   $ cat .swiftpm/configuration/registries.json
   {
     "authentication" : {
   
     },
     "registries" : {
       "[default]" : {
         "url" : "https://my-domain-111122223333.d.codeartifact.us-west-2.amazonaws.com/swift/my-repo/"
       }
     },
     "version" : 1
   }
   ```

Now that you've configured the Swift Package Manager with your CodeArtifact repository, you can use it to publish and consume Swift packages to and from it. For more information, see [Consuming and publishing Swift packages](swift-publish-consume.md).

# Consuming and publishing Swift packages
<a name="swift-publish-consume"></a>

## Consuming Swift packages from CodeArtifact
<a name="consume-swift-packages"></a>

Use the following procedure to consume Swift packages from an AWS CodeArtifact repository.

**To consume Swift packages from a CodeArtifact repository**

1. If you haven't, follow the steps in [Configure the Swift Package Manager with CodeArtifact](configure-swift.md) to configure the Swift Package Manager to use your CodeArtifact repository with proper credentials.
**Note**  
The authorization token generated is valid for 12 hours. You will need to create a new one if 12 hours have passed since a token was created.

1. Edit the `Package.swift` file in your application project folder to update the package dependencies to be used by your project.

   1. If the `Package.swift` file does not contain a `dependencies` section, add one.

   1. In the `dependencies` section of the `Package.swift` file, add the package you want to use by adding its package identifier. The package identifier consists of the scope and package name separated by a period. See the code snippet following a later step for an example.
**Tip**  
To find the package identifier, you can use the CodeArtifact console. Find the specific package version you want to use and reference the **Install shortcut** instructions on the package version page.

   1. If the `Package.swift` file does not contain a `targets` section, add one.

   1. In the `targets` section, add the targets that will need to use the dependency.

      The following snippet is an example snippet showing configured `dependencies` and `targets` sections in a `Package.swift` file:

      ```
      ...
          ],
          dependencies: [
              .package(id: "my_scope.package_name", from: "1.0.0")
          ],
          targets: [
            .target(
               name: "MyApp",
               dependencies: ["package_name"]
            ),...
          ],
      ...
      ```

1. Now that everything is configured, use the following command to download the package dependencies from CodeArtifact.

   ```
   swift package resolve
   ```

## Consuming Swift packages from CodeArtifact in Xcode
<a name="consume-swift-packages-xcode"></a>

Use the following procedure to consume Swift packages from a CodeArtifact repository in Xcode.

**To consume Swift packages from a CodeArtifact repository in Xcode**

1. If you haven't, follow the steps in [Configure the Swift Package Manager with CodeArtifact](configure-swift.md) to configure the Swift Package Manager to use your CodeArtifact repository with proper credentials.
**Note**  
The authorization token generated is valid for 12 hours. You will need to create a new one if 12 hours have passed since a token was created.

1. Add the packages as a dependency in your project in Xcode.

   1. Choose **File > Add Packages**.

   1. Search for your package using the search bar. Your search must be in the form `package_scope.package_name`.

   1. Once found, choose the package and choose **Add Package**.

   1. Once the package is verified, choose the package products you want to add as a dependency, and choose **Add Package**.

If you run into problems using your CodeArtifact repository with Xcode, see [Swift troubleshooting](swift-troubleshooting.md) for common issues and possible fixes.

## Publishing Swift packages to CodeArtifact
<a name="publish-swift-packages"></a>

CodeArtifact recommends Swift 5.9 or later and using the `swift package-registry publish` command to publish Swift packages. If you are using an earlier version, you must use a Curl command to publish Swift packages to CodeArtifact.

### Publishing CodeArtifact packages with the `swift package-registry publish` command
<a name="publish-swift-packages-publish-command"></a>

Use the following procedure with Swift 5.9 or later to publish Swift packages to a CodeArtifact repository with the Swift Package Manager.

1. If you haven't, follow the steps in [Configure the Swift Package Manager with CodeArtifact](configure-swift.md) to configure the Swift Package Manager to use your CodeArtifact repository with proper credentials.
**Note**  
The authorization token generated is valid for 12 hours. You will need to create a new one if 12 hours have passed since it was created.

1. Navigate to the Swift project directory that contains the `Package.swift` file for your package.

1. Run the following `swift package-registry publish` command to publish the package. The command creates a package source archive and publishes it to your CodeArtifact repository.

   ```
   swift package-registry publish packageScope.packageName packageVersion
   ```

   For example:

   ```
   swift package-registry publish myScope.myPackage 1.0.0
   ```

1. You can confirm that the package was published and exists in the repository by checking in the console or using the `aws codeartifact list-packages` command as follows:

   ```
   aws codeartifact list-packages --domain my_domain --repository my_repo
   ```

   You can list the single version of the package using the `aws codeartifact list-package-versions` command as follows:

   ```
   aws codeartifact list-package-versions --domain my_domain --repository my_repo \
   --format swift --namespace my_scope --package package_name
   ```

### Publishing CodeArtifact packages with Curl
<a name="publish-swift-packages-curl"></a>

While it is recommended to use the `swift package-registry publish` command that comes with Swift 5.9 or later, you can also use Curl to publish Swift packages to CodeArtifact.

Use the following procedure to publish Swift packages to an AWS CodeArtifact repository with Curl.

1. If you haven't, create and update the `CODEARTIFACT_AUTH_TOKEN` and `CODEARTIFACT_REPO` environment variables by following the steps in [Configure the Swift Package Manager with CodeArtifact](configure-swift.md).
**Note**  
The authorization token is valid for 12 hours. You will need to refresh your `CODEARTIFACT_AUTH_TOKEN` environment variable with new credentials if 12 hours have passed since it was created.

1. First, if you do not have a Swift package created, you can do so by running the following commands:

   ```
   mkdir testDir && cd testDir
   swift package init
   git init .
   swift package archive-source
   ```

1. Use the following Curl command to publish your Swift package to CodeArtifact:

------
#### [ macOS and Linux ]

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

------
#### [ Windows ]

   ```
   curl -X PUT  --user "aws:%CODEARTIFACT_AUTH_TOKEN%" \
   -H "Accept: application/vnd.swift.registry.v1+json" \
   -F source-archive="@test_dir_package_name.zip" \
   "%CODEARTIFACT_REPO%my_scope/package_name/packageVersion"
   ```

------

1. You can confirm that the package was published and exists in the repository by checking in the console or using the `aws codeartifact list-packages` command as follows:

   ```
   aws codeartifact list-packages --domain my_domain --repository my_repo
   ```

   You can list the single version of the package using the `aws codeartifact list-package-versions` command as follows:

   ```
   aws codeartifact list-package-versions --domain my_domain --repository my_repo \
   --format swift --namespace my_scope --package package_name
   ```

## Fetching Swift packages from GitHub and republishing to CodeArtifact
<a name="publish-swift-packages-from-github"></a>

Use the following procedure to fetch a Swift package from GitHub and republish it to a CodeArtifact repository.

**To fetch a Swift package from GitHub and republish it to CodeArtifact**

1. If you haven't, follow the steps in [Configure the Swift Package Manager with CodeArtifact](configure-swift.md) to configure the Swift Package Manager to use your CodeArtifact repository with proper credentials.
**Note**  
The authorization token generated is valid for 12 hours. You will need to create a new one if 12 hours have passed since a token was created.

1. Clone the git repository of the Swift package you want to fetch and republish by using the following `git clone` command. For information about cloning GitHub repositories, see [Cloning a repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) in the GitHub Docs.

   ```
   git clone repoURL
   ```

1. Navigate to the repository that you just cloned:

   ```
   cd repoName
   ```

1. Create the package and publish it to CodeArtifact.

   1. **Recommended:** If you are using Swift 5.9 or later, you can use the following `swift package-registry publish` command to create the package and publish it to your configured CodeArtifact repository.

      ```
      swift package-registry publish packageScope.packageName versionNumber
      ```

      For example:

      ```
      swift package-registry publish myScope.myPackage 1.0.0
      ```

   1. If you're using a Swift version that is older than 5.9, you must use the `swift archive-source` command to create the package and then use a Curl command to publish it.

      1. If you haven't configured the `CODEARTIFACT_AUTH_TOKEN` and `CODEARTIFACT_REPO` environment variables, or it's been over 12 hours since you have, follow the steps in [Configure Swift without the login command](configure-swift.md#configure-swift-without-login-command).

      1. Create the Swift package by using the `swift package archive-source` command:

         ```
         swift package archive-source
         ```

         If successful, you will see `Created package_name.zip` in the command line.

      1. Use the following Curl command to publish the Swift package to CodeArtifact:

------
#### [ macOS and Linux ]

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

------
#### [ Windows ]

         ```
         curl -X PUT  --user "aws:%CODEARTIFACT_AUTH_TOKEN%" \
         -H "Accept: application/vnd.swift.registry.v1+json" \
         -F source-archive="@package_name.zip" \
         "%CODEARTIFACT_REPO%my_scope/package_name/packageVersion"
         ```

------

1. You can confirm that the package was published and exists in the repository by checking in the console or using the `aws codeartifact list-packages` command as follows:

   ```
   aws codeartifact list-packages --domain my_domain --repository my_repo
   ```

   You can list the single version of the package using the `aws codeartifact list-package-versions` command as follows:

   ```
   aws codeartifact list-package-versions --domain my_domain --repository my_repo \
   --format swift --namespace my_scope --package package_name
   ```

# Swift package name and namespace normalization
<a name="swift-name-normalization"></a>

CodeArtifact normalizes package names and namespaces before storing them, which means the names in CodeArtifact may be different than the ones provided when the package was published.

**Package name and namespace normalization: ** CodeArtifact normalizes Swift package names and namespaces by converting all letters to lowercase.

**Package version normalization: ** CodeArtifact does not normalize Swift package versions. Note that CodeArtifact only supports Semantic Versioning 2.0 version patterns, for more information about Semantic Versioning, see [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html).

The non-normalized package name and namespace can be used with API and CLI requests because CodeArtifact performs normalization on the inputs for those requests. For example, inputs of `--package myPackage` and `--namespace myScope` would be normalized and return a package that has a normalized package name of `mypackage` and namespace of `myscope`.

**You must use normalized names in ARNs, such as in IAM policies.**

To find the normalized name of a package, use the `aws codeartifact list-packages` command. For more information, see [List package names](list-packages.md).

# Swift troubleshooting
<a name="swift-troubleshooting"></a>

The following information might help you troubleshoot common issues with Swift and CodeArtifact.

## I'm getting a 401 error in Xcode even after configuring the Swift Package Manager
<a name="swift-troubleshooting-xcode"></a>

**Problem:** When you are trying to add a package from your CodeArtifact repository as a dependency to your Swift project in Xcode, you are getting a 401 unauthorized error even after you have followed the instructions for [connecting Swift to CodeArtifact](configure-swift.md).

**Possible fixes:** This can be caused by an issue with the macOS Keychain application, where your CodeArtifact credentials are stored. To fix this, we recommend opening the Keychain application and deleting all of the CodeArtifact entries and configuring the Swift Package Manager with your CodeArtifact repository again by following the instructions in [Configure the Swift Package Manager with CodeArtifact](configure-swift.md).

## Xcode hangs on CI machine due to keychain prompt for password
<a name="swift-troubleshooting-ci-machine"></a>

**Problem:** When you are trying to pull Swift packages from CodeArtifact as part of an Xcode build on a continuous integration (CI) server, such as with GitHub Actions, authentication with CodeArtifact can hang and eventually fail with an error message similar to the following:

`Failed to save credentials for \'https://my_domain-111122223333.d.codeartifact.us-west-2.amazonaws.com\' to keychain: status -60008`

**Possible fixes:** This is caused by credentials not being saved to the keychain on CI machines, and Xcode only supporting credentials saved in Keychain. To fix this, we recommend creating the keychain entry manually using the following steps:

1. Prepare the keychain.

   ```
   KEYCHAIN_PASSWORD=$(openssl rand -base64 20)
   KEYCHAIN_NAME=login.keychain
   SYSTEM_KEYCHAIN=/Library/Keychains/System.keychain
   
   if [ -f $HOME/Library/Keychains/"${KEYCHAIN_NAME}"-db ]; then
       echo "Deleting old ${KEYCHAIN_NAME} keychain"
       security delete-keychain "${KEYCHAIN_NAME}"
   fi
   echo "Create Keychain"
   security create-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"
   
   EXISTING_KEYCHAINS=( $( security list-keychains | sed -e 's/ *//' | tr '\n' ' ' | tr -d '"') )
   sudo security list-keychains -s "${KEYCHAIN_NAME}" "${EXISTING_KEYCHAINS[@]}"
   
   echo "New keychain search list :"
   security list-keychain 
   
   echo "Configure keychain : remove lock timeout"
   security unlock-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"
   security set-keychain-settings "${KEYCHAIN_NAME}"
   ```

1. Get a CodeArtifact authentication token and your repository endpoint.

   ```
   export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token \
                                       --region us-west-2 \
                                       --domain my_domain   \
                                       --domain-owner 111122223333   \
                                       --query authorizationToken  \
                                       --output text`
                                        
   export CODEARTIFACT_REPO=`aws codeartifact get-repository-endpoint  \
                                 --region us-west-2   \
                                 --domain my_domain   \
                                 --domain-owner 111122223333   \
                                 --format swift     \
                                 --repository my_repo    \
                                 --query repositoryEndpoint   \
                                 --output text`
   ```

1. Manually create the Keychain entry.

   ```
   SERVER=$(echo $CODEARTIFACT_REPO | sed  's/https:\/\///g' | sed 's/.com.*$/.com/g')
   AUTHORIZATION=(-T /usr/bin/security -T /usr/bin/codesign -T /usr/bin/xcodebuild -T /usr/bin/swift \
                  -T /Applications/Xcode-15.2.app/Contents/Developer/usr/bin/xcodebuild)
   
   security delete-internet-password -a token -s $SERVER -r htps "${KEYCHAIN_NAME}"
   
   security add-internet-password -a token \
                                  -s $SERVER \
                                  -w $CODEARTIFACT_AUTH_TOKEN \
                                  -r htps \
                                  -U \
                                  "${AUTHORIZATION[@]}" \
                                  "${KEYCHAIN_NAME}"
   
   security set-internet-password-partition-list \
                -a token \
                -s $SERVER \
                -S "com.apple.swift-package,com.apple.security,com.apple.dt.Xcode,apple-tool:,apple:,codesign" \
                -k "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"
   
   security find-internet-password   "${KEYCHAIN_NAME}"
   ```

For more information about this error and the solution, see [https://github.com/apple/swift-package-manager/issues/7236](https://github.com/apple/swift-package-manager/issues/7236).