---
url: /en/artifact/conan.md
---
Conan Artifact Repository is a repository for storing and distributing C/C++ packages. It allows developers to upload, manage, and install various C/C++ third-party libraries and tools.

## Prerequisites

1. [Create Artifact Registry](./intro.md#creating-an-artifact-registry)
2. [Obtain Artifact Registry Address](./intro.md#obtaining-the-artifact-registry-address)
3. [Create Access Token](./intro.md#creating-an-access-token)

## Local Development

### Add a Remote and Login

```shell
# <REMOTE_NAME> is your chosen name for the remote
# <REPO_URL> is the URL of your repository
# Example: conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
conan remote add <REMOTE_NAME> <REPO_URL>

# Example: conan remote login -p my-token cnb-conan-repo cnb
conan remote login -p <YOUR_TOKEN> <REMOTE_NAME> cnb
```

### Pull Artifacts

```shell
# Example: conan download zlib/1.3.1 -r cnb-conan-repo
conan download <PACKAGE_NAME> -r <REMOTE_NAME>
```

### Build and Push Artifacts

```shell
# Create the package locally first
# Example 1: conan create . 
# Example 2: conan create . --user=test-user --channel=test-channel
conan create . --user=<USER> --channel=<CHANNEL>

# Upload the package to the remote
# Example 1: conan upload my-project/1.0.0 -r cnb-conan-repo (without user and channel)
# Example 2: conan upload my-project/1.0.0@test-user/test-channel -r cnb-conan-repo (with user and channel)
conan upload <PACKAGE_NAME> -r <REMOTE_NAME>
```

## Cloud Native Build

### Pull Artifacts

* Option 1: Using the built-in `CNB_TOKEN` environment variable:

```yaml title=".cnb.yml"
master:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      stages:
        - name: Configure Conan remote credentials
          script:
            # Example: conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
            - conan remote add <REMOTE_NAME> <REPO_URL>
            # Example: conan remote login -p ${CNB_TOKEN} cnb-conan-repo ${CNB_TOKEN_USER_NAME}
            - conan remote login -p ${CNB_TOKEN} <REMOTE_NAME> ${CNB_TOKEN_USER_NAME}
        - name: Download Conan package
          script:
            # Example: conan download zlib/1.3.1 -r cnb-conan-repo
            - conan download <PACKAGE_NAME> -r <REMOTE_NAME>
```

* Option 2: Use the secret repository file:

```yaml title=".cnb.yml"
master:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      import:
        # Import secret repository configuration file
        - <SECRET_REPO_URL>
      stages:
        - name: Configure Conan remote credentials
          script:
            - conan remote add <REMOTE_NAME> <REPO_URL>
            - conan remote login -p <PASS_WORD> <REMOTE_NAME> <USER_NAME>
        - name: Download Conan package
          script:
            - conan download <PACKAGE_NAME> -r <REMOTE_NAME>
```

Example:

```yaml title=".cnb.yml"
master:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      import:
        - https://cnb.share.ralphlauren.cn/cnb-demo/env-demo/-/blob/main/envs/env.yml
      stages:
        - name: Configure Conan remote credentials
          script:
            - conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
            # Import secret registry file and inject USER_NAME and PASS_WORD as environment variables
            - conan remote login -p ${PASS_WORD} cnb-conan-repo ${USER_NAME}
        - name: Download Conan package
          script:
            - conan download zlib/1.3.1 -r cnb-conan-repo
```

### Build and Push Artifacts

* Option 1: Using the built-in `CNB_TOKEN` environment variable:

```yaml title=".cnb.yml"
master:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      stages:
        - name: Configure Conan remote credentials
          script:
            # Example: conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
            - conan remote add <REMOTE_NAME> <REPO_URL>
            # Example: conan remote login -p ${CNB_TOKEN} cnb-conan-repo ${CNB_TOKEN_USER_NAME}
            - conan remote login -p ${CNB_TOKEN} <REMOTE_NAME> ${CNB_TOKEN_USER_NAME}
        - name: Build Conan package
          script:
             # Example: conan create . --user=test-user --channel=test-channel
            - conan create . --user=<USER> --channel=<CHANNEL>
        - name: Upload Conan package
          script:
            # Example: conan upload my-project/1.0.0@test-user/test-channel -r cnb-conan-repo
            - conan upload <PACKAGE_NAME> -r <REMOTE_NAME>
```

* Option 2: Use the secret repository file:

```yaml title=".cnb.yml"
master:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      import:
        # Import secret repository configuration file
        - <SECRET_REPO_URL>  
      stages:
        - name: Configure Conan remote credentials
          script:
            - conan remote add <REMOTE_NAME> <REPO_URL>
            - conan remote login -p <PASS_WORD> <REMOTE_NAME> <USER_NAME>
        - name: Build Conan package
          script:
            - conan create . --user=<USER> --channel=<CHANNEL>
        - name: Upload Conan package
          script:
            - conan upload <PACKAGE_NAME> -r <REMOTE_NAME>
```

Example:

```yaml title=".cnb.yml"
master:
  push:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      import:
        - https://cnb.share.ralphlauren.cn/cnb-demo/env-demo/-/blob/main/envs/env.yml  
      stages:
        - name: Configure Conan remote credentials
          script:
            - conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
            # The imported secret file injects USER_NAME and PASS_WORD as environment variables
            - conan remote login -p ${PASS_WORD} cnb-conan-repo ${USER_NAME}
        - name: Build Conan package
          script:
            - conan create . --user=test-user --channel=test-channel
        - name: Upload Conan package
          script:
            - conan upload my-project/1.0.0@test-user/test-channel -r cnb-conan-repo
```

## Workspaces

### Prerequisites

Add the following configuration to your `.cnb.yml` file:

```yaml title=".cnb.yml"
$:
  vscode:
    - docker:
        image: docker.cnb.cool/examples/language/gcc-13.4
      services:
        - vscode
        - docker
        # If using the secret repository file, fill in the following configuration  
      imports:
        # Example: https://cnb.share.ralphlauren.cn/cnb-demo/env-demo/-/blob/main/envs/env.yml
        - <SECRET_REPO_URL>
```

### Add a Remote and Login

* Option 1: Using the built-in `CNB_TOKEN` environment variable

```shell
# <REMOTE_NAME> is your chosen name for the remote
# <REPO_URL> is the URL of your repository
# Example: conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
conan remote add <REMOTE_NAME> <REPO_URL>

# Example: conan remote login -p ${CNB_TOKEN} cnb-conan-repo ${CNB_TOKEN_USER_NAME}
conan remote login -p ${CNB_TOKEN} <REMOTE_NAME> ${CNB_TOKEN_USER_NAME}
```

* Option 2: Use the secret repository file:

```shell
# <REMOTE_NAME> is your chosen name for the remote
# <REPO_URL> is the URL of your repository
# Example: conan remote add cnb-conan-repo https://conan.cnb.share.ralphlauren.cn/cnb/conan-repo/-/packages/
conan remote add <REMOTE_NAME> <REPO_URL>

# The imported secret file injects USER_NAME and PASS_WORD as environment variables
# Example: conan remote login -p ${PASS_WORD} cnb-conan-repo ${USER_NAME}
conan remote login -p ${PASS_WORD} <REMOTE_NAME> ${USER_NAME}
```

### Pull Artifacts

```shell
# Example: conan download zlib/1.3.1 -r cnb-conan-repo
conan download <PACKAGE_NAME> -r <REMOTE_NAME>
```

### Build and Push Artifacts

```shell
# Create the package locally first
# Example 1: conan create . 
# Example 2: conan create . --user=test-user --channel=test-channel
conan create . --user=<USER> --channel=<CHANNEL>

# Upload the package to the remote
# Example 1: conan upload my-project/1.0.0 -r cnb-conan-repo (without user and channel)
# Example 2: conan upload my-project/1.0.0@test-user/test-channel -r cnb-conan-repo (with user and channel)
conan upload <PACKAGE_NAME> -r <REMOTE_NAME>
```

## FAQ

### Q: Why can't I upload packages to the CNB Conan repository using Conan 1.x?

A: We do not support the legacy protocol of Conan 1.x. If you need to upload using Conan 1.x, you must first enable revisions by running the command `export CONAN_REVISIONS_ENABLED=True`, and then try uploading again.

### Q: Why do I get a 409 Conflict error when uploading?

A: Currently, we only support storing a single recipe revision and a single package revision per version. Pushing a different revision for an existing recipe or package is considered an "overwrite" operation. To resolve this, either change your repository's "Overwrite Policy" to "Allow Overwrites" or increment the version of your package before uploading.

### Q: Why do I get a 400 Bad Request error when uploading?

A: This usually happens when your package name does not conform to the Conan 2.x naming conventions. Please check and correct the package name before trying to upload again.

## More Information

For more advanced usage, please refer to the [official Conan documentation](https://docs.conan.io/).
