本文 AI 產出,尚未審核

Rust 課程 – 專案管理與 Cargo

主題:發布到 crates.io


簡介

在 Rust 生態系統中,crates.io 是唯一官方的套件(crate)託管平台。把自己的程式庫發佈到 crates.io,不僅能讓其他開發者輕鬆取得、使用與回饋,還能提升個人或團隊的能見度與信譽。對於想要在開源社群留下足跡、或是希望未來的專案能透過 cargo add 快速整合的開發者而言,掌握正確的發布流程是必備技能。

本篇文章將從 Cargo 的基本設定說起,說明如何準備、測試、簽署與上傳 crate,並提供實作範例、常見陷阱與最佳實踐,協助你在 1500 左右的篇幅 內完成一次安全、可維護的發布。


核心概念

1. Cargo.toml 必備欄位

Cargo.toml 是 crate 的「身份證」與「說明書」。在發布前,必須確保以下欄位正確填寫:

欄位 說明 範例
name 套件名稱(全小寫、只能使用 -_ my-awesome-lib
version 依照 SemVer(MAJOR.MINOR.PATCH)規則更新 0.2.1
authors 作者資訊(可多筆) ["Alice <alice@example.com>"]
description 簡短說明,會顯示在 crates.io 搜尋結果 "一個用於字串處理的輕量函式庫"
license / license-file 授權條款,必須明確指出 "MIT OR Apache-2.0"
repository 原始碼倉庫 URL(GitHub、GitLab 等) "https://github.com/alice/my-awesome-lib"
homepage / documentation 相關說明文件的連結(可選) "https://docs.rs/my-awesome-lib"
readme README 檔案路徑,建議使用 README.md "README.md"
keywordscategories 讓使用者更容易搜尋 ["string", "utility"]["text-processing"]

重點license 必須是 SPDX 識別碼,且 不能留空,否則 crates.io 會拒絕上傳。

程式碼範例 1:完整的 Cargo.toml

[package]
name = "my-awesome-lib"
version = "0.2.1"
authors = ["Alice <alice@example.com>"]
edition = "2021"
description = "一個用於字串處理的輕量函式庫"
license = "MIT OR Apache-2.0"
repository = "https://github.com/alice/my-awesome-lib"
homepage = "https://github.com/alice/my-awesome-lib#readme"
documentation = "https://docs.rs/my-awesome-lib"
readme = "README.md"
keywords = ["string", "utility"]
categories = ["text-processing"]

2. 產生與管理 API 金鑰

發布到 crates.io 必須使用 API token(金鑰)驗證身分。流程如下:

  1. 前往 https://crates.io/me,登入後點擊 "New Token"
  2. 為金鑰命名(例如 ci-publish),並設定 只允許 publish 的權限。
  3. 複製金鑰,切勿在版本控制系統中暴露

在本機端,使用 cargo login <TOKEN> 把金鑰寫入 ~/.cargo/credentials,之後的 cargo publish 會自動使用。

程式碼範例 2:CI/CD 中使用金鑰(GitHub Actions)

name: Publish to crates.io
on:
  push:
    tags:
      - 'v*.*.*'   # 只在標記版號時觸發

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust toolchain
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          override: true
      - name: Publish crate
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish --token $CARGO_REGISTRY_TOKEN

小技巧:在 GitHub Secrets 中儲存金鑰,避免在日誌中洩漏。


3. 測試與檢查(cargo testcargo clippycargo fmt

在正式發布前,必須確保 crate 通過所有測試、Lint 與格式化。建議的 CI 步驟:

cargo fmt -- --check   # 確認程式碼格式
cargo clippy -- -D warnings   # 把所有警告視為錯誤
cargo test --all-features      # 執行所有測試

如果有 示範範例(examples),也要在 CI 中編譯:

cargo build --examples

程式碼範例 3:簡易測試範例

// src/lib.rs
/// 反轉字串的函式,支援 Unicode
pub fn reverse(s: &str) -> String {
    s.chars().rev().collect()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_reverse_ascii() {
        assert_eq!(reverse("hello"), "olleh");
    }

    #[test]
    fn test_reverse_unicode() {
        assert_eq!(reverse("你好世界"), "界世好你");
    }
}

4. cargo publish 的細節

參數 功能 範例
--dry-run 模擬發布,檢查是否有遺漏檔案或錯誤 cargo publish --dry-run
--allow-dirty 允許工作目錄有未提交變更(不建議在正式發布使用) cargo publish --allow-dirty
--no-verify 跳過測試與 lint(僅在特殊情況下使用) cargo publish --no-verify
--registry <NAME> 發布到自訂 registry(如私有) cargo publish --registry my-registry

最佳做法:先執行 cargo publish --dry-run,確定 Cargo.tomlREADME.mdLICENSE 等檔案皆在套件內,才正式執行 cargo publish

程式碼範例 4:自動化發布腳本(Bash)

#!/usr/bin/env bash
set -euo pipefail

# 1. 確認工作目錄乾淨
if [[ -n $(git status --porcelain) ]]; then
  echo "工作目錄有未提交的變更,請先 commit 或 stash。" >&2
  exit 1
fi

# 2. 執行檢查
cargo fmt -- --check
cargo clippy -- -D warnings
cargo test --all-features

# 3. 模擬發布
cargo publish --dry-run

# 4. 正式發布
cargo publish
echo "✅ 已成功發布至 crates.io"

5. 發布後的版本管理

  • 語意化版本(SemVer)

    • MAJOR:破壞相容性變更
    • MINOR:向下相容的新功能
    • PATCH:向下相容的 bug 修正
  • YANK:若發現嚴重錯誤,可使用 cargo yank 暫時隱藏特定版本,避免新專案依賴。

cargo yank --vers 0.2.1   # 隱藏 0.2.1 版
cargo yank --undo --vers 0.2.1   # 取消隱藏
  • RETRACT:在 Cargo.toml 中加入 [package.metadata] 讓舊版在 cargo search 時顯示「已撤回」訊息(Rust 1.71+ 支援)。

常見陷阱與最佳實踐

陷阱 為何會發生 解決方式
忘記更新 Cargo.lock(只在 binary crate) cargo publish 只會打包 src/,但 Cargo.lock 仍會被忽略,導致依賴版本不一致 不需要手動管理,只要在 library crate 中不放 Cargo.lock 即可
License 欄位空白或不符合 SPDX crates.io 會直接拒絕上傳 使用合法的 SPDX 識別碼,或提供 license-file
README 中的相對路徑失效 crates.io 會把 README 渲染成 HTML,若使用相對路徑會找不到檔案 使用絕對 URL(GitHub raw)或把圖片放在 docs/ 並在 Cargo.toml 指定 readme = "README.md"
發佈過於頻繁的 PATCH 版 版本號過於雜亂,使用者難以追蹤 遵循 SemVer,僅在必要時發布 PATCH
金鑰洩漏 CARGO_REGISTRY_TOKEN 放在公開 repo 中 永遠使用 CI secret,且 .gitignore 排除 ~/.cargo/credentials

最佳實踐總結

  1. CI/CD 完全自動化:測試 → Lint → Dry‑run → Publish。
  2. 使用 cargo-release 套件:自動 bump 版本、產生 git tag、執行 cargo publish
  3. README 中加入安裝指令cargo add my-awesome-lib,降低使用門檻。
  4. 維護 CHANGELOG:使用 keep-a-changelog 標準,讓使用者快速了解變更。

實際應用場景

場景 需求 如何利用 crates.io
內部工具庫 多個微服務共用相同的序列化/驗證函式 發佈為 私有 registry(或使用 cargo publish --registry
開源 CLI 提供 cargo install my-cli 一鍵安裝 把二進位 [[bin]] 加入 Cargo.toml,發布後使用者即可 cargo install
WebAssembly (wasm) 套件 前端需要呼叫 Rust 編寫的演算法 發佈 wasm-bindgen 包,配合 npmwasm-pack 發布流程
學術研究 公布實驗演算法與資料結構 Cargo.toml 中加入 documentation = "https://doi.org/...",讓引用更正式

案例serdereqwesttokio 都是透過 crates.io 讓全球開發者即時取得、升級與回報問題的典範。


總結

將 Rust 程式庫發布到 crates.io 不僅是技術上的里程碑,更是與開源社群互動的橋樑。本文從 Cargo.toml 必備欄位、API 金鑰管理測試與 Lint發布指令、到 版本管理常見陷阱,一步步說明了完整流程。只要遵循 SemVer、使用 CI/CD 自動化測試與發布,並妥善保護金鑰與授權資訊,你就能安全、快速地把自己的 crate 推向全球開發者。

祝你在 Rust 的開源旅程中,發佈順利、持續成長! 🚀