rust-semver について
Rust crate のメンテナー向けリリース管理スキルです。SemVer の互換性や API の破壊的変更の確認に加え、公開、ワークスペースのリリース調整、バージョンの Yank、安全勧告への対応を扱います。
主な機能
- 01互換性と破壊的変更の分類
- 021.0 未満のバージョン規則の適用
- 03cargo-semver-checks の結果解釈
- 04ワークスペースのリリース調整
- 05Yank と安全勧告への対応
活用シーン
- 01crate のバージョン更新幅の決定
- 02公開前の API 変更確認
- 03複数 crate のワークスペース公開準備
- 04crate の脆弱性勧告への対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ full-stack-skills/ rust-skills --skill rust-semverインストール後、Claude Code で/rust-semverを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlexamples/workspace-publishing.mdexamples/golden-semver/Cargo.lockCargo.tomlexamples/golden-semver/src/lib.rsreferences/cargo-semver-checks-lints.mdsemver-reference.md詳細
Rust の Semver とリリースワークフロー
権威ある情報源:Cargo Semver Reference、RFC 1105 (Semver)、cargo-semver-checks、RustSec Advisory Database。
このスキルは、Rust における破壊的変更に該当するものと該当しないもの、crates.io への公開ワークフロー、およびワークスペース全体のリリース調整を担当します。API の設計(rust-api-design)、Cargo マニフェストの仕組み(rust-cargo-build)、lint 設定(rust-style-clippy)は担当しません。
対応範囲
✅ 得意なこと
- 特定のコード変更に必要なバージョンアップがメジャー、マイナー、パッチのどれかを判断する
- 1.0 より前のバージョン(
0.x.y)に適用される特別なルールを理解する cargo-semver-checks(270 以上の lint)の実行と結果の解釈cargo-workspacesを使った複数クレートのワークスペースリリースの調整- yank、非推奨化、RustSec アドバイザリーのワークフローへの対応
#[non_exhaustive]、sealed trait、機能フラグ、非表示モジュールが Semver に与える影響の把握- 変更の種類に合ったリリースノートの作成
⚠️ 前提条件
- 明確な公開 API を持つ Rust クレート —
rust-api-designを参照 - Cargo マニフェストと
cargo publishの基本 —rust-cargo-buildを参照
❌ 対象外
- API 自体の設計 →
rust-api-design - Cargo マニフェスト形式とビルド設定 →
rust-cargo-build - Clippy の lint ルール →
rust-style-clippy - 動作を検証するためのテスト設計 →
rust-testing
データプライバシー
このスキルはユーザーデータを収集、保存、送信しません。crates.io への公開は公開操作です。cargo publish を実行する前に、ユーザーに確認してください。
Part 1: 公開 API とは?
Semver が適用されるのは公開 API の範囲です。Rust では、公開 API とは下流から見えるすべての要素ですが、その定義は少し複雑です。
可視アイテム
// src/lib.rs
pub fn hello() {} // public API
pub struct User { pub name: String } // public API
pub mod network { // public API
pub fn connect() {} // public API
}
mod internal { // private — NOT public API
pub fn helper() {} // pub, but module is private → not reachable
}
ルール:アイテムが公開 API となるのは、下流のクレートから unsafe を使わずに名前を指定できる場合に限ります。pub(crate) モジュール内の pub アイテムは、公開 API ではありません。
再エクスポートを通じた到達可能性
// src/lib.rs
mod hidden;
pub use hidden::Config; // Config IS public API (reachable via crate root)
hidden は非公開ですが、Config は再エクスポート経由で到達できるため、公開 API です。
非表示モジュール
#[doc(hidden)]
pub mod unstable { /* */ }
#[doc(hidden)] を付けても、Semver の観点ではアイテムは公開 API から除外されません。 下流からは引き続き use crate::unstable::Foo を使用できます。不安定な API として扱う場合は、機能フラグの背後に置くか、非公開モジュールに移してください。
機能フラグで条件付けられたアイテム
#[cfg(feature = "json")]
pub mod json; // public API only when feature enabled
Semver の契約は機能の組み合わせごとに適用されます。json が有効なユーザーにとって、json 配下へのアイテム追加はマイナーバージョンアップとなり、json を有効にしていないユーザーには影響しません。
Part 2: 破壊的変更と非破壊的変更
Cargo Book には標準的な変更の一覧が記載されています。概要:
常に破壊的(1.0 より前を除き、メジャーバージョンアップ)
| 変更 | 理由 |
|---|---|
| 公開アイテムを削除する | そのアイテムを参照している下流のコードが動作しなくなる |
| 公開アイテムの名前を変更する | 削除と追加を同時に行うのと同じ |
| 関数のシグネチャ(引数/戻り値の型)を変更する | 呼び出し側がコンパイルできなくなる |
#[non_exhaustive] でない enum に新しいバリアントを追加する | match にワイルドカードがない場合に問題が起きる |
| 公開 struct にフィールドを追加する | Foo にフィールドが追加されると、Foo { x: 1 } が動作しなくなる |
| 外部型に trait を実装する(またはその逆) | 下流の orphan 実装と競合する |
| trait 境界を厳しくする | 下流の実装が境界を満たさなくなる可能性がある |
pub アイテムを pub(crate) に変更する | API から削除される |
Copy/Clone/Debug の derive を削除する | 下流がそれらに依存している可能性がある |
| 公開依存関係の Semver を変更する | 推移的な依存先で問題が起きる可能性がある |
破壊的変更を含まない変更(マイナーまたはパッチのバージョンアップ)
| 変更 | 理由 |
|---|---|
| 新しい公開関数を追加する | 追加のみ |
| 独自の型に新しいトレイト実装を追加する | 追加のみ |
#[non_exhaustive] 列挙型にバリアントを追加する | 呼び出し側でワイルドカードを使用できる |
| 非公開フィールドを持つ構造体にフィールドを追加する | 呼び出し側は構造体リテラルを使用できない |
| 新しい機能フラグを追加する | 利用していないユーザーには見えない |
| トレイト境界を緩和する | より許容的になる |
| シールドされたトレイトにデフォルトメソッドを追加する | シールド済み = 実装を制御できる |
#[deprecated] で非推奨にする | 段階的な削除 |
注意が必要なケース
公開トレイトにメソッドを追加する
// Before
pub trait Foo { fn a(&self); }
// After
pub trait Foo { fn a(&self); fn b(&self); } // ❌ BREAKING
Foo の下流の実装は、b がないためコンパイルに失敗します。対処法:(a)メジャーバージョンを上げる、(b)メソッドを追加する前にトレイトをシールドする、または(c)b をデフォルトメソッドとして追加する(fn b(&self) {})。
シールドされていないトレイトにデフォルトメソッドを追加する
pub trait Foo { fn a(&self); fn b(&self) {} } // ✅ non-breaking
デフォルトメソッドは破壊的変更ではありません。ただし、後からデフォルトを削除すると、破壊的変更になります。
デフォルト値付きのジェネリックパラメーター
// Before
pub fn parse<T>(input: &str) -> T { /* */ }
// After
pub fn parse<T = String>(input: &str) -> T { /* */ } // ✅ non-breaking
ジェネリックにデフォルト値を追加することは破壊的変更ではありません。デフォルト値を削除すると、破壊的変更になります。
トレイトオブジェクトの安全性
現在 Foo がオブジェクト安全(Box<dyn Foo> が機能する)である場合、オブジェクト安全でなくなる変更(Self: Sized 境界の追加、ジェネリックメソッドの追加)は破壊的変更です。
ライフタイムの追加
// Before
pub fn parse(input: &str) -> &str { /* */ }
// After
pub fn parse<'a>(input: &'a str) -> &'a str { /* */ } // ✅ usually non-breaking
ライフタイム省略により、ほとんどのライフタイム変更は透過的です。
パート 3:1.0 より前(0.x.y)のルール
バージョン 0.x のクレートでは、変更されたセマンティックバージョニングに従います。
| バージョン | 互換性があるバージョン | 破壊的変更時に上げる番号 |
|---|---|---|
0.0.x | なし — 実験段階で、どのような変更も可能 | 0.0.x |
0.x.y(x > 0) | 同じ 0.x.* のみ | 「メジャー」に相当するマイナー(x)の位置 |
したがって、0.1.0 → 0.2.0 はメジャーバージョンアップです。0.1.0 → 0.1.1 はパッチ(バグ修正)です。
# Allowed in Cargo.toml:
[dependencies]
my-crate = "0.1" # means >=0.1.0, <0.2.0
1.0.0 に達すると、通常のセマンティックバージョニングに戻ります。
いつ 1.0 にするか
- API が安定している(今後約 6 か月、破壊的変更の予定がない)
- 他のクレートで使用されている(有用性の指標)
- 基本的な設計上の決定がすべて確定している
1.0 を恐れないでください。多くのクレートは、約束を負うことを恐れて 0.x のまま長くとどまっています。1.0 にするコストは、「破壊的変更にはメジャーバージョンアップが必要であると約束する」ことであり、通常は問題ありません。
パート 4:cargo-semver-checks
cargo-semver-checks は、クレートの現在の公開 API と公開済みバージョンを比較し、破壊的変更を検出するツールです。270 以上のリントで、ほとんどのケースをカバーします。
インストールと実行
cargo install cargo-semver-checks --locked
# Before publishing a new version:
cargo semver-checks check-release
# Compare against a specific baseline:
cargo semver-checks check-release --baseline-version 1.2.0
# Compare against a git tag:
cargo semver-checks check-release --baseline-tag v1.2.0
出力の解釈
--- failure function_missing ---
Description: Function removed or renamed, or return type changed.
Error: the function `parse` was removed from the API
各エラーはセマンティックバージョニング違反です。次のいずれかで対処してください。
- 項目を復元する(実際には削除しない)
- メジャーバージョンを上げる(破壊的変更であることを認める)
- 互換性シムを使用する(古い名前で再追加し、新しい名前に処理を委譲する)
CI との統合
# .github/workflows/semver.yml
name: Semver Check
on: [pull_request]
jobs:
semver:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: obi1kenobi/cargo-semver-checks-action@v2
破壊的変更を導入する PR は、適切にバージョンを上げない限り CI で失敗します。
よく検出されるリント
| リント | 意味 | 対処法 |
|---|---|---|
function_missing | 関数が削除または名前変更された | 復元するか、メジャーバージョンを上げる |
enum_variant_added | #[non_exhaustive] ではない列挙型にバリアントが追加された | #[non_exhaustive] を付ける |
struct_field_added | 公開構造体にフィールドが追加された | 非公開にするか、#[non_exhaustive] を付ける |
trait_method_added | シールドされていないトレイトにメソッドが追加された | デフォルトメソッドを追加するか、シールドする |
inherent_method_missing | impl ブロックのメソッドが削除された | 復元するか、メジャーバージョンを上げる |
type_marked_deprecated | #[deprecated] が追加された | 許容可能。マイナーバージョンを上げる |
パート 5:公開ワークフロー
単一クレートの公開
# 1. Bump version in Cargo.toml
# 2. Update CHANGELOG.md
# 3. Run quality gates
cargo fmt --all --check
cargo test --workspace --all-targets --all-features
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo semver-checks check-release
# 4. Verify package contents
cargo package --list # show files included
cargo package # build the .crate in target/package/
cargo publish --dry-run # full simulation
# 5. Publish
cargo publish # 🚨 public action — confirm with user first
cargo-workspaces によるワークスペースの一括公開
複数のクレートを含むワークスペースでは、cargo-workspaces がバージョンアップと公開の一連の作業を自動化します。
cargo install cargo-workspaces
# Bump all members together:
cargo workspaces version minor # 0.1.0 → 0.2.0 across all members
# Bump with custom prerelease:
cargo workspaces version prerelease --pre-id beta
# Publish all members in topological order:
cargo workspaces publish
cargo-workspaces は次の処理を行います。
- 各メンバーの
Cargo.tomlのバージョンを編集する - 内部の
path = ""依存関係を新しいバージョンに更新する --no-individual-tagsまたは--individual-tagsを渡した場合、コミットとタグ付けを行う- 依存関係の順序に従って公開する(依存先を依存元より先に公開)
公開済みバージョンを取り下げる
バージョンに重大なバグがある場合は、取り下げてください(新たな依存関係の追加を防ぎますが、既存の依存関係は削除しません)。
cargo yank --vers 1.2.3
# To undo:
cargo yank --vers 1.2.3 --undo
取り下げられたバージョンは、Cargo.lock で固定しているプロジェクト向けにレジストリに残ります。
クレートを非推奨にする
メンテナーのページから、crates.io 上でクレートを非推奨としてマークします。下流のユーザーは cargo add を実行したときに非推奨の通知を確認できます。
パート 6:RustSec アドバイザリー
RustSec Advisory Database は、公開済みクレートで確認されている脆弱性を追跡します。
cargo-audit
cargo install cargo-audit --locked
cargo audit # scan Cargo.lock against advisory DB
cargo audit --deny warnings # fail CI on any advisory
cargo-deny(より包括的)
cargo-deny は、以下を対象とします。
- advisories — RustSec
- licenses — 許可されていないライセンスを拒否
- bans — 特定のクレートを拒否
- sources — 特定の git/レジストリソースを拒否
# deny.toml
[advisories]
db-urls = ["https://github.com/rustsec/advisory-db"]
yanked = "deny"
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-3-Clause"]
confidence-threshold = 0.8
cargo install cargo-deny --locked
cargo deny check
自分のクレートに関するアドバイザリーへの対応
- イシュートラッカーで確認したことを伝えます
- パッチを適用し、新しいバージョンを公開します
- 該当する場合は、RustSec にアドバイザリーを提出します:https://github.com/rustsec/advisory-db/
- 修正の公開後に、脆弱性のあるバージョンを取り下げます
- CHANGELOG とリリースノートでユーザーに知らせます
パート 7:リリースノート
公開するたびに、CHANGELOG.md にエントリーを記載してください。推奨フォーマット:
## [1.2.0] - 2026-07-21
### Added
- `Client::builder()` for ergonomic construction (#45)
- `Visibility::IncludeHidden` variant
### Changed
- `parse()` now accepts `impl AsRef<str>` instead of `&str`
### Deprecated
- `Client::new()` — use `Client::builder()` instead
### Fixed
- Panic on empty input in `parse()` — now returns `Err`
ツール:
cargo-release— バージョン更新、タグ付け、公開を自動化しますrelease-plz— conventional commits から CHANGELOG を生成します- setuptools-changelog — 手動で作成します
ワークフロー
- 差分を確認する — 前回のリリース以降、
pub項目にどのような変更がありましたか? - 各変更を分類する — 破壊的変更、追加、修正のいずれかです(パート 2 を参照)
- バージョン更新を決める — メジャー/マイナー/パッチを選びます。1.0 未満の場合のルールにも注意してください
- cargo-semver-checks を実行する — 分類がツールの判定と一致することを確認します
- CHANGELOG を更新する — 何が、なぜ変わったのか、移行に関する注記を記載します
- 品質チェックを実行する — fmt、test、clippy、doc
- 公開する — 単一クレート(
cargo publish)またはワークスペース(cargo workspaces publish) - 公開後の対応を行う — 問題があれば取り下げ、セキュリティ上の問題があればアドバイザリーを提出します
判断の早見表
| 変更 | バージョン更新 | 注記 |
|---|---|---|
pub fn を追加 | マイナー | 追加的変更 |
| バグを修正 | パッチ | 動作の変更。API の変更なし |
pub fn を削除 | メジャー | または復元して非推奨にする |
| シールドされたトレイトメソッドを追加 | マイナー | シールド済みなら実装を制御できます |
| シールドされていないトレイトメソッドを追加 | メジャー | またはデフォルト実装を追加 |
| enum バリアントを追加 | メジャー(#[non_exhaustive] の場合はマイナーも可) | |
| pub 構造体フィールドを追加 | メジャー(#[non_exhaustive] または非公開の場合はマイナーも可) | |
| MSRV を引き上げ | マイナー(最小バージョンが 1.0 以上の場合) | 方針を文書化してください |
| 依存関係の semver メジャーバージョンを引き上げ | メジャー | 推移的な破壊的変更 |
リソース
- Semver Reference(完全版) — 変更項目の完全な一覧
- cargo-semver-checks Lint Catalog
- Workspace Publishing Cookbook —
cargo-workspacesのレシピ examples/golden-semver/— 破壊的でないバージョン更新を示すクレート