Agent-almanac apply-semantic-versioning

install
source · Clone the upstream repo
git clone https://github.com/pjt222/agent-almanac
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/ja/skills/apply-semantic-versioning" ~/.claude/skills/pjt222-agent-almanac-apply-semantic-versioning-40ac37 && rm -rf "$T"
manifest: i18n/ja/skills/apply-semantic-versioning/SKILL.md
source content

セマンティックバージョニングの適用

最後のリリース以降の変更を分析して、正しいセマンティックバージョンバンプを決定し適用する。このスキルはバージョンファイルを読み、変更を破壊的(メジャー)、機能(マイナー)、修正(パッチ)に分類し、新しいバージョン番号を計算し、適切なファイルを更新する。SemVer 2.0.0仕様に従う。

使用タイミング

  • 新しいリリースを準備して正しいバージョン番号を決定する必要がある時
  • 一連の変更をマージした後、リリースをタグ付けする前
  • 変更が破壊的変更に該当するか評価する時
  • バージョンにプレリリース識別子(alpha、beta、rc)を追加する時
  • 適切なバージョンバンプについて意見が分かれた時

入力

  • 必須: バージョンファイル(DESCRIPTION、package.json、Cargo.toml、pyproject.toml、またはVERSION)を含むプロジェクトルートディレクトリ
  • 必須: 最後のリリース以降のGit履歴(タグまたはコミット)
  • 任意: 使用中のコミット規約(Conventional Commits、自由形式)
  • 任意: 適用するプレリリースラベル(alpha、beta、rc)
  • 任意: ファイルから読み取れない場合の前のバージョン

手順

ステップ1: 現在のバージョンを読み取る

プロジェクトルートでバージョンファイルを見つけて読み取る。

# R packages
grep "^Version:" DESCRIPTION

# Node.js
grep '"version"' package.json

# Rust
grep '^version' Cargo.toml

# Python
grep 'version' pyproject.toml

# Plain file
cat VERSION

現在のバージョンをmajor.minor.patchコンポーネントにパースする。バージョンにプレリリースサフィックス(例:

1.2.0-beta.1
)が含まれる場合、個別に記録する。

期待結果: 現在のバージョンが

MAJOR.MINOR.PATCH[-PRERELEASE]
として特定される。

失敗時: バージョンファイルが見つからない場合、VERSIONファイルまたはgitタグ(

git describe --tags --abbrev=0
)を確認する。バージョンが全く存在しない場合、初期開発には
0.1.0
、安定したパブリックAPIを持つプロジェクトには
1.0.0
から始める。

ステップ2: 最後のリリース以降の変更を分析する

最後にタグ付けされたリリース以降の変更リストを取得する。

# Find the last version tag
git describe --tags --abbrev=0

# List commits since that tag
git log --oneline v1.2.3..HEAD

# If using Conventional Commits, filter by type
git log --oneline v1.2.3..HEAD | grep -E "^[a-f0-9]+ (feat|fix|BREAKING)"

タグが存在しない場合、最初のコミットまたは既知のベースラインと比較する。

期待結果: 変更タイプ別に分類できるメッセージ付きのコミットリスト。

失敗時: git履歴が利用できないかタグが欠落している場合、開発者に変更を手動で説明してもらう。説明に基づいて分類する。

ステップ3: 変更を分類する

SemVer分類ルールを適用する:

変更タイプバージョンバンプ
破壊的(非互換APIの変更)MAJORパブリック関数の名前変更/削除、戻り値型の変更、パラメータの削除、デフォルト動作の変更
機能(後方互換の新機能)MINOR新しいエクスポート関数、デフォルト付き新パラメータ、新ファイル形式サポート
修正(後方互換のバグ修正)PATCHバグ修正、ドキュメント修正、同じAPIでのパフォーマンス改善

分類ルール:

  1. いずれかの変更が破壊的であれば、バンプはMAJOR(マイナーとパッチを0にリセット)
  2. 破壊的変更はないが新機能がある場合、バンプはMINOR(パッチを0にリセット)
  3. 修正のみの場合、バンプはPATCH

特殊ケース:

  • 1.0.0未満: 初期開発中(
    0.x.y
    )、マイナーバンプに破壊的変更が含まれる場合がある。明確にドキュメント化する。
  • 非推奨化: 関数を非推奨にするのはMINOR変更(まだ動作する)。削除するのがMAJOR。
  • 内部変更: パブリックAPIを変更しないリファクタリングはPATCH。

期待結果: 各変更が破壊的/機能/修正に分類され、全体的なバンプレベルが決定される。

失敗時: 変更が曖昧な場合、より高いバンプ側に倒す。控えめなメジャーバンプは、下流のコードを壊すマイナーバンプよりも良い。

ステップ4: 新しいバージョンを計算する

現在のバージョンにバンプを適用する:

現在バンプ新バージョン
1.2.3MAJOR2.0.0
1.2.3MINOR1.3.0
1.2.3PATCH1.2.4
0.9.5MINOR0.10.0
2.0.0-rc.1(リリース)2.0.0

プレリリースラベルが要求された場合:

  • 1.3.0-alpha.1
    次の1.3.0の最初のアルファ
  • 1.3.0-beta.1
    最初のベータ
  • 1.3.0-rc.1
    最初のリリース候補

プレリリースの優先順位:

alpha < beta < rc < (リリース)

期待結果: SemVerルールに従って計算された新しいバージョン番号。

失敗時: 現在のバージョンが不正な形式または非SemVerの場合、まず正規化する。例えば、

1.2
1.2.0
になる。

ステップ5: バージョンファイルを更新する

適切なファイルに新しいバージョンを書き込む。

# R: Update DESCRIPTION
# Change "Version: 1.2.3" to "Version: 1.3.0"
// Node.js: Update package.json
// Change "version": "1.2.3" to "version": "1.3.0"
// Also update package-lock.json if present
# Rust: Update Cargo.toml
# Change version = "1.2.3" to version = "1.3.0"

プロジェクトにバージョンを参照する複数のファイルがある場合(例:

_pkgdown.yml
CITATION
codemeta.json
)、すべて更新する。

期待結果: すべてのバージョンファイルが新しいバージョン番号に一貫して更新される。

失敗時: ファイル更新が失敗した場合、一貫性を維持するためにすべての変更を元に戻す。バージョンファイルを部分的に更新された状態のまま放置してはならない。

ステップ6: バージョンタグを作成する

バージョンバンプをコミットした後、gitタグを作成する。

# Annotated tag (preferred)
git tag -a v1.3.0 -m "Release v1.3.0"

# Lightweight tag (acceptable)
git tag v1.3.0

プロジェクトで確立されたタグ形式を使用する:

  • v1.3.0
    (最も一般的)
  • 1.3.0
    (プレフィックスなし)
  • package-name@1.3.0
    (モノレポ)

期待結果: 新しいバージョンに一致するGitタグが作成される。

失敗時: タグが既に存在する場合、バージョンが適切にバンプされていなかった。

git tag -l "v1.3*"
で重複タグを確認し、続行する前に解決する。

バリデーション

  • 現在のバージョンが正しいバージョンファイルから読み取られた
  • 最後のリリース以降のすべてのコミットが分析された
  • 各変更が破壊的、機能、修正に分類されている
  • バンプレベルが最も重大な変更に一致する(破壊的 > 機能 > 修正)
  • 新しいバージョンがSemVer 2.0.0形式に従う:
    MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]
  • プロジェクト内のすべてのバージョンファイルが一貫して更新されている
  • バージョンがスキップされていない(例: 1.3.0がリリースされずに1.2.3から1.4.0)
  • Gitタグが新しいバージョンとプロジェクトのタグ形式規約に一致する
  • プレリリースサフィックスが使用された場合、正しい優先順位に従っている(alpha < beta < rc)

よくある落とし穴

  • マイナーバージョンのスキップ: 「2つの機能を追加した」ため1.2.3から直接1.4.0にする。各リリースは1つのバンプを得る; 機能の数がバージョンを決定するのではない。
  • 非推奨化を破壊的として扱う: 関数を非推奨にする(警告を追加する)のはマイナー変更。削除することのみが破壊的変更である。
  • 1.0.0未満のルールの忘れ: 1.0.0の前はAPIが不安定と見なされる。一部のプロジェクトはこのフェーズで破壊的変更にマイナーバンプを使用するが、ドキュメント化すべきである。
  • 一貫性のないバージョンファイル: package.jsonは更新したがpackage-lock.jsonはしない、またはDESCRIPTIONは更新したがCITATIONはしない。すべてのバージョン参照は同期を維持しなければならない。
  • ビルドメタデータの混同: ビルドメタデータ(
    +build.123
    )はバージョンの優先順位に影響しない。
    1.0.0+build.1
    1.0.0+build.2
    は同じ優先順位を持つ。
  • リリースにタグを付けない: gitタグなしでは、将来のバージョンバンプが変更分析のベースラインを決定できない。

関連スキル

  • manage-changelog
    -- バージョンバンプと対になる変更ログエントリを維持する
  • plan-release-cycle
    -- バージョンバンプの発生時期を決定するリリースマイルストーンを計画する
  • release-package-version
    -- バージョンバンプを含むR固有のリリースワークフロー
  • commit-changes
    -- 適切なメッセージでバージョンバンプをコミットする
  • create-github-release
    -- バージョンタグからGitHubリリースを作成する