diff --git a/lib/kamal/commands/builder/base.rb b/lib/kamal/commands/builder/base.rb index 53fd144cf..2dd3ab087 100644 --- a/lib/kamal/commands/builder/base.rb +++ b/lib/kamal/commands/builder/base.rb @@ -6,7 +6,7 @@ class BuilderError < StandardError; end delegate :argumentize, to: Kamal::Utils delegate \ :args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote, - :pack?, :pack_builder, :pack_buildpacks, + :pack?, :pack_builder, :pack_buildpacks, :additional_contexts, :cache_from, :cache_to, :ssh, :provenance, :sbom, :driver, :docker_driver?, to: :builder_config @@ -41,7 +41,7 @@ def inspect_builder end def build_options - [ *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance, *builder_sbom ] + [ *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance, *builder_sbom, *build_additional_contexts ] end def build_context @@ -95,6 +95,10 @@ def build_args argumentize "--build-arg", args, sensitive: true end + def build_additional_contexts + argumentize "--build-context", additional_contexts + end + def build_secrets argumentize "--secret", secrets.keys.collect { |secret| [ "id", secret ] } end diff --git a/lib/kamal/configuration/builder.rb b/lib/kamal/configuration/builder.rb index 0e2c4c618..e6391472e 100644 --- a/lib/kamal/configuration/builder.rb +++ b/lib/kamal/configuration/builder.rb @@ -85,6 +85,10 @@ def context builder_config["context"] || "." end + def additional_contexts + builder_config["additional_contexts"] || {} + end + def driver builder_config.fetch("driver", "docker-container") end diff --git a/lib/kamal/configuration/docs/builder.yml b/lib/kamal/configuration/docs/builder.yml index 190fd240a..146653607 100644 --- a/lib/kamal/configuration/docs/builder.yml +++ b/lib/kamal/configuration/docs/builder.yml @@ -67,6 +67,14 @@ builder: # The Dockerfile to use for building, defaults to `Dockerfile`: dockerfile: Dockerfile.production + # Additional build contexts + # + # Additional build contexts to use when building. They are referenced by + # name from the Dockerfile: + additional_contexts: + scripts: ../../scripts + assets: ../../assets + # Build target # # If not set, then the default target is used: diff --git a/lib/kamal/configuration/validator.rb b/lib/kamal/configuration/validator.rb index 05d4c0824..b55cf8f36 100644 --- a/lib/kamal/configuration/validator.rb +++ b/lib/kamal/configuration/validator.rb @@ -45,7 +45,7 @@ def validate_against_example!(validation_config, example) end elsif example_value.is_a?(Hash) case key.to_s - when "options", "args" + when "options", "args", "additional_contexts" validate_type! value, Hash when "labels" validate_hash_of! value, example_value.first[1].class diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index 65517c554..d0580d709 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -150,6 +150,20 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder.push.join(" ") end + test "build additional contexts" do + builder = new_builder_command(builder: { "additional_contexts" => { "scripts" => "../../scripts", "assets" => "../../assets" } }) + assert_equal \ + "--label service=\"app\" --file Dockerfile --build-context scripts=\"../../scripts\" --build-context assets=\"../../assets\"", + builder.target.build_options.join(" ") + end + + test "push with additional contexts" do + builder = new_builder_command(builder: { "additional_contexts" => { "scripts" => "../../scripts", "assets" => "../../assets" } }) + assert_equal \ + "docker buildx build --output=type=registry --platform linux/amd64 --builder kamal-local-docker-container -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile --build-context scripts=\"../../scripts\" --build-context assets=\"../../assets\" . 2>&1", + builder.push.join(" ") + end + test "push with build args" do builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } }) assert_equal \ diff --git a/test/configuration/builder_test.rb b/test/configuration/builder_test.rb index 7925d4caf..861337c9a 100644 --- a/test/configuration/builder_test.rb +++ b/test/configuration/builder_test.rb @@ -141,6 +141,16 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase assert_equal "..", config.builder.context end + test "additional_contexts" do + assert_equal({}, config.builder.additional_contexts) + end + + test "setting additional_contexts" do + @deploy[:builder]["additional_contexts"] = { "scripts" => "../../scripts", "assets" => "../../assets" } + + assert_equal({ "scripts" => "../../scripts", "assets" => "../../assets" }, config.builder.additional_contexts) + end + test "ssh" do assert_nil config.builder.ssh end