2026年8月14日
2026年8月14日
セマンティックバージョニングとリリース管理(WordPressプラグイン・テーマ編)
セマンティックバージョニング(SemVer)は、1.4.2 のような「メジャー.マイナー.パッチ」の番号で、利用者に変更の影響範囲を伝えるルールです。WordPress のプラグインやテーマでは、番号を書く場所が複数あり、更新通知・アセットのキャッシュ・データベースの更新処理にも番号が使われるため、決め方と上げ方を仕組みにしておくと事故が減ります。この記事では、SemVer の基本、WordPress での判断基準、番号を書く場所の一元化、リリース手順、データベース更新処理の書き方を説明します。
セマンティックバージョニングの基本
SemVer 2.0.0 の考え方は次のとおりです。
- メジャー(
1.x.x→2.0.0): 後方互換性のない変更。利用者側のコードや設定に手直しが必要になりうるもの - マイナー(
1.4.x→1.5.0): 後方互換性を保った機能追加 - パッチ(
1.4.2→1.4.3): 後方互換性を保ったバグ修正
マイナーを上げたらパッチは0に、メジャーを上げたらマイナーとパッチは0に戻します。1.0.0-beta.1 のような接尾辞は正式版より前のプレリリースを表します。0.x.x の間は開発初期で、何が変わってもよいとされています。
番号そのものより大事なのは、「どんな変更をメジャーと呼ぶか」を事前に決めて公開しておくことです。利用者は番号を見て、すぐ更新してよいか、検証してから更新すべきかを判断します。
WordPress で「互換性を壊す変更」とは何か
WordPress のプラグインやテーマでは、利用者が依存しているのは画面だけではありません。次のような変更は、他の開発者のコードや子テーマを動かなくする可能性があるため、メジャー扱いを検討します。
- 公開しているアクションフック・フィルターフックの削除、名前の変更、渡す引数の順序変更
- 利用者が呼び出す前提の関数・クラス・メソッドの削除やシグネチャ変更
- ショートコード名やブロック名の変更、ブロックの属性の削除
- テンプレートファイル(テーマや、テーマで上書きできるプラグインのテンプレート)の構造の大きな変更
- 保存しているオプションやメタデータの形式を、移行処理なしで変えること
一方、必要な PHP や WordPress の最低バージョンを引き上げることをどう扱うかは、プロジェクトによって判断が分かれます。古い環境の利用者には更新が届かなくなるので、少なくともマイナー以上で、変更履歴に明記するのが親切です。
なお、WordPress コア自体は SemVer ではありません。コアでは 6.8 から 6.9 のように小数点以下1桁目が変わるものがメジャーリリースで、3桁目がメンテナンス・セキュリティリリースです。プラグインの番号の付け方とは別物として考えてください。
番号を書く場所を整理する
WordPress のプラグインでは、同じ番号を何か所にも書くことになります。
| 場所 | 用途 |
|---|---|
メインファイルのヘッダー Version: |
管理画面の表示、更新の判定 |
readme.txt の Stable tag: |
WordPress.org のプラグインディレクトリで配布する版の指定 |
PHP の定数(例: MYPLUGIN_VERSION) |
アセットのバージョン、データベース更新処理 |
package.json の version |
ビルドツールやリリース自動化ツール |
テーマの場合は style.css の Version: が中心です。これらがずれると、「管理画面では新しい版なのに、CSS は古いキャッシュが返る」といった分かりにくい不具合になります。PHP の中では定数を1つ定義し、そこだけを参照するようにします。
<?php
/**
* Plugin Name: My Plugin
* Version: 1.5.0
* Requires at least: 6.4
* Requires PHP: 8.1
*/
define( 'MYPLUGIN_VERSION', '1.5.0' );
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style(
'myplugin',
plugins_url( 'assets/style.css', __FILE__ ),
array(),
MYPLUGIN_VERSION // ?ver=1.5.0 が付き、更新時にブラウザキャッシュが切り替わる
);
} );
wp_enqueue_style() や wp_enqueue_script() の第4引数にバージョンを渡すと URL に ?ver= が付き、版を上げたときにブラウザや CDN のキャッシュが切り替わります。@wordpress/scripts でビルドしている場合は、生成される index.asset.php にファイル内容から作ったバージョン文字列が入っているので、それを使う方法もあります。
ヘッダーと定数、readme.txt の番号を手で書き換えると漏れが出るため、リリース時に1つのスクリプトでまとめて置き換え、置き換え後に grep で全箇所が一致しているかを確認する手順にしておくと安心です。
リリースの流れ
Git で管理しているプロジェクトなら、次の流れが基本になります。
- 変更をまとめ、メジャー・マイナー・パッチのどれに当たるかを判断する
- 番号を書く場所をすべて更新し、変更履歴(readme.txt の
== Changelog ==や CHANGELOG.md)に追記する - ステージング環境で、旧版からの更新を実際に行って動作を確認する
- リリース用のコミットに
v1.5.0のような Git タグを付ける - 配布用の ZIP を作る。開発用ファイル(node_modules、テスト、設定ファイルなど)は含めない
git tag -a v1.5.0 -m "Release 1.5.0"
git push origin v1.5.0
タグは一度公開したら付け直さないのが原則です。誤りが見つかったら、1.5.1 として出し直します。同じ番号で中身が違うものが出回ると、どの利用者がどのコードを使っているか分からなくなるためです。
変更履歴は、番号ごとに「追加」「変更」「修正」「削除」のように分けて書くと、利用者が更新の影響を判断しやすくなります。コミットメッセージを Conventional Commits の形式(feat:、fix: など)で書いておけば、release-please や semantic-release といったツールで、次の番号の判断と変更履歴の作成を自動化できます。ただしこれらのツールは WordPress のプラグインヘッダーや readme.txt を標準では知らないので、追加の設定で更新対象のファイルを指定する必要があります。設定方法はツールの版によって異なるため、各ツールのドキュメントを確認してください(2026年10月現在)。
WordPress.org で配布する場合
プラグインディレクトリは Git ではなく Subversion(SVN)で管理され、trunk/ に最新のコード、tags/1.5.0/ のように版ごとのコピーを置きます。readme.txt の Stable tag: が利用者に配布される版を決めるので、tags/ に同じ番号のディレクトリがあること、そのディレクトリ内のヘッダーの Version: が一致していることを確認します。手順の詳細はプラグインハンドブックで確認してください。
データベースの更新処理は番号で制御する
テーブルの追加やオプション形式の変更がある版では、更新後の最初の読み込みで移行処理を走らせます。有効化フック(register_activation_hook())はプラグインの自動更新では実行されないため、保存済みの番号と現在の番号を比べる方法が確実性の高いやり方です。
add_action( 'plugins_loaded', 'myplugin_maybe_upgrade' );
function myplugin_maybe_upgrade() {
$installed = get_option( 'myplugin_version', '0.0.0' );
if ( version_compare( $installed, MYPLUGIN_VERSION, '>=' ) ) {
return; // 更新済み
}
if ( version_compare( $installed, '1.5.0', '<' ) ) {
myplugin_migrate_to_150(); // 1.5.0 で必要になった移行処理
}
update_option( 'myplugin_version', MYPLUGIN_VERSION, false );
}
移行処理は、途中で止まったり2回実行されたりしても壊れないように書きます(すでに列があれば追加しない、など)。アクセスの多いサイトでは同時に複数のリクエストが移行処理に入ることもあるため、重い処理は WP-CLI のコマンドや一度だけ実行される予約処理に分けることも検討してください。リリース前にはデータベースのバックアップを取り、旧版のデータから更新するテストを行います。
version_compare の落とし穴
PHP の version_compare() は SemVer とまったく同じ規則ではありません。たとえば version_compare( '1.5', '1.5.0' ) は等しいとは判定されず、-1(前者が小さい)になります。番号は常に3つの数字で書くようにそろえておくと、こうした比較の食い違いを避けられます。プレリリースの接尾辞の扱いも SemVer の順序と細部が異なるため、-beta.1 のような番号を比較に使う場合はテストで結果を確かめてください。
まとめ
- SemVer は「メジャー.マイナー.パッチ」で互換性の影響を伝える約束です。何をメジャーとするかを事前に決めて公開します。
- WordPress では、公開しているフック・関数・ブロック属性・テンプレートの変更が互換性に関わります。
- ヘッダー、readme.txt の
Stable tag:、PHP 定数、package.json の番号をそろえ、PHP 内は定数1つを参照します。 - 公開したタグは付け直さず、誤りは次のパッチ版で直します。
- データベースの移行処理は保存済みの番号と比べて実行し、何度実行しても壊れないように書きます。番号は3桁でそろえ、
version_compare()の挙動の違いに注意します。