mcpField
R
rust-semver

rust-semver

github.com/full-stack-skills開発12106 回インストール5 週間前に更新
リポジトリ

rust-semver について

Rust crate のメンテナー向けリリース管理スキルです。SemVer の互換性や API の破壊的変更の確認に加え、公開、ワークスペースのリリース調整、バージョンの Yank、安全勧告への対応を扱います。

主な機能

  1. 01互換性と破壊的変更の分類
  2. 021.0 未満のバージョン規則の適用
  3. 03cargo-semver-checks の結果解釈
  4. 04ワークスペースのリリース調整
  5. 05Yank と安全勧告への対応

活用シーン

  1. 01crate のバージョン更新幅の決定
  2. 02公開前の API 変更確認
  3. 03複数 crate のワークスペース公開準備
  4. 04crate の脆弱性勧告への対応

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/full-stack-skills/rust-skills --skill rust-semver

インストール後、Claude Code で/rust-semverを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
examples/
workspace-publishing.md
examples/golden-semver/
Cargo.lock
Cargo.toml
examples/golden-semver/src/
lib.rs
references/
cargo-semver-checks-lints.md
semver-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. 特定のコード変更に必要なバージョンアップがメジャー、マイナー、パッチのどれかを判断する
  2. 1.0 より前のバージョン(0.x.y)に適用される特別なルールを理解する
  3. cargo-semver-checks(270 以上の lint)の実行と結果の解釈
  4. cargo-workspaces を使った複数クレートのワークスペースリリースの調整
  5. yank、非推奨化、RustSec アドバイザリーのワークフローへの対応
  6. #[non_exhaustive]、sealed trait、機能フラグ、非表示モジュールが Semver に与える影響の把握
  7. 変更の種類に合ったリリースノートの作成
⚠️ 前提条件
  1. 明確な公開 API を持つ Rust クレート — rust-api-design を参照
  2. Cargo マニフェストと cargo publish の基本 — rust-cargo-build を参照
❌ 対象外
  1. API 自体の設計 → rust-api-design
  2. Cargo マニフェスト形式とビルド設定 → rust-cargo-build
  3. Clippy の lint ルール → rust-style-clippy
  4. 動作を検証するためのテスト設計 → 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

各エラーはセマンティックバージョニング違反です。次のいずれかで対処してください。

  1. 項目を復元する(実際には削除しない)
  2. メジャーバージョンを上げる(破壊的変更であることを認める)
  3. 互換性シムを使用する(古い名前で再追加し、新しい名前に処理を委譲する)

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_missingimpl ブロックのメソッドが削除された復元するか、メジャーバージョンを上げる
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 は次の処理を行います。

  1. 各メンバーの Cargo.toml のバージョンを編集する
  2. 内部の path = "" 依存関係を新しいバージョンに更新する
  3. --no-individual-tags または --individual-tags を渡した場合、コミットとタグ付けを行う
  4. 依存関係の順序に従って公開する(依存先を依存元より先に公開)

公開済みバージョンを取り下げる

バージョンに重大なバグがある場合は、取り下げてください(新たな依存関係の追加を防ぎますが、既存の依存関係は削除しません)。

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

自分のクレートに関するアドバイザリーへの対応

  1. イシュートラッカーで確認したことを伝えます
  2. パッチを適用し、新しいバージョンを公開します
  3. 該当する場合は、RustSec にアドバイザリーを提出します:https://github.com/rustsec/advisory-db/
  4. 修正の公開後に、脆弱性のあるバージョンを取り下げます
  5. 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`

ツール:


ワークフロー

  1. 差分を確認する — 前回のリリース以降、pub 項目にどのような変更がありましたか?
  2. 各変更を分類する — 破壊的変更、追加、修正のいずれかです(パート 2 を参照)
  3. バージョン更新を決める — メジャー/マイナー/パッチを選びます。1.0 未満の場合のルールにも注意してください
  4. cargo-semver-checks を実行する — 分類がツールの判定と一致することを確認します
  5. CHANGELOG を更新する — 何が、なぜ変わったのか、移行に関する注記を記載します
  6. 品質チェックを実行する — fmt、test、clippy、doc
  7. 公開する — 単一クレート(cargo publish)またはワークスペース(cargo workspaces publish)
  8. 公開後の対応を行う — 問題があれば取り下げ、セキュリティ上の問題があればアドバイザリーを提出します

判断の早見表

変更バージョン更新注記
pub fn を追加マイナー追加的変更
バグを修正パッチ動作の変更。API の変更なし
pub fn を削除メジャーまたは復元して非推奨にする
シールドされたトレイトメソッドを追加マイナーシールド済みなら実装を制御できます
シールドされていないトレイトメソッドを追加メジャーまたはデフォルト実装を追加
enum バリアントを追加メジャー(#[non_exhaustive] の場合はマイナーも可)
pub 構造体フィールドを追加メジャー(#[non_exhaustive] または非公開の場合はマイナーも可)
MSRV を引き上げマイナー(最小バージョンが 1.0 以上の場合)方針を文書化してください
依存関係の semver メジャーバージョンを引き上げメジャー推移的な破壊的変更

リソース

上流の情報源

コメント