エイリアスで destination を指定可能に
Kamalでは、エイリアスの定義内で -d オプションを使って destination を指定できるようになりました。これにより、環境ごとのデプロイコマンドをエイリアスとして定義し、コマンド実行時の -d 指定を省略できます。
背景
Kamalでは require_destination を設定すると、コマンド実行時に必ず -d オプションでの destination 指定が求められます。しかし、従来のエイリアス実装では、設定ファイルの読み込み前に destination が必要とされるため、エイリアス定義内で destination を指定することができませんでした。
#1786 では、設定ファイルの読み込みフローを変更することで、この制約を解消しています。
技術的な変更
Kamal::Commander#resolve_alias メソッドが新設され、設定ファイルの完全な読み込み前にエイリアスを解決できるようになりました。
def resolve_alias(name)
if @config
@config.aliases[name]&.command
else
raw_config = Kamal::Configuration.load_raw_config(**@config_kwargs.to_h.slice(:config_file, :destination))
raw_config[:aliases]&.dig(name)
end
end
このメソッドは、設定オブジェクトが存在する場合は既存の実装を使い、存在しない場合は Kamal::Configuration.load_raw_config を呼び出して生の設定ファイルからエイリアスを取得します。load_raw_config は create_from メソッドから切り出された新しいクラスメソッドです。
def self.load_raw_config(config_file:, destination: nil)
load_config_files(config_file, *destination_config_file(config_file, destination))
end
Kamal::Cli::Alias::Command#run では、KAMAL.config.aliases[name] の代わりに KAMAL.resolve_alias(name) を呼び出すように変更されました。
def run(instance, args = [])
if (command = KAMAL.resolve_alias(name))
KAMAL.reset
Kamal::Cli::Main.start(Shellwords.split(command) + ARGV[1..-1])
else
super
end
end
変更後は、以下のようなエイリアス定義が可能になります。
require_destination: true
aliases:
staging_deploy: deploy -d staging
production_deploy: deploy -d production
これにより、kamal staging_deploy のように destination を省略したコマンド実行が可能になります。
設計判断
設定ファイルの部分的な読み込み という方式が採用されました。
従来の実装では、destination の検証後に設定ファイル全体を読み込んでいましたが、本PRではエイリアス解決時に必要最小限の設定(config_file と destination のみ)を先行して読み込みます。これにより、エイリアスに含まれる destination を評価してから、完全な設定オブジェクトを構築できるようになりました。
resolve_alias メソッドは、設定オブジェクトの有無で処理を分岐させることで、既存の挙動との互換性を保っています。設定が既に読み込まれている場合は従来通りの処理を行い、未読み込みの場合のみ生の設定を参照します。
本PRは、設定の読み込みタイミングを調整することで、エイリアスと destination の依存関係を解消した変更です。環境ごとのデプロイコマンドをエイリアスとして定義できるようになり、コマンドラインでの -d 指定が不要になります。