Skip to content

HelmのsemverCompare関数でバージョン比較について学ぶ

Helm Chart を作成する中で、特定のバージョンに基づいて処理を分岐させたい場面に遭遇しました。たとえば、依存する Chart のバージョンによって設定を変えたり、特定のバージョン以上でのみ有効な機能を使ったりする場合です。Helm には semverCompare という便利な関数が用意されており、これを使うことでセマンティックバージョニングに基づいた比較が可能です。この記事では、semverCompare 関数の使い方と、実際の Chart 開発でどのように活用できるかを学習した記録を共有します。

https://github.com/kntks/blog-code/tree/main/2025/05/using-semvercompare-in-helm-charts

バージョン
MacSequoia 15.4.1
Helm3.17.3

Helm は example という名前の Chart を作成しました。

Terminal window
helm create example

セマンティックバージョニング (SemVer) のおさらい

Section titled “セマンティックバージョニング (SemVer) のおさらい”

semverCompare を理解する上で、SemVer の基本をおさらいします。SemVer は メジャー.マイナー.パッチ (例: 1.2.3) という形式でバージョンを表現する規約です。

  • メジャーバージョン: 後方互換性のない API 変更があった場合にインクリメントします。
  • マイナーバージョン: 後方互換性を保ちつつ機能が追加された場合にインクリメントします。
  • パッチバージョン: 後方互換性を保ちつつバグ修正が行われた場合にインクリメントします。

semverCompare は、この SemVer のルールにしたがってバージョン間の比較を行います。

semverCompare 関数と基本的な使い方

Section titled “semverCompare 関数と基本的な使い方”

この関数は、セマンティックバージョニング (SemVer) に基づいてバージョン文字列を比較するために使用します。Helm Chart 内で特定のバージョン条件に基づいてリソースの定義や設定値を動的に変更したい場合に非常に役立ちます。

semverCompare 関数は、主に 2 つの文字列引数を取ります。

semverCompare "CONSTRAINT" "VERSION"

CONSTRAINT: 比較条件を表す文字列です。バージョン番号と比較演算子を組み合わせた形式 (例: >=1.2.0, <2.0.0, =1.5.x) や、より複雑な範囲指定 (例: >=1.0.0, <2.0.0) が可能です。
VERSION: 比較対象となる SemVer 形式のバージョン文字列です (例: 1.2.3, 2.0.0-beta.1)。通常は .Chart.AppVersion や .Values から取得した値を使用します。

この関数は、指定された VERSIONCONSTRAINT で定義された条件を満たす場合に true を、満たさない場合に false のブール値を返します。

CONSTRAINT 文字列内では、以下の比較演算子を使用できます。

  • =: 等しい(省略可能、例: 1.2.3 は =1.2.3 と同じ)
  • !=: 等しくない
  • >: より大きい
  • <: より小さい
  • >=: 以上
  • <=: 以下

これらの演算子を組み合わせることで、柔軟なバージョン比較を実現できます。たとえば、>=1.2.0, <1.3.0 は「1.2.0 以上かつ 1.3.0 未満」という範囲を指定します。

実際に semverCompare を使用して、さまざまな条件での比較結果を示す ConfigMap を生成します。以下のコードは、基本的な比較演算子を使用した例です。

example/templates/semver-compare-basic-operators.yaml
$ helm template example -s templates/semver-compare-basic-operators.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-basic-operators
data:
test01_condition: '{{ semverCompare "=1.2.3" "1.2.3" }}'
test01_result: true
test02_condition: '{{ semverCompare "!=1.2.3" "1.2.4" }}'
test02_result: true
test03_condition: '{{ semverCompare ">1.2.3" "1.2.4" }}'
test03_result: true
test04_condition: '{{ semverCompare "<1.2.3" "1.2.2" }}'
test04_result: true
test05_condition: '{{ semverCompare ">=1.2.3" "1.2.3" }}'
test05_result: true
test06_condition: '{{ semverCompare "<=1.2.3" "1.2.3" }}'
test06_result: true

プレリリースバージョンの扱い

Section titled “プレリリースバージョンの扱い”

セマンティックバージョニングでは、安定版(stable)やGA(Generally Available)リリース前のバージョンを「プレリリース」として扱います。これらはバージョン文字列内でハイフン(-)に続く識別子で表現されます。たとえば以下のようなものがプレリリースに該当します

  • 1.2.3-alpha
  • 1.2.3-beta.1
  • 1.2.3-rc.2
  • 2.0.0-dev.20250505

SemVer の仕様では、プレリリースバージョンは対応する正式リリースよりも「低い」と見なされます。
たとえば、以下のような順序で比較されます

1.2.3-alpha < 1.2.3-beta < 1.2.3-rc.1 < 1.2.3

これは、プレリリースバージョンがまだ安定版ではなく、関連する正式バージョンと互換性要件を満たさない可能性があることを示します。

semverCompare でのプレリリースの扱い

Section titled “semverCompare でのプレリリースの扱い”

Helm の semverCompare 関数を使用する際、プレリリースの扱いにはとくに注意が必要です。

  1. プレリリース指定子なしの比較

    重要なポイントとして、制約条件にプレリリース指定子を含めない場合、プレリリースバージョンは比較対象から除外されます

    {{/* 1.2.0-alpha は 1.2.0 未満なので条件は満たさない */}}
    {{ semverCompare ">=1.2.0" "1.2.0-alpha" }} {{/* false */}}
    {{/* 1.2.1-alpha は 1.2.0 より大きいように見えるが、制約にプレリリース指定子がないため条件を満たさない */}}
    {{ semverCompare ">=1.2.0" "1.2.1-alpha" }} {{/* false */}}
  2. プレリリース指定子を含む比較

    プレリリースバージョンを比較に含めたい場合は、制約側にもプレリリース指定子を付ける必要があります。
    ここで -0 を使用する理由は、ASCII ソート順で 0 がもっとも小さい値となるためで、これによりすべてのプレリリースバージョンを対象にできます。

    {{/* 1.2.0-alpha は 1.2.0-0 未満なので条件を満たす */}}
    {{ semverCompare ">=1.2.0-0" "1.2.0-alpha" }} {{/* true */}}
    {{/* 1.1.9-alpha は 1.2.0-0 より小さいので条件を満たさない */}}
    {{ semverCompare ">=1.2.0-0" "1.1.9-alpha" }} {{/* false */}}

実際に semverCompare を使用してプレリリースバージョンを比較する例を示します。以下のコードは、さまざまな条件での比較結果を示す ConfigMap を生成します。

example/templates/semver-compare-prereleases.yaml
$ helm template example -s templates/semver-compare-prereleases.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-prereleases
data:
test01_condition: '{{ semverCompare ">=1.2.0" "1.2.0-alpha" }}'
test01_result: false
test02_condition: '{{ semverCompare ">=1.2.0" "1.2.1-alpha" }}'
test02_result: false
test03_condition: '{{ semverCompare ">=1.2.0-0" "1.2.0-alpha" }}'
test03_result: true
test04_condition: '{{ semverCompare ">=1.2.0-0" "1.1.9-alpha" }}'
test04_result: false
test05_condition: '{{ semverCompare ">=1.2.0-alpha" "1.2.0-beta" }}'
test05_result: true

プレリリース識別子の比較は ASCII ソート順に基づいて行われます。これは直感に反する結果をもたらすことがあります

{{ semverCompare ">=1.2.3-BETA" "1.2.3-alpha" }} {{/* true - 直感に反するかも */}}

数字は英字よりも「小さい」と見なされます

{{ semverCompare ">=1.2.3-9" "1.2.3-alpha" }} {{/* true */}}

プレリリースバージョンを正しく扱うことで、開発環境から本番環境まで一貫性のある Helm Chart を作成することが可能になります。

実際に semverCompare を使用して ASCII ソート順を考慮した比較を行う例を示します。以下のコードは、さまざまな条件での比較結果を示す ConfigMap を生成します。

example/templates/semver-compare-ascii-order.yaml
$ helm template example -s templates/semver-compare-ascii-order.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-ascii-order
data:
test01_condition: "semverCompare >=1.2.0-BETA 1.2.0-alpha"
test01_result: true
test02_condition: "semverCompare >=1.2.0-9 1.2.0-alpha"
test02_result: true
test03_condition: "semverCompare >=1.2.0-alpha 1.2.0-9"
test03_result: false

semverCompare を使用して、バージョンの範囲を指定することも可能です。たとえば、特定のバージョン以上かつ以下の範囲を指定する場合、以下のように記述します。

{{ semverCompare ">=1.2.0, <1.3.0" "1.2.3" }} {{/* true */}}
{{ semverCompare ">=1.2.0, <1.3.0" "1.3.0" }} {{/* false */}}

さらに、ハイフン(-)を使用して範囲を指定することもできます。たとえば、1.2 - 1.4.5>=1.2 <=1.4.5 と同等です。

{{ semverCompare "1.2 - 1.4.5" "1.3.0" }} {{/* true */}}
{{ semverCompare "1.2 - 1.4.5" "1.2.0" }} {{/* true */}}
{{ semverCompare "1.2 - 1.4.5" "1.4.5" }} {{/* true */}}
{{ semverCompare "1.2 - 1.4.5" "1.5.0" }} {{/* false */}}
{{ semverCompare "1.2 - 1.4.5" "1.1.9" }} {{/* false */}}

semverCompare を使用してバージョン範囲を指定する例を示します。以下のコードは、さまざまな条件での比較結果を示す ConfigMap を生成します。

example/templates/semver-compare-version-ranges.yaml
$ helm template example -s templates/semver-compare-version-ranges.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-hyphen-ranges
data:
# バージョン範囲のテスト(カンマ区切り)
test01_condition: '{{ semverCompare ">=1.2.0, <1.3.0" "1.2.3" }}'
test01_result: true
test02_condition: '{{ semverCompare ">=1.2.0, <1.3.0" "1.3.0" }}'
test02_result: false
# ハイフン範囲のテスト
# 1.2 - 1.4.5 は >= 1.2 <= 1.4.5 と同等
test03_condition: '{{ semverCompare "1.2 - 1.4.5" "1.3.0" }}'
test03_result: true
test04_condition: '{{ semverCompare "1.2 - 1.4.5" "1.2.0" }}'
test04_result: true
test05_condition: '{{ semverCompare "1.2 - 1.4.5" "1.4.5" }}'
test05_result: true
test06_condition: '{{ semverCompare "1.2 - 1.4.5" "1.5.0" }}'
test06_result: false
test07_condition: '{{ semverCompare "1.2 - 1.4.5" "1.1.9" }}'
test07_result: false
# 2.3.4 - 4.5 は >= 2.3.4 <= 4.5 と同等
test08_condition: '{{ semverCompare "2.3.4 - 4.5" "3.0.0" }}'
test08_result: true
test09_condition: '{{ semverCompare "2.3.4 - 4.5" "2.3.4" }}'
test09_result: true
test10_condition: '{{ semverCompare "2.3.4 - 4.5" "4.5.0" }}'
test10_result: true
test11_condition: '{{ semverCompare "2.3.4 - 4.5" "4.6.0" }}'
test11_result: false
test12_condition: '{{ semverCompare "2.3.4 - 4.5" "2.3.3" }}'
test12_result: false
# ハイフン範囲とプレリリースの組み合わせ
test13_condition: '{{ semverCompare "1.2.0 - 1.4.0" "1.3.0-beta" }}'
test13_result: false
test14_condition: '{{ semverCompare "1.2.0-0 - 1.4.0" "1.3.0-beta" }}'
test14_result: false
test15_condition: '{{ semverCompare "1.2.0-0 - 1.4.0-0" "1.3.0-beta" }}'
test15_result: true

セマンティックバージョン比較において、Helm の semverCompare 関数では x、X、* の文字をワイルドカード文字として使用できます。これらのワイルドカードはすべての比較演算子で使用可能で、とくに = 演算子では後述するチルダ比較演算子と同様に、パッチレベルの比較に置き換わります。

ワイルドカードを使用すると、特定のバージョン部分(メジャー、マイナー、パッチ)を「任意の値」として指定できます。以下はワイルドカードの一般的な使用例です

  • 1.2.x>= 1.2.0, < 1.3.0 と同等になります(1.2.x系のすべてのバージョン)
  • >= 1.2.x>= 1.2.0 と同等になります(1.2.0以上のすべてのバージョン)
  • <= 2.x< 3 と同等になります(3.0.0未満のすべてのバージョン)
  • *>= 0.0.0 と同等になります(すべてのバージョン)

これにより、特定のマイナーバージョンやメジャーバージョンに属するすべてのパッチバージョンを簡単に指定できます。

semverCompare を使用してバージョン範囲を指定する例を示します。以下のコードは、さまざまな条件での比較結果を示す ConfigMap を生成します。

example/templates/semver-compare-wildcards.yaml
$ helm template example -s templates/semver-compare-wildcards.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-wildcards
data:
# ワイルドカード x を使用したテスト
# 1.2.x は >= 1.2.0, < 1.3.0 と同等
test01_condition: '{{ semverCompare "1.2.x" "1.2.7" }}'
test01_result: true
test02_condition: '{{ semverCompare "1.2.x" "1.3.0" }}'
test02_result: false
test03_condition: '{{ semverCompare "1.2.x" "1.1.9" }}'
test03_result: false
# >= 1.2.x は >= 1.2.0 と同等
test04_condition: '{{ semverCompare ">=1.2.x" "1.2.0" }}'
test04_result: true
test05_condition: '{{ semverCompare ">=1.2.x" "1.3.0" }}'
test05_result: true
test06_condition: '{{ semverCompare ">=1.2.x" "1.1.9" }}'
test06_result: false
# <= 2.x は < 3 と同等
test07_condition: '{{ semverCompare "<=2.x" "2.9.9" }}'
test07_result: true
test08_condition: '{{ semverCompare "<=2.x" "3.0.0" }}'
test08_result: false
test09_condition: '{{ semverCompare "<=2.x" "1.9.9" }}'
test09_result: true
# * は >= 0.0.0 と同等
test10_condition: '{{ semverCompare "*" "0.0.1" }}'
test10_result: true
test11_condition: '{{ semverCompare "*" "1.2.3" }}'
test11_result: true
# ワイルドカードとプレリリースバージョンの組み合わせ
test12_condition: '{{ semverCompare "1.2.x" "1.2.3-beta" }}'
test12_result: false
test13_condition: '{{ semverCompare "1.2.x-0" "1.2.3-beta" }}'
test13_result: true
# 大文字Xと*を使ったテスト
test14_condition: '{{ semverCompare "1.2.X" "1.2.7" }}'
test14_result: true
test15_condition: '{{ semverCompare ">=1.2.*" "1.3.0" }}'
test15_result: true

チルダ比較演算子は、マイナーバージョンが指定されている場合はパッチレベルの範囲を表し、マイナーバージョンが省略されている場合はメジャーレベルの変更範囲を表します。具体的には以下のように解釈されます

  • ~1.2.3>= 1.2.3, < 1.3.0 と同等(1.2.3以上1.3.0未満)
  • ~1>= 1, < 2 と同等(1.x.xのすべてのバージョン)
  • ~2.3>= 2.3, < 2.4 と同等(2.3.x系のすべてのバージョン)
  • ~1.2.x>= 1.2.0, < 1.3.0 と同等(1.2.x系のすべてのバージョン)
  • ~1.x>= 1, < 2 と同等(1.x.xのすべてのバージョン)

チルダ比較演算子を使った semverCompare の実用例を示します。以下のコードは、さまざまな条件での比較結果を示す ConfigMap を生成します。

example/templates/semver-compare-tilde.yaml
$ helm template example -s templates/semver-compare-tilde.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-tilde
data:
# ~1.2.3 は >= 1.2.3, < 1.3.0 と同等
test01_condition: '{{ semverCompare "~1.2.3" "1.2.3" }}'
test01_result: true
test02_condition: '{{ semverCompare "~1.2.3" "1.2.9" }}'
test02_result: true
test03_condition: '{{ semverCompare "~1.2.3" "1.3.0" }}'
test03_result: false
# ~1 は >= 1, < 2 と同等
test04_condition: '{{ semverCompare "~1" "1.0.0" }}'
test04_result: true
test05_condition: '{{ semverCompare "~1" "1.9.9" }}'
test05_result: true
test06_condition: '{{ semverCompare "~1" "2.0.0" }}'
test06_result: false
# ~2.3 は >= 2.3, < 2.4 と同等
test07_condition: '{{ semverCompare "~2.3" "2.3.0" }}'
test07_result: true
test08_condition: '{{ semverCompare "~2.3" "2.3.9" }}'
test08_result: true
test09_condition: '{{ semverCompare "~2.3" "2.4.0" }}'
test09_result: false
# ~1.2.x は >= 1.2.0, < 1.3.0 と同等
test10_condition: '{{ semverCompare "~1.2.x" "1.2.7" }}'
test10_result: true
test11_condition: '{{ semverCompare "~1.2.x" "1.3.0" }}'
test11_result: false
# ~1.x は >= 1, < 2 と同等
test12_condition: '{{ semverCompare "~1.x" "1.9.9" }}'
test12_result: true
test13_condition: '{{ semverCompare "~1.x" "2.0.0" }}'
test13_result: false
# プレリリースバージョンとの組み合わせ
test14_condition: '{{ semverCompare "~1.2.0" "1.2.0-beta" }}'
test14_result: false
test15_condition: '{{ semverCompare "~1.2.0-0" "1.2.0-beta" }}'
test15_result: true
test16_condition: '{{ semverCompare "~1.2.0-0" "1.2.5-alpha" }}'
test16_result: true
test17_condition: '{{ semverCompare "~1.2.0-0" "1.3.0-alpha" }}'
test17_result: false

キャレット比較演算子(^)は、安定版(1.0.0以上)のリリース以降はメジャーレベルの変更を意味し、1.0.0未満のリリースでは異なる挙動をします。この演算子は、とくにAPI互換性に基づいたバージョン制約を簡潔に表現するために便利です。

1.0.0以上のバージョンでは、キャレット演算子はメジャーバージョンの上限を設定します(API互換性を保証)。1.0.0未満のバージョンでは、より保守的な動作をし、マイナーバージョンが変わると非互換とみなします。

具体的には、キャレット演算子は左端の非ゼロの要素を固定します

  • ^1.2.3>= 1.2.3, < 2.0.0 と同等(メジャーバージョン1の範囲内)
  • ^0.2.3>= 0.2.3, < 0.3.0 と同等(マイナーバージョン0.2の範囲内)
  • ^0.0.3>= 0.0.3, < 0.0.4 と同等(パッチバージョン0.0.3のみ)

キャレット演算子を使った semverCompare の実用例を示します。以下のコードは、さまざまな条件での比較結果を示す ConfigMap を生成します。

example/templates/semver-compare-caret.yaml
$ helm template example -s templates/semver-compare-caret.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: semver-compare-caret
data:
# ^1.2.3 は >= 1.2.3, < 2.0.0 と同等(メジャーバージョン1の範囲内)
test01_condition: '{{ semverCompare "^1.2.3" "1.2.3" }}'
test01_result: true
test02_condition: '{{ semverCompare "^1.2.3" "1.9.9" }}'
test02_result: true
test03_condition: '{{ semverCompare "^1.2.3" "2.0.0" }}'
test03_result: false
# ^0.2.3 は >=0.2.3, <0.3.0 と同等(マイナーバージョン0.2の範囲内)
test04_condition: '{{ semverCompare "^0.2.3" "0.2.3" }}'
test04_result: true
test05_condition: '{{ semverCompare "^0.2.3" "0.2.9" }}'
test05_result: true
test06_condition: '{{ semverCompare "^0.2.3" "0.3.0" }}'
test06_result: false
# ^0.0.3 は >=0.0.3, <0.0.4 と同等(パッチバージョン0.0.3のみ)
test07_condition: '{{ semverCompare "^0.0.3" "0.0.3" }}'
test07_result: true
test08_condition: '{{ semverCompare "^0.0.3" "0.0.4" }}'
test08_result: false
# ワイルドカードとの組み合わせ
test09_condition: '{{ semverCompare "^1.2.x" "1.5.0" }}'
test09_result: true
test10_condition: '{{ semverCompare "^2.x" "2.9.9" }}'
test10_result: true
test11_condition: '{{ semverCompare "^2.x" "3.0.0" }}'
test11_result: false
# 他のパターン
test12_condition: '{{ semverCompare "^0.2" "0.2.5" }}'
test12_result: true
test13_condition: '{{ semverCompare "^0" "0.9.9" }}'
test13_result: true
test14_condition: '{{ semverCompare "^0" "1.0.0" }}'
test14_result: false
# プレリリースバージョンとの組み合わせ
test15_condition: '{{ semverCompare "^1.2.0" "1.3.0-beta" }}'
test15_result: false
test16_condition: '{{ semverCompare "^1.2.0-0" "1.3.0-beta" }}'
test16_result: true
test17_condition: '{{ semverCompare "^0.2.0-0" "0.2.3-beta" }}'
test17_result: true
test18_condition: '{{ semverCompare "^0.2.0-0" "0.3.0-alpha" }}'
test18_result: false

この記事では、Helm の semverCompare 関数の基本から応用までを詳しく解説しました。以下が主要なポイントです。

基本機能と使い方

  • semverCompare 関数はセマンティックバージョニング (SemVer) に基づいてバージョン文字列を比較します
  • semverCompare “CONSTRAINT” “VERSION” の形式で使用し、制約条件を満たす場合に true を返します
  • 基本的な比較演算子(=, !=, >, <, >=, <=)をサポートしています

プレリリースバージョンの扱い

  • プレリリースバージョン(1.2.3-beta など)は、対応する正式リリース(1.2.3)より「低い」と見なされます
  • 制約条件にプレリリース指定子がない場合、プレリリースバージョンは比較対象から除外されます
  • プレリリースバージョンを比較に含めるには、制約側にプレリリース指定子(例:-0)を付ける必要があります

高度な比較構文

  • バージョン範囲: カンマ(,)またはハイフン(-)で範囲を指定できます
  • ワイルドカード: x、X、* を使って「任意の値」として指定できます
  • チルダ演算子: ~1.2.3 はパッチレベル更新を許容します(>= 1.2.3, < 1.3.0)
  • キャレット演算子: ^1.2.3 はメジャーバージョン互換性を維持する更新を許容します(>= 1.2.3, < 2.0.0)

実践的な利用シーン

  • Kubernetes リソースの条件付きデプロイ(特定バージョン以上で新機能を有効化)
  • 依存する Chart のバージョンによって設定を変更
  • API バージョンの互換性に基づいた分岐処理
  • マイクロサービスアーキテクチャでのサービス間の互換性確保

注意点

  • プレリリースバージョンの扱いに注意が必要です
  • ASCII ソート順に基づく比較は直感に反する結果になることがあります
  • 複雑な条件を作成する場合は、個別にテストして期待通りに動作することを確認しましょう

semverCompare を活用することで、互換性を考慮したバージョン分岐処理が可能になり、より柔軟で堅牢な Helm Chart を作成できます。