# Rust and Cargo

> Use crates from a Telesphorepo Cargo registry in Rust builds, and what is different when you publish crates.

Source: https://docs.telesphorepo.com/cargo/

This page sets up Cargo to fetch crates from Telesphorepo. To publish a crate, see [Publish from a project](/publish-from-a-project/), under Publish your packages; what is different for Cargo is under [Publish to this repository](#publish-to-this-repository).

An admin first makes a repository with the format **Cargo (Rust)** (see [Make a repository](/repositories-and-access/#make-a-repository)). The examples use the server `repo.example.com` and a repository named `crates`, so the registry index is this:

```text
sparse+https://repo.example.com/cargo/crates/index/
```

Cargo 1.68 or later reads it. A private repository needs Cargo 1.74 or later. Put your own values in the blocks below. The **Use this repository** tab of the repository shows the same blocks with your values.

## Use crates

1. Name the registry in `.cargo/config.toml` of the project, or in `~/.cargo/config.toml` for every project.

   #### Your own crates, anyone can download

   ```toml title=".cargo/config.toml"
   [registries.crates]
   index = "sparse+https://repo.example.com/cargo/crates/index/"
   ```

   #### Your own crates, only signed-in people

   ```toml title=".cargo/config.toml"
   [registries.crates]
   index = "sparse+https://repo.example.com/cargo/crates/index/"
   credential-provider = "cargo:token"
   ```

   Cargo refuses a private registry that has no credential provider, so keep the `credential-provider` line.

   #### crates.io crates too, anyone can download

   ```toml title=".cargo/config.toml"
   [registries.crates]
   index = "sparse+https://repo.example.com/cargo/crates/index/"

   [source.crates-io]
   replace-with = "crates"
   ```

   Cargo then fetches every crate of crates.io through this repository.

   #### crates.io crates too, only signed-in people

   ```toml title=".cargo/config.toml"
   [registries.crates]
   index = "sparse+https://repo.example.com/cargo/crates/index/"
   credential-provider = "cargo:token"

   [source.crates-io]
   replace-with = "crates"
   ```

   Cargo then fetches every crate of crates.io through this repository. Cargo refuses a private registry that has no credential provider, so keep the `credential-provider` line.

2. Give Cargo a read token.

   #### Anyone can download

   Skip this step. Anyone can download.

   #### Only signed-in people

   **Settings** › **Tokens** › **New read token**. Type a name, then click **Create token**. Put the token in `~/.cargo/credentials.toml`:

   ```toml title="~/.cargo/credentials.toml"
   [registries.crates]
   token = "YOUR_READ_TOKEN"
   ```

   This file is in your home folder, not in the project. Do not commit it. In CI, set `CARGO_REGISTRIES_CRATES_TOKEN` to the token instead.

3. Add a crate.

   #### Your own crates

   ```sh
   cargo add acme-core@1.2.0 --registry crates
   ```

   Cargo writes the line into `Cargo.toml`:

   ```toml title="Cargo.toml"
   [dependencies]
   acme-core = { version = "1.2.0", registry = "crates" }
   ```

   #### crates.io crates too

   ```sh
   cargo add acme-core@1.2.0
   ```

   A crate of crates.io and a crate of your own both come through the repository, so the dependency needs no `registry`.

4. Build.

   ```sh
   cargo build
   ```

Done when Cargo prints `Finished`.

## Your own crates

A hosted repository holds your own crates only. The crates of crates.io still come from crates.io. To fetch every crate through one registry, ask your server admin for a group of your repository and a proxy of crates.io.

## crates.io crates too

A group asks its members in order. The first member that has a crate name owns it, and the group serves every version of that name from that member only. So a crate on crates.io with the name of your private crate cannot take its place, even with a higher version. Your admin puts your hosted repository before the proxy.

## Publish to this repository

Publish as in [Publish from a project](/publish-from-a-project/): run the setup line in the folder that holds `Cargo.toml`, commit `telesphorepo.toml`, then run `telesphorepo publish`. Done when Cargo prints `Published`.

The CLI runs `cargo publish` to the repository, with a publish token for this one repository. Cargo packs and checks the crate as usual. `Cargo.toml` and your Cargo config stay as they are, and no file holds the token.

A version that the repository has already, also with other build metadata, answers `409`. Raise the version. A name that differs from a crate of the repository only in case, or in `-` and `_`, answers `409` too, as on crates.io.

### The CI file for Cargo

[Publish from CI](/publish-from-ci/) has the steps. When you choose **GitHub Actions** at setup, the CLI writes this file:

```yaml title=".github/workflows/publish.yml"
on:
  push:
    branches: ["main"]

permissions:
  id-token: write
  contents: read

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: dtolnay/rust-toolchain@stable
      - run: curl -fsSL https://repo.example.com/install.sh | sh
      - run: telesphorepo publish
```

The identity token publishes only. If the build reads a private repository, keep a read token in a CI secret and set `CARGO_REGISTRIES_CRATES_TOKEN` to it. For Jenkins, see [Publish from CI](/publish-from-ci/).

## If something goes wrong

Cargo asks for a token, or says that the registry needs a credential provider

Add `credential-provider = "cargo:token"` under `[registries.crates]` in `.cargo/config.toml`, and check the token in `~/.cargo/credentials.toml`.

Cargo does not send the token

A private repository needs Cargo 1.74 or later. Run `rustup update`.

Cargo cannot find a crate of your repository

Without source replacement, the dependency needs `registry = "crates"`. Check the name of the registry in `.cargo/config.toml`.

A group serves your private crate, not the one on crates.io

The first member that has a name owns it. Rename your crate, or ask your admin to change the order of the members.

409 when you publish

That version is on the server, or another crate of the repository has nearly the same name. Raise the version, or rename the crate.

`cargo search` or `cargo owner` answers 404

The server does not serve them. Search on the repository page in the web UI. Your server admin gives **Publish** on the repository.

You want to yank a version

Make a publish token in **Settings** › **Tokens** › **New publish token**. Set `CARGO_REGISTRIES_CRATES_TOKEN` to it, then run `cargo yank acme-core@1.2.0 --registry crates`. Add `--undo` to take the yank back. A read token cannot yank.

The CLI says that cargo is not on the PATH

Install Rust 1.74 or later from <https://rustup.rs>.
