diff --git a/lib/kamal/cli/templates/deploy.yml b/lib/kamal/cli/templates/deploy.yml index 2c9568f4..af018554 100644 --- a/lib/kamal/cli/templates/deploy.yml +++ b/lib/kamal/cli/templates/deploy.yml @@ -31,7 +31,6 @@ registry: # user: app # Configure builder setup. -# Set git_archive: true to build from a git archive of HEAD # builder: # args: # RUBY_VERSION: 3.2.0 @@ -40,7 +39,6 @@ registry: # remote: # arch: amd64 # host: ssh://app@192.168.0.1 -# git_archive: false # Use accessory services (secrets come from .env). # accessories: diff --git a/lib/kamal/configuration/builder.rb b/lib/kamal/configuration/builder.rb index 6805ca72..ea4e71d9 100644 --- a/lib/kamal/configuration/builder.rb +++ b/lib/kamal/configuration/builder.rb @@ -86,7 +86,7 @@ class Kamal::Configuration::Builder end def git_archive? - @options["git_archive"] + Kamal::Git.used? && @options["context"].nil? end private @@ -94,9 +94,6 @@ class Kamal::Configuration::Builder if @options["cache"] && @options["cache"]["type"] raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"]) end - if @options["context"] && @options["git_archive"] - raise ArgumentError, "Cannot set a builder context when building from a git archive" - end end def cache_image diff --git a/test/cli/build_test.rb b/test/cli/build_test.rb index 1cb99fa4..186c1e9e 100644 --- a/test/cli/build_test.rb +++ b/test/cli/build_test.rb @@ -15,7 +15,7 @@ class CliBuildTest < CliTestCase run_command("push").tap do |output| assert_hook_ran "pre-build", output, **hook_variables assert_match /docker --version && docker buildx version/, output - assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder kamal-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*@localhost/, output + assert_match /git archive -tar HEAD | docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder kamal-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile - as .*@localhost/, output end end @@ -25,7 +25,10 @@ class CliBuildTest < CliTestCase .with(:docker, "--version", "&&", :docker, :buildx, "version") SSHKit::Backend::Abstract.any_instance.stubs(:execute) - .with { |*args| args[0..1] == [ :docker, :buildx ] } + .with(:docker, :buildx, :create, "--use", "--name", "kamal-app-multiarch") + + SSHKit::Backend::Abstract.any_instance.stubs(:execute) + .with { |*args| p args[0..6]; args[0..6] == [ :git, :archive, "--format=tar", :HEAD, "|", :docker, :buildx ] } .raises(SSHKit::Command::Failed.new("no builder")) .then .returns(true) diff --git a/test/commands/builder_test.rb b/test/commands/builder_test.rb index bc78184a..b03b0c83 100644 --- a/test/commands/builder_test.rb +++ b/test/commands/builder_test.rb @@ -9,7 +9,7 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder = new_builder_command(builder: { "cache" => { "type" => "gha" } }) assert_equal "multiarch", builder.name assert_equal \ - "docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .", + "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile -", builder.push.join(" ") end @@ -17,7 +17,7 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder = new_builder_command(builder: { "multiarch" => false }) assert_equal "native", builder.name assert_equal \ - "docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest", + "git archive --format=tar HEAD | docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile - && docker push dhh/app:123 && docker push dhh/app:latest", builder.push.join(" ") end @@ -25,7 +25,7 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder = new_builder_command(builder: { "multiarch" => false, "cache" => { "type" => "gha" } }) assert_equal "native/cached", builder.name assert_equal \ - "docker buildx build --push -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .", + "git archive --format=tar HEAD | docker buildx build --push -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile -", builder.push.join(" ") end @@ -33,7 +33,7 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder = new_builder_command(builder: { "local" => {}, "remote" => {}, "cache" => { "type" => "gha" } }) assert_equal "multiarch/remote", builder.name assert_equal \ - "docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch-remote -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .", + "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch-remote -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile -", builder.push.join(" ") end @@ -41,7 +41,7 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder = new_builder_command(builder: { "local" => { "arch" => "amd64" } }) assert_equal "multiarch", builder.name assert_equal \ - "docker buildx build --push --platform linux/amd64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile .", + "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile -", builder.push.join(" ") end @@ -49,7 +49,7 @@ class CommandsBuilderTest < ActiveSupport::TestCase builder = new_builder_command(builder: { "remote" => { "arch" => "amd64" }, "cache" => { "type" => "gha" } }) assert_equal "native/remote", builder.name assert_equal \ - "docker buildx build --push --platform linux/amd64 --builder kamal-app-native-remote -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile .", + "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64 --builder kamal-app-native-remote -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile -", builder.push.join(" ") end @@ -93,21 +93,21 @@ class CommandsBuilderTest < ActiveSupport::TestCase test "native push with build args" do builder = new_builder_command(builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } }) assert_equal \ - "docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest", + "git archive --format=tar HEAD | docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile - && docker push dhh/app:123 && docker push dhh/app:latest", builder.push.join(" ") end test "multiarch push with build args" do builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } }) assert_equal \ - "docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile .", + "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --build-arg a=\"1\" --build-arg b=\"2\" --file Dockerfile -", builder.push.join(" ") end test "native push with build secrets" do builder = new_builder_command(builder: { "multiarch" => false, "secrets" => [ "a", "b" ] }) assert_equal \ - "docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"a\" --secret id=\"b\" --file Dockerfile . && docker push dhh/app:123 && docker push dhh/app:latest", + "git archive --format=tar HEAD | docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --secret id=\"a\" --secret id=\"b\" --file Dockerfile - && docker push dhh/app:123 && docker push dhh/app:latest", builder.push.join(" ") end @@ -123,31 +123,31 @@ class CommandsBuilderTest < ActiveSupport::TestCase assert_equal "docker inspect -f '{{ .Config.Labels.service }}' dhh/app:123 | grep -x app || (echo \"Image dhh/app:123 is missing the 'service' label\" && exit 1)", new_builder_command.validate_image.join(" ") end - test "multiarch git archive build" do - builder = new_builder_command(builder: { "git_archive" => true }) + test "multiarch context build" do + builder = new_builder_command(builder: { "context" => "./foo" }) assert_equal \ - "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile -", + "docker buildx build --push --platform linux/amd64,linux/arm64 --builder kamal-app-multiarch -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo", builder.push.join(" ") end - test "native git archive build" do - builder = new_builder_command(builder: { "multiarch" => false, "git_archive" => true }) + test "native context build" do + builder = new_builder_command(builder: { "multiarch" => false, "context" => "./foo" }) assert_equal \ - "git archive --format=tar HEAD | docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile - && docker push dhh/app:123 && docker push dhh/app:latest", + "docker build -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo && docker push dhh/app:123 && docker push dhh/app:latest", builder.push.join(" ") end - test "cached git archive build" do - builder = new_builder_command(builder: { "multiarch" => false, "git_archive" => true, "cache" => { "type" => "gha" } }) + test "cached context build" do + builder = new_builder_command(builder: { "multiarch" => false, "context" => "./foo", "cache" => { "type" => "gha" } }) assert_equal \ - "git archive --format=tar HEAD | docker buildx build --push -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile -", + "docker buildx build --push -t dhh/app:123 -t dhh/app:latest --cache-to type=gha --cache-from type=gha --label service=\"app\" --file Dockerfile ./foo", builder.push.join(" ") end - test "remote git archive build" do - builder = new_builder_command(builder: { "remote" => { "arch" => "amd64" }, "git_archive" => true }) + test "remote context build" do + builder = new_builder_command(builder: { "remote" => { "arch" => "amd64" }, "context" => "./foo" }) assert_equal \ - "git archive --format=tar HEAD | docker buildx build --push --platform linux/amd64 --builder kamal-app-native-remote -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile -", + "docker buildx build --push --platform linux/amd64 --builder kamal-app-native-remote -t dhh/app:123 -t dhh/app:latest --label service=\"app\" --file Dockerfile ./foo", builder.push.join(" ") end diff --git a/test/configuration/builder_test.rb b/test/configuration/builder_test.rb index a519be67..9ac02ad6 100644 --- a/test/configuration/builder_test.rb +++ b/test/configuration/builder_test.rb @@ -140,7 +140,7 @@ class ConfigurationBuilderTest < ActiveSupport::TestCase end test "context" do - assert_equal ".", @config.builder.context + assert_equal "-", @config.builder.context end test "setting context" do diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 720f65fc..6f89d669 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -103,17 +103,17 @@ class ConfigurationTest < ActiveSupport::TestCase Kamal::Git.expects(:revision).returns("git-version") Kamal::Git.expects(:uncommitted_changes).returns("M file\n") - assert_match /^git-version_uncommitted_[0-9a-f]{16}$/, @config.version + assert_equal "git-version", @config.version end - test "version from git archive uncommitted" do + test "version from uncommitted context" do ENV.delete("VERSION") - config = Kamal::Configuration.new(@deploy.tap { |c| c[:builder] = { "git_archive" => true } }) + config = Kamal::Configuration.new(@deploy.tap { |c| c[:builder] = { "context" => "." } }) Kamal::Git.expects(:revision).returns("git-version") Kamal::Git.expects(:uncommitted_changes).returns("M file\n") - assert_equal "git-version", config.version + assert_match /^git-version_uncommitted_[0-9a-f]{16}$/, config.version end test "version from env" do