

# Working with upstream repositories in CodeArtifact
<a name="repos-upstream"></a>

A repository can have other AWS CodeArtifact repositories as *upstream* repositories. This enables a package manager client to access the packages that are contained in more than one repository using a single repository endpoint.

You can add one or more upstream repositories to an AWS CodeArtifact repository using the AWS Management Console, AWS CLI, or SDK. To associate a repository with an upstream repository, you must have permission for the `AssociateWithDownstreamRepository` action on the upstream repository. For more information, see [Create a repository with an upstream repository](create-repo.md#creating-a-repository-with-an-upstream) and [Add or remove upstream repositories](repo-upstream-add.md). 

If an upstream repository has an external connection to a public repository, the repositories that are downstream from it can pull packages from that public repository. For example, suppose that the repository `my_repo` has an upstream repository named `upstream`, and `upstream` has an external connection to a public npm repository. In this case, a package manager that is connected to `my_repo` can pull packages from the npm public repository. For more information about requesting packages from upstream repositories or external connections, see [Requesting a package version with upstream repositories](repo-upstream-behavior.md) or [Requesting packages from external connections](external-connection-requesting-packages.md).

**Topics**
+ [

## What's the difference between upstream repositories and external connections?
](#repos-external-connections)
+ [

# Add or remove upstream repositories
](repo-upstream-add.md)
+ [

# Connect a CodeArtifact repository to a public repository
](external-connection.md)
+ [

# Requesting a package version with upstream repositories
](repo-upstream-behavior.md)
+ [

# Requesting packages from external connections
](external-connection-requesting-packages.md)
+ [

# Upstream repository priority order
](repo-upstream-search-order.md)
+ [

# API behavior with upstream repositories
](upstream-repo-api-behavior.md)

## What's the difference between upstream repositories and external connections?
<a name="repos-external-connections"></a>

In CodeArtifact, upstream repositories and external connections behave mostly the same, but there are a few important differences.

1. You can add up to 10 upstream repositories to a CodeArtifact repository. You can only add one external connection.

1. There are separate API calls to add an upstream repository or an external connection.

1. The package retention behavior is slightly different, as packages requested from upstream repositories are retained in those repositories. For more information, see [Package retention in intermediate repositories](repo-upstream-behavior.md#package-retention-intermediate-repositories).

# Add or remove upstream repositories
<a name="repo-upstream-add"></a>

Follow the steps in the following sections to add or remove upstream repositories to or from an CodeArtifact repository. For more information about upstream repositories, see [Working with upstream repositories in CodeArtifact](repos-upstream.md).

This guide contains information about configuring other CodeArtifact repositories as upstream repositories. For information about configuring an external connection to public repositories like npmjs.com, Nuget Gallery, Maven Central, or PyPI, see [Add an external connection](https://docs.aws.amazon.com/codeartifact/latest/ug/external-connection.html).

## Add or remove upstream repositories (console)
<a name="repo-upstream-add-console"></a>

Perform the steps in the following procedure to add a repository as an upstream repository using the CodeArtifact console. For information about adding an upstream repository with the AWS CLI, see [Add or remove upstream repositories (AWS CLI)](#repo-upstream-add-cli).

**To add an upstream repository using the CodeArtifact console**

1. Open the AWS CodeArtifact console at [https://console.aws.amazon.com/codesuite/codeartifact/home](https://console.aws.amazon.com/codesuite/codeartifact/home).

1.  In the navigation pane, choose **Domains**, and then choose the domain name that contains your repository. 

1.  Choose the name of your repository.

1.  Choose **Edit**.

1.  In **Upstream repositories**, choose **Associate upstream repository** and add the repository you want to add as an upstream repository. You can only add repositories in the same domain as upstream repositories.

1.  Choose **Update repository**.

**To remove an upstream repository using the CodeArtifact console**

1. Open the AWS CodeArtifact console at [https://console.aws.amazon.com/codesuite/codeartifact/home](https://console.aws.amazon.com/codesuite/codeartifact/home).

1.  In the navigation pane, choose **Domains**, and then choose the domain name that contains your repository. 

1.  Choose the name of your repository.

1.  Choose **Edit**.

1.  In **Upstream repositories**, find the list entry of the upstream repository you want to remove and choose **Disassociate**.
**Important**  
Once you remove an upstream repository from a CodeArtifact repository, package managers will not have access to packages in the upstream repository or any of its upstream repositories.

1.  Choose **Update repository**.

## Add or remove upstream repositories (AWS CLI)
<a name="repo-upstream-add-cli"></a>

 You can add or remove a CodeArtifact repository's upstream repositories using the AWS Command Line Interface (AWS CLI). To do this, use the `update-repository` command, and specify the upstream repositories using the `--upstreams` parameter. 

You can only add repositories in the same domain as upstream repositories.

**To add upstream repositories (AWS CLI)**

1. If you haven't, follow the steps in [Setting up with AWS CodeArtifact](get-set-up-for-codeartifact.md) to set up and configure the AWS CLI with CodeArtifact.

1. Use the `aws codeartifact update-repository` command with the `--upstreams` flag to add upstream repositories.
**Note**  
Calling the `update-repository` command replaces the existing configured upstream repositories with the list of repositories provided with the `--upstreams` flag. If you want to add upstream repositories and keep the existing ones, you must include the existing upstream repositories in the call.

   The following example command adds two upstream repositories to a repository named `my_repo` that is in a domain named `my_domain`. The order of the upstream repositories in the `--upstreams` parameter determines their search priority when CodeArtifact requests a package from the `my_repo` repository. For more information, see [Upstream repository priority order](repo-upstream-search-order.md). 

   For information about connecting to public, external repositories such as npmjs.com or Maven Central, see [Connect a CodeArtifact repository to a public repository](external-connection.md).

   ```
   aws codeartifact update-repository \
      --repository my_repo \
      --domain my_domain \
      --domain-owner 111122223333 \
      --upstreams repositoryName=upstream-1 repositoryName=upstream-2
   ```

    The output contains the upstream repositories, as follows.

   ```
   {
          "repository": {
              "name": "my_repo",
              "administratorAccount": "123456789012",
              "domainName": "my_domain",
              "domainOwner": "111122223333",
              "arn": "arn:aws:codeartifact:us-east-2:111122223333:repository/my_domain/my_repo",
              "upstreams": [
                  {
                      "repositoryName": "upstream-1"
                  },
                  {
                      "repositoryName": "upstream-2"
                  }
              ],
              "externalConnections": []
          }
      }
   ```

**To remove an upstream repository (AWS CLI)**

1. If you haven't, follow the steps in [Setting up with AWS CodeArtifact](get-set-up-for-codeartifact.md) to set up and configure the AWS CLI with CodeArtifact.

1. To remove upstream repositories from a CodeArtifact repository, use the `update-repository` command with the `--upstreams` flag. The list of repositories provided to the command will be the new set of upstream repositories for the CodeArtifact repository. Include existing upstream repositories that you want to keep, and omit the upstream repositories you want to remove.

   To remove all upstream repositories from a repository, use the `update-repository` command and include `--upstreams` without an argument. The following removes upstream repositories from a repository named `my_repo` that is contained in a domain named `my_domain`.

   ```
   aws codeartifact update-repository \
      --repository my_repo \
      --domain my_domain \
      --domain-owner 111122223333 \
      --upstreams
   ```

    The output shows that the list of `upstreams` is empty.

   ```
   {
          "repository": {
              "name": "my_repo",
              "administratorAccount": "123456789012",
              "domainName": "my_domain",
              "domainOwner": "111122223333",
              "arn": "arn:aws:codeartifact:us-east-2:111122223333:repository/my_domain/my_repo",
              "upstreams": [],
              "externalConnections": []
          }
      }
   ```

# Connect a CodeArtifact repository to a public repository
<a name="external-connection"></a>

You can add a external connection between a CodeArtifact repository and an external, public repository such as [https://npmjs.com](https://npmjs.com) or the [Maven Central repository](https://repo.maven.apache.org/maven2/). Then, when you request a package from the CodeArtifact repository that's not already present in the repository, the package can be fetched from the external connection. This makes it possible to consume open-source dependencies used by your application.

In CodeArtifact, the intended way to use external connections is to have one repository per domain with an external connection to a given public repository. For example, if you want to connect to npmjs.com, configure one repository in your domain with an external connection to npmjs.com and configure all the other repositories with an upstream to it. This way, all the repositories can make use of the packages that have already been fetched from npmjs.com, rather than fetching and storing them again.

**Topics**
+ [

## Connect to an external repository (console)
](#adding-an-external-connection-console)
+ [

## Connect to an external repository (CLI)
](#adding-an-external-connection)
+ [

## Supported external connection repositories
](#supported-public-repositories)
+ [

## Remove an external connection (CLI)
](#removing-an-external-connection)

## Connect to an external repository (console)
<a name="adding-an-external-connection-console"></a>

When you use the console to add a connection to an external repository, the following will occur:

1. A `-store` repository for the external repository will be created in your CodeArtifact domain if one does not exist already. These `-store` repositories behave as intermediate repositories between your repository and the external repository and allow you to connect to more than one external repository.

1. The appropriate `-store` repository is added as an upstream to your repository.

The following list contains each `-store` repository in CodeArtifact and the respective external repository they connect to.

1. `cargo-store` is connected to crates.io.

1. `clojars-store` is connected to Clojars Repository.

1. `commonsware-store` is connected to CommonsWare Android Repository.

1. `google-android-store` is connected to Google Android.

1. `gradle-plugins-store` is connected to Gradle plugins.

1. `maven-central-store` is connected to Maven Central Repository.

1. `npm-store` is connected to npmjs.com.

1. `nuget-store` is connected to nuget.org.

1. `pypi-store` is connected to the Python Packaging Authority.

1. `rubygems-store` is connected to RubyGems.org.

**To connect to an external repository (console)**

1. Open the AWS CodeArtifact console at [https://console.aws.amazon.com/codesuite/codeartifact/home](https://console.aws.amazon.com/codesuite/codeartifact/home).

1.  In the navigation pane, choose **Domains**, and then choose the domain name that contains your repository. 

1.  Choose the name of your repository.

1.  Choose **Edit**.

1. In **Upstream repositories**, choose **Associate upstream repository** and add the appropriate `-store` repository that is connected as an upstream.

1.  Choose **Update repository**.

After the `-store` repository is added as an upstream repository, package managers connected to your CodeArtifact repository can fetch packages from the respective external repository.

## Connect to an external repository (CLI)
<a name="adding-an-external-connection"></a>

You can use the AWS CLI to connect your CodeArtifact repository to an external repository by adding an external connection directly to the repository. This will allow users connected to the CodeArtifact repository, or any of its downstream repositories, to fetch packages from the configured external repository. Each CodeArtifact repository can only have one external connection.

It is recommended to have one repository per domain with an external connection to a given public repository. To connect other repositories to the public repository, add the repository with the external connection as an upstream to them. If you or someone else in your domain has already configured external connections in the console, your domain likely already has a `-store` repository with an external connection to the public repository you want to connect to. For more information about `-store` repositories and connecting with the console, see [Connect to an external repository (console)](#adding-an-external-connection-console).

**To add an external connection to a CodeArtifact repository (CLI)**
+ Use `associate-external-connection` to add an external connection. The following example connects a repository to the npm public registry, npmjs.com. For a list of supported external repositories, see [Supported external connection repositories](#supported-public-repositories).

  ```
  aws codeartifact associate-external-connection --external-connection public:npmjs \
      --domain my_domain --domain-owner 111122223333 --repository my_repo
  ```

  Example output:

  ```
  {
      "repository": {
          "name": my_repo
          "administratorAccount": "123456789012",
          "domainName": "my_domain",
          "domainOwner": "111122223333",
          "arn": "arn:aws:codeartifact:us-west-2:111122223333:repository/my_domain/my_repo",
          "description": "A description of my_repo",
          "upstreams": [],
          "externalConnections": [
              {
                  "externalConnectionName": "public:npmjs",
                  "packageFormat": "npm",
                  "status": "AVAILABLE"
              }
          ]
      }
  }
  ```

After adding an external connection, see [Requesting packages from external connections](external-connection-requesting-packages.md) for information about requesting packages from an external repository with an external connection.

## Supported external connection repositories
<a name="supported-public-repositories"></a>

 CodeArtifact supports an external connection to the following public repositories. To use the CodeArtifact CLI to specify an external connection, use the value in the **Name** column for the `--external-connection` parameter when you run the `associate-external-connection` command. 


| Repository type | Description | Name | 
| --- | --- | --- | 
| Maven | Clojars repository | public:maven-clojars | 
| Maven | CommonsWare Android repository | public:maven-commonsware | 
| Maven | Google Android repository | public:maven-googleandroid | 
| Maven | Gradle plugins repository | public:maven-gradleplugins | 
| Maven | Maven Central | public:maven-central | 
| npm | npm public registry | public:npmjs | 
| NuGet | NuGet Gallery | public:nuget-org | 
| Python | Python Package Index | public:pypi | 
| Ruby | RubyGems.org | public:ruby-gems-org | 
| Rust | Crates.io | public:crates-io | 

## Remove an external connection (CLI)
<a name="removing-an-external-connection"></a>

To remove an external connection that was added by using the `associate-external-connection` command in the AWS CLI, use `disassociate-external-connection`.

```
aws codeartifact disassociate-external-connection --external-connection public:npmjs \
    --domain my_domain --domain-owner 111122223333 --repository my_repo
```

Example output:

```
{
    "repository": {
        "name": my_repo
        "administratorAccount": "123456789012",
        "domainName": "my_domain",
        "domainOwner": "111122223333",
        "arn": "arn:aws:codeartifact:us-west-2:111122223333:repository/my_domain/my_repo",
        "description": "A description of my_repo",
        "upstreams": [],
        "externalConnections": []
    }
}
```

# Requesting a package version with upstream repositories
<a name="repo-upstream-behavior"></a>

 When a client (for example, npm) requests a package version from a CodeArtifact repository named `my_repo` that has multiple upstream repositories, the following can occur: 
+  If `my_repo` contains the requested package version, it is returned to the client. 
+  If `my_repo` does not contain the requested package version, CodeArtifact looks for it in `my_repo`'s upstream repositories. If the package version is found, a reference to it is copied to `my_repo`, and the package version is returned to the client. 
+  If neither `my_repo` nor its upstream repositories contain the package version, an HTTP 404 `Not Found` response is returned to the client.

 When you add upstream repositories using the `create-repository` or `update-repository` command, the order they are passed to the `--upstreams` parameter determines their priority when a package version is requested. Specify upstream repositories with `--upstreams` in the order that you want CodeArtifact to use when a package version is requested. For more information, see [Upstream repository priority order](repo-upstream-search-order.md). 

 The maximum number of direct upstream repositories allowed for one repository is 10. Because direct upstream repositories can also have direct upstream repositories of their own, CodeArtifact can search more than 10 repositories for package versions. The maximum number of repositories CodeArtifact looks in when a package version is requested is 25. 

## Package retention from upstream repositories
<a name="package-retention-upstream-repos"></a>

 If a requested package version is found in an upstream repository, a reference to it is retained and is always available from the downstream repository. The retained package version is not affected by any of the following: 
+  Deleting the upstream repository. 
+  Disconnecting the upstream repository from the downstream repository. 
+  Deleting the package version from the upstream repository. 
+  Editing the package version in the upstream repository (for example, by adding a new asset to it). 

## Fetch packages through an upstream relationship
<a name="fetching-packages-through-an-upstream-relationship"></a>

If a CodeArtifact repository has an upstream relationship with a repository that has an external connection, requests for packages not in the upstream repository are copied from the external repository. For example, consider the following configuration: a repository named `repo-A` has an upstream repository named `repo-B`. `repo-B` has an external connection to [https://npmjs.com](https://npmjs.com).

![\[Simple upstream repository diagram showing three repositories chained together.\]](http://docs.aws.amazon.com/codeartifact/latest/ug/images/upstream-with-external.png)


If `npm` is configured to use the `repo-A` repository, running `npm install` triggers the copying of packages from [https://npmjs.com](https://npmjs.com) into `repo-B`. The versions installed are also pulled into `repo-A`. The following example installs `lodash`.

```
$ npm config get registry
https://my_domain-111122223333.d.codeartifact.us-west-2.amazonaws.com/npm/my-downstream-repo/
$ npm install lodash
+ lodash@4.17.20
added 1 package from 2 contributors in 6.933s
```

After running `npm install`, `repo-A` contains just the latest version (`lodash 4.17.20`) because that's the version that was fetched by `npm` from `repo-A`.

```
aws codeartifact list-package-versions --repository repo-A --domain my_domain \
            --domain-owner 111122223333 --format npm --package lodash
```

Example output:

```
{
    "package": "lodash",
    "format": "npm",
    "versions": [
        {
            "version": "4.17.15",
            "revision": "REVISION-1-SAMPLE-6C81EFF7DA55CC",
            "status": "Published"
        }
    ]
}
```

 Because `repo-B` has an external connection to [https://npmjs.com](https://npmjs.com), all the package versions that are imported from [https://npmjs.com](https://npmjs.com) are stored in `repo-B`. These package versions could have been fetched by any downstream repository with an upstream relationship to `repo-B`. 

The contents of `repo-B` provide a way to see all the packages and package versions imported from [https://npmjs.com](https://npmjs.com) over time. For example, to see all the versions of the `lodash` package imported over time, you can use `list-package-versions`, as follows.

```
aws codeartifact list-package-versions --repository repo-B --domain my_domain \
            --domain-owner 111122223333 --format npm --package lodash --max-results 5
```

Example output:

```
{
    "package": "lodash",
    "format": "npm",
    "versions": [
        {
            "version": "0.10.0",
            "revision": "REVISION-1-SAMPLE-6C81EFF7DA55CC",
            "status": "Published"
        },
        {
            "version": "0.2.2",
            "revision": "REVISION-2-SAMPLE-6C81EFF7DA55CC",
            "status": "Published"
        },
        {
            "version": "0.2.0",
            "revision": "REVISION-3-SAMPLE-6C81EFF7DA55CC",
            "status": "Published"
        },
        {
            "version": "0.2.1",
            "revision": "REVISION-4-SAMPLE-6C81EFF7DA55CC",
            "status": "Published"
        },
        {
            "version": "0.1.0",
            "revision": "REVISION-5-SAMPLE-6C81EFF7DA55CC",
            "status": "Published"
        }
    ],
    "nextToken": "eyJsaXN0UGFja2FnZVZlcnNpb25zVG9rZW4iOiIwLjIuMiJ9"
}
```

## Package retention in intermediate repositories
<a name="package-retention-intermediate-repositories"></a>

 CodeArtifact allows chaining upstream repositories. For example, `repo-A` can have `repo-B` as an upstream and `repo-B` can have `repo-C` as an upstream. This configuration makes the package versions in `repo-B` and `repo-C` available from `repo-A`. 

![\[Simple upstream repository diagram showing three repositories chained together.\]](http://docs.aws.amazon.com/codeartifact/latest/ug/images/upstream-chaining.png)


 When a package manager connects to repository `repo-A` and fetches a package version from repository `repo-C`, the package version will not be retained in repository `repo-B`. The package version will only be retained in the most-downstream repository, in this example, `repo-A`. It will not be retained in any intermediate repositories. This is also true for longer chains; for example if there were four repositories `repo-A`, `repo-B`, `repo-C`, and `repo-D` and a package manager connected to `repo-A` fetched a package version from `repo-D`, the package version would be retained in `repo-A` but not in `repo-B` or `repo-C`. 

 Package retention behavior is similar when pulling a package version from an external repository, except that the package version is always retained in the repository that has the external connection attached. For example, `repo-A` has `repo-B` as an upstream. `repo-B` has `repo-C` as an upstream, and `repo-C` also has **npmjs.com** configured as an external connection; see the followng diagram.

![\[Upstream repository diagram showing three repositories chained together with an external connection to npmjs.com.\]](http://docs.aws.amazon.com/codeartifact/latest/ug/images/upstream-chaining-external.png)


 If a package manager connected to `repo-A` requests a package version, *lodash 4.17.20* for example, and the package version is not present in any of the three repositories, it will be fetched from **npmjs.com**. When *lodash 4.17.20* is fetched, it will be retained in `repo-A` as that is the most-downstream repository and `repo-C` as it has the external connection to **npmjs.com** attached. *lodash 4.17.20* will not be retained in `repo-B` as that is an intermediate repository. 

# Requesting packages from external connections
<a name="external-connection-requesting-packages"></a>

The following sections describe how to request a package from an external connection and expected CodeArtifact behavior when requesting a package.

**Topics**
+ [

## Fetch packages from an external connection
](#fetching-packages-from-a-public-repository)
+ [

## External connection latency
](#external-connection-latency)
+ [

## CodeArtifact behavior when an external repository is not available
](#external-connection-unavailable)
+ [

## Availability of new package versions
](#new-pv-availability)
+ [

## Importing package versions with more than one asset
](#import-pv-multi-asset)

## Fetch packages from an external connection
<a name="fetching-packages-from-a-public-repository"></a>

To fetch packages from an external connection once you've added it to your CodeArtifact repository as described in [Connect a CodeArtifact repository to a public repository](external-connection.md), configure your package manager to use your repository and install the packages.

**Note**  
The following instructions use `npm`, to view configuration and usage instructions for other package types, see [Using CodeArtifact with Maven](using-maven.md), [Using CodeArtifact with NuGet](using-nuget.md), or [Using CodeArtifact with Python](using-python.md).

**To fetch packages from an external connection**

1. Configure and authenticate your package manager with your CodeArtifact repository. For `npm`, use the following `aws codeartifact login` command.

   ```
   aws codeartifact login --tool npm --domain my_domain --domain-owner 111122223333 --repository my_repo
   ```

1. Request the package from the public repository. For `npm`, use the following `npm install` command, replacing *lodash* with the package you want to install.

   ```
   npm install lodash
   ```

1. After the package has been copied into your CodeArtifact repository, you can use the `list-packages` and `list-package-versions` commands to view it.

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

   Example output:

   ```
   {
       "packages": [
           {
               "format": "npm",
               "package": "lodash"
           }
       ]
   }
   ```

   The `list-package-versions` command lists all versions of the package copied into your CodeArtifact repository.

   ```
   aws codeartifact list-package-versions --domain my_domain --domain-owner 111122223333 --repository my_repo --format npm --package lodash
   ```

   Example output:

   ```
   {
       "defaultDisplayVersion: "1.2.5"
       "format": "npm",
       "package": "lodash",
       "namespace": null,
       "versions": [
           {
               "version": "1.2.5", 
               "revision": "REVISION-1-SAMPLE-6C81EFF7DA55CC",
               "status": "Published"
           }
       ]
   }
   ```

## External connection latency
<a name="external-connection-latency"></a>

When fetching a package from a public repository using an external connection, there is a delay from when the package is fetched from the public repository and when it is stored in your CodeArtifact repository. For example, say you have installed version 1.2.5 of the npm package "lodash" as described in [Fetch packages from an external connection](#fetching-packages-from-a-public-repository). Although the `npm install lodash` lodash command completed successfully, the package version might not appear in your CodeArtifact repository yet. It typically takes around 3 minutes for the package version to appear in your repository, although occasionally it can take longer.

Because of this latency, you might have successfully retrieved a package version, but might not yet be able to see the version in your repository in the CodeArtifact console or when calling the ListPackages and ListPackageVersions API operations. Once CodeArtifact has asynchronously persisted the package version, it will be visible in the console and via API requests.

## CodeArtifact behavior when an external repository is not available
<a name="external-connection-unavailable"></a>

Occasionally, an external repository will experience an outage that means CodeArtifact cannot fetch packages from it, or fetching packages is much slower than normal. When this occurs, package versions already pulled from an external repository (e.g. **npmjs.com**) and stored in a CodeArtifact repository will continue to be available for download from CodeArtifact. However, packages that are not already stored in CodeArtifact may not be available, even when an external connection to that repository has been configured. For example, your CodeArtifact repository might contain the npm package version `lodash 4.17.19 ` because that's what you have been using in your application so far. When you want to upgrade to `4.17.20`, normally CodeArtifact will fetch that new version from **npmjs.com** and store it in your CodeArtifact repository. However, if **npmjs.com** is experiencing an outage this new version will not be available. The only workaround is to try again later once **npmjs.com** has recovered.

External repository outages can also affect publishing new package versions to CodeArtifact. In a repository with an external connection configured, CodeArtifact will not permit publishing a package version that is already present in the external repository. For more information, see [Packages overview](packages-overview.md). However, in rare cases, an external repository outage might mean that CodeArtifact does not have up-to-date information on which packages and package versions are present in an external repository. In this case, CodeArtifact might permit a package version to be published that it would normally deny.

## Availability of new package versions
<a name="new-pv-availability"></a>

 For a package version in a public repository such as npmjs.com to be available through a CodeArtifact repository, it must first be added to a Regional package metadata cache. This cache is maintained by CodeArtifact in each AWS Region and contains metadata that describes the contents of supported public repositories. Because of this cache, there is a delay between when a new package version is published to a public repository and when it is available from CodeArtifact. This delay varies by package type.

For npm, Python, and Nuget packages, there may be a delay of up to 30 minutes from when a new package version is published to npmjs.com, pypi.org, or nuget.org and when it is available for installation from a CodeArtifact repository. CodeArtifact automatically synchronizes metadata from these two repositories to ensure that the cache is up to date.

For Maven packages, there may be a delay of up to 3 hours from when a new package version is published to a public repository and when it is available for installation from a CodeArtifact repository. CodeArtifact will check for new versions of a package at most once every 3 hours. The first request for a given package name after the 3-hour cache lifetime has expired will cause all new versions of that package to be imported into the Regional cache.

For Maven packages in common use, new versions will typically be imported every 3 hours because the high rate of requests means that the cache will often be updated as soon as the cache lifetime has expired. For infrequently used packages, the cache will not have the latest version until a version of the package is requested from a CodeArtifact repository. On the first request, only previously imported versions will be available from CodeArtifact, but this request will cause the cache to be updated. On subsequent requests, the new versions of the package will be added to the cache and will be available for download.

## Importing package versions with more than one asset
<a name="import-pv-multi-asset"></a>

Both Maven and Python packages can have multiple assets per package version. This makes importing packages of these formats more complex than npm and NuGet packages, which only have one asset per package version. For descriptions of which assets are imported for these package types and how newly-added assets are made available, see [Requesting Python packages from upstreams and external connections](python-upstream-external-connections-request.md) and [Requesting Maven packages from upstreams and external connections](maven-upstream-external-connections-request.md).

# Upstream repository priority order
<a name="repo-upstream-search-order"></a>

 When you request a package version from a repository with one or more upstream repositories, their priority corresponds to the order that they were listed when calling the `create-repository` or `update-repository` command. When the requested package version is found, the search stops, even if it didn't search all upstream repositories. For more information, see [Add or remove upstream repositories (AWS CLI)](repo-upstream-add.md#repo-upstream-add-cli). 

 Use the `describe-repository` command to see the priority order.

```
aws codeartifact describe-repository --repository my_repo --domain my_domain --domain-owner 111122223333
```

 The result might be the following. It shows that the upstream repository priority is `upstream-1` first, `upstream-2` second, and `upstream-3` third. 

```
{
    "repository": {
        "name": "my_repo",
        "administratorAccount": "123456789012",
        "domainName": "my_domain",
        "domainOwner": "111122223333",
        "arn": "arn:aws:codeartifact:us-east-1:111122223333:repository/my_domain/my_repo",
        "description": "My new repository",
        "upstreams": [
            {
                "repositoryName": "upstream-1"
            },
            {
                "repositoryName": "upstream-2"
            },
            {
                "repositoryName": "upstream-3"
            }
        ],
        "externalConnections": []
    }
}
```

## Simple priority order example
<a name="upstream-priority-order-simple"></a>

 In the following diagram, the `my_repo` repository has three upstream repositories. The priority order of the upstream repositories is `upstream-1`, `upstream-2`, `upstream-3`. 

![\[Simple upstream repository diagram showing my_repo with 3 upstream repositories.\]](http://docs.aws.amazon.com/codeartifact/latest/ug/images/upstream-diagram-simple.png)


 A request for a package version in `my_repo` searches the repositories in the following order until it is found, or until an HTTP 404 `Not Found` response is returned to the client: 

1.  `my_repo` 

1.  `upstream-1` 

1.  `upstream-2` 

1.  `upstream-3` 

If the package version is found, the search stops, even if it didn't look in all upstream repositories. For example, if the package version is found in `upstream-1`, the search stops and CodeArtifact doesn't look in `upstream-2` or `upstream-3`. 

 When you use the AWS CLI command `list-package-versions` to list package versions in `my_repo`, it looks only in `my_repo`. It does not list package versions in upstream repositories. 

## Complex priority order example
<a name="upstream-search-order-complex"></a>

 If an upstream repository has its own upstream repositories, the same logic is used to find a package version before moving to the next upstream repository. For example, suppose that your `my_repo` repository has two upstream repositories, `A` and `B`. If repository `A` has upstream repositories, a request for a package version in `my_repo` first looks in `my_repo`, second in `A`, then in the upstream repositories of `A`, and so on. 

 In the following diagram, the `my_repo` repository contains upstream repositories. Upstream repository `A` has two upstream repositories, and `D` has one upstream repository. Upstream repositories at the same level in the diagram appear in their priority order, left to right (repository `A` has a higher priority order than repository `B`, and repository `C` has a higher priority order than repository `D`). 

![\[A more complex upstream repository diagram with 2 upstream repositories A and B and additional upstream repositories.\]](http://docs.aws.amazon.com/codeartifact/latest/ug/images/upstream-diagram-complex.png)


In this example, a request for a package version in `my_repo` looks in the repositories in the following order until it is found, or until a package manager returns an HTTP 404 `Not Found` response to the client: 

1.  `my_repo` 

1.  `A` 

1.  `C` 

1.  `D` 

1.  `E` 

1.  `B` 

# API behavior with upstream repositories
<a name="upstream-repo-api-behavior"></a>

 When you call certain CodeArtifact APIs on repositories that are connected to upstream repositories, the behavior may be different depending on if the packages or package versions are stored in the target repository or the upstream repository. The behavior of these APIs is documented here. 

For more information on CodeArtifact APIs, see the [CodeArtifact API Reference](https://docs.aws.amazon.com/codeartifact/latest/APIReference/Welcome.html).

Most APIs that reference a package or package version will return a `ResourceNotFound` error if the specified package version is not present in the target repository. This is true even if the package or package version is present in an upstream repository. Effectively, upstream repositories are ignored when calling these APIs. These APIs are:
+ DeletePackageVersions
+ DescribePackageVersion
+ GetPackageVersionAsset
+ GetPackageVersionReadme
+ ListPackages
+ ListPackageVersionAssets
+ ListPackageVersionDependencies
+ ListPackageVersions
+ UpdatePackageVersionsStatus

To demonstrate this behavior, we have two repositories: `target-repo` and `upstream-repo`. `target-repo` is empty and has `upstream-repo` configured as an upstream repository. `upstream-repo` contains the npm package `lodash`.

When calling the `DescribePackageVersion` API on `upstream-repo`, which contains the `lodash` package, we get the following output:

```
{
    "packageVersion": {
        "format": "npm",
        "packageName": "lodash",
        "displayName": "lodash",
        "version": "4.17.20",
        "summary": "Lodash modular utilities.",
        "homePage": "https://lodash.com/",
        "sourceCodeRepository": "https://github.com/lodash/lodash.git",
        "publishedTime": "2020-10-14T11:06:10.370000-04:00",
        "licenses": [
            {
                "name": "MIT"
            }
        ],
        "revision": "Ciqe5/9yicvkJT13b5/LdLpCyE6fqA7poa9qp+FilPs=",
        "status": "Published"
    }
```

When calling the same API on `target-repo`, which is empty but has `upstream-repo` configured as an upstream, we get the following output:

```
An error occurred (ResourceNotFoundException) when calling the DescribePackageVersion operation: 
Package not found in repository. RepoId: repo-id, Package = PackageCoordinate{packageType=npm, packageName=lodash},
```

 The `CopyPackageVersions` API behaves differently. By default, `CopyPackageVersions` API only copies package versions that are stored in the target repository. If a package version is stored in the upstream repository but not in the target repository, it will not be copied. To include package versions of packages that are stored only in the upstream repository, set the value of `includeFromUpstream` to `true` in your API request. 

For more information on the `CopyPackageVersions` API, see [Copy packages between repositories](copy-package.md).