블로그로 돌아가기

Rust 라이브러리를 crates.io에 배포하는 방법

Rust로 라이브러리를 만들었으면 crates.io에 배포해서 다른 사람들이 cargo add로 쓸 수 있게 해야겠죠. 처음 해보면 뭘 준비해야 하는지 헷갈리는데, 생각보다 간단합니다.

1. crates.io 계정 준비

crates.io에 GitHub 계정으로 로그인합니다. 그다음 Account Settings → API Tokens에서 토큰을 생성합니다.

터미널에서 로그인:

Bash
cargo login <YOUR_API_TOKEN>

한 번만 하면 됩니다. 토큰이 ~/.cargo/credentials.toml에 저장됩니다.

2. Cargo.toml 필수 필드

crates.io에 publish하려면 Cargo.toml에 최소한 이 필드들이 있어야 합니다:

TOML
[package]
name = "my-awesome-lib"
version = "0.1.0"
edition = "2024"
description = "한 줄 설명 (없으면 거부됨)"
license = "MIT OR Apache-2.0"
repository = "https://github.com/username/my-awesome-lib"
필드필수 여부설명
name필수crate 이름 (crates.io에서 유일해야 함)
version필수SemVer 형식
edition권장Rust 에디션 (2021, 2024 등)
description필수없으면 publish 거부됨
license필수SPDX 식별자 (MIT, Apache-2.0, MIT OR Apache-2.0)
repository권장GitHub URL
readme선택README 파일 경로 (기본: README.md)
keywords선택최대 5개, 검색에 도움
categories선택crates.io 카테고리

3. 라이선스 파일

Rust 생태계의 표준은 MIT + Apache 2.0 듀얼 라이선스입니다. 프로젝트 루트에 두 파일을 만듭니다:

  • LICENSE-MIT — MIT 라이선스 전문
  • LICENSE-APACHE — Apache 2.0 라이선스 전문

Cargo.toml에는:

TOML
license = "MIT OR Apache-2.0"

단일 라이선스를 쓰고 싶으면:

TOML
license = "MIT"
# 또는
license = "Apache-2.0"

4. README.md

crates.io 페이지에 표시됩니다. 최소한 이 내용은 넣으세요:

Markdown
# my-awesome-lib

한 줄 설명.

## 설치

\```toml
[dependencies]
my-awesome-lib = "0.1"
\```

## 사용법

\```rust
use my_awesome_lib::something;

fn main() {
    // 예제 코드
}
\```

## 라이선스

MIT OR Apache-2.0

5. 배포 전 검증

실제 publish 전에 dry-run으로 확인합니다:

Bash
cargo publish --dry-run

이 명령이 하는 것:

  1. 패키지 압축 (어떤 파일이 포함되는지 확인)
  2. 압축된 패키지로 빌드 테스트
  3. 실제 업로드는 하지 않음

문제가 있으면 여기서 에러가 나옵니다.

자주 나는 에러들

TEXT
error: `description` is missing
→ Cargo.toml에 description 추가

error: `license` is missing
→ Cargo.toml에 license 추가

error: package exceeds maximum size
→ .gitignore나 Cargo.toml의 [package] exclude로 불필요한 파일 제외

6. 실제 배포

Bash
cargo publish

끝입니다. 성공하면 이런 메시지가 나옵니다:

TEXT
Uploading my-awesome-lib v0.1.0
Uploaded my-awesome-lib v0.1.0 to registry `crates-io`
Published my-awesome-lib v0.1.0 at registry `crates-io`

이제 누구나 cargo add my-awesome-lib로 설치할 수 있습니다.

7. 워크스페이스에서 여러 crate 배포

여러 crate가 있는 워크스페이스에서는 의존성 순서대로 배포해야 합니다.

TEXT
my-core    → 의존성 없음 (1번)
my-render  → core에 의존 (2번)
my-lib     → core + render에 의존 (3번)
my-cli     → 전부 의존 (4번)

path + version 병기

로컬에서는 path로 참조하지만, crates.io에서는 version이 필요합니다. 둘 다 적으면 됩니다:

TOML
# Before (로컬 전용)
my-core = { path = "../my-core" }

# After (배포 가능)
my-core = { version = "0.1.0", path = "../my-core" }

이렇게 하면:

  • 로컬 빌드: path를 사용
  • crates.io에서 다운받은 사용자: version으로 resolve

배포 순서 실행

Bash
cargo publish -p my-core
# 1~2분 대기 (crates.io 인덱스 반영)
cargo publish -p my-render
cargo publish -p my-lib
cargo publish -p my-cli

-p 플래그로 특정 crate만 지정합니다. 각 단계 사이에 약간의 대기 시간이 필요한데, 이전 crate가 crates.io 인덱스에 반영되어야 다음 crate가 의존성을 찾을 수 있기 때문입니다.

Rate Limit 주의

crates.io는 단시간에 너무 많은 crate를 publish하면 429 에러를 반환합니다:

TEXT
error: Too Many Requests
Please try again after [시간]

5개 이상 연속으로 publish할 때는 사이에 1~2분씩 여유를 두세요.

8. 버전 업데이트

코드를 수정한 후 새 버전을 배포하려면:

  1. Cargo.tomlversion을 올린다
  2. 의존하는 다른 crate에서도 version을 맞춘다
  3. cargo publish
TOML
# 버그 수정: 0.1.0 → 0.1.1
# 기능 추가: 0.1.0 → 0.2.0
# 호환성 깨짐: 0.1.0 → 1.0.0
version = "0.1.1"

SemVer 규칙:

  • patch (0.1.0 → 0.1.1): 버그 수정, 호환성 유지
  • minor (0.1.0 → 0.2.0): 기능 추가, 하위 호환
  • major (0.x → 1.0): 호환성 깨지는 변경

9. 주의사항

  • 한 번 publish한 버전은 삭제할 수 없습니다. yank만 가능합니다 (신규 설치 차단, 기존 사용자는 계속 사용 가능)
  • crate 이름은 선점입니다. 먼저 등록한 사람이 소유자
  • 민감한 정보 (API 키, .env 등)를 포함하지 마세요. 한 번 올리면 되돌릴 수 없습니다
Bash
# 특정 버전 yank (신규 설치 차단)
cargo yank --version 0.1.0

# yank 해제
cargo yank --version 0.1.0 --undo

10. .gitignore / 패키지 제외

publish할 때 불필요한 파일이 포함되지 않도록:

TOML
# Cargo.toml
[package]
exclude = ["tests/fixtures/*", "benches/*", ".github/*"]

또는 반대로 포함할 파일만 지정:

TOML
[package]
include = ["src/**/*", "Cargo.toml", "LICENSE-*", "README.md"]

체크리스트

배포 전 최종 확인:

  • Cargo.toml에 name, version, description, license, repository 있는지
  • LICENSE 파일 존재하는지
  • README.md 있는지
  • cargo publish --dry-run 통과하는지
  • 민감한 정보가 포함되지 않았는지
  • 의존하는 crate가 이미 crates.io에 올라가 있는지 (워크스페이스)
  • path 의존성에 version이 병기되어 있는지 (워크스페이스)

이것만 확인하면 배포 준비 끝입니다.

댓글