Add a pre-deploy hook
Useful for checking the status of CI before deploying. Doing this at this point in the deployment maximises the parallelisation of building and running CI.
This commit is contained in:
@@ -9,7 +9,11 @@ class CliBuildTest < CliTestCase
|
||||
end
|
||||
|
||||
test "push" do
|
||||
Mrsk::Commands::Hook.any_instance.stubs(:hook_exists?).returns(true)
|
||||
hook_variables = { version: 999, service_version: "app@999", hosts: "1.1.1.1,1.1.1.2,1.1.1.3,1.1.1.4", command: "build", subcommand: "push" }
|
||||
|
||||
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 mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*@localhost/, output
|
||||
end
|
||||
|
||||
@@ -27,19 +27,30 @@ class CliTestCase < ActiveSupport::TestCase
|
||||
.raises(SSHKit::Command::Failed.new("failed"))
|
||||
end
|
||||
|
||||
def ensure_hook_runs(hook)
|
||||
Mrsk::Commands::Hook.any_instance.stubs(:hook_exists?).returns(true)
|
||||
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
||||
.with { |*args| args != [".mrsk/hooks/#{hook}"] }
|
||||
SSHKit::Backend::Abstract.any_instance.expects(:execute)
|
||||
.with { |*args| args.first == ".mrsk/hooks/#{hook}" }
|
||||
.once
|
||||
end
|
||||
|
||||
def stub_locking
|
||||
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
||||
.with { |arg1, arg2| arg1 == :mkdir && arg2 == :mrsk_lock }
|
||||
SSHKit::Backend::Abstract.any_instance.stubs(:execute)
|
||||
.with { |arg1, arg2| arg1 == :rm && arg2 == "mrsk_lock/details" }
|
||||
end
|
||||
|
||||
def assert_hook_ran(hook, output, version:, service_version:, hosts:, command:, subcommand: nil, runtime: nil)
|
||||
performer = `whoami`.strip
|
||||
|
||||
assert_match "Running the #{hook} hook...\n", output
|
||||
|
||||
expected = %r{Running\s/usr/bin/env\s\.mrsk/hooks/#{hook}\sas\s#{performer}@localhost\n\s
|
||||
DEBUG\s\[[0-9a-f]*\]\sCommand:\s\(\sexport\s
|
||||
MRSK_RECORDED_AT=\"\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ\"\s
|
||||
MRSK_PERFORMER=\"#{performer}\"\s
|
||||
MRSK_VERSION=\"#{version}\"\s
|
||||
MRSK_SERVICE_VERSION=\"#{service_version}\"\s
|
||||
MRSK_HOSTS=\"#{hosts}\"\s
|
||||
MRSK_COMMAND=\"#{command}\"\s
|
||||
#{"MRSK_SUBCOMMAND=\\\"#{subcommand}\\\"\\s" if subcommand}
|
||||
#{"MRSK_RUNTIME=\\\"#{runtime}\\\"\\s" if runtime}
|
||||
;\s/usr/bin/env\s\.mrsk/hooks/#{hook} }x
|
||||
|
||||
assert_match expected, output
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,16 +21,18 @@ class CliMainTest < CliTestCase
|
||||
Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:prune:all", [], invoke_options)
|
||||
|
||||
Mrsk::Commands::Hook.any_instance.stubs(:hook_exists?).returns(true)
|
||||
hook_variables = { version: 999, service_version: "app@999", hosts: "1.1.1.1,1.1.1.2", command: "deploy" }
|
||||
|
||||
run_command("deploy").tap do |output|
|
||||
assert_match /Running the pre-connect hook.../, output
|
||||
assert_hook_ran "pre-connect", output, **hook_variables
|
||||
assert_match /Log into image registry/, output
|
||||
assert_match /Build and push app image/, output
|
||||
assert_hook_ran "pre-deploy", output, **hook_variables
|
||||
assert_match /Ensure Traefik is running/, output
|
||||
assert_match /Ensure app can pass healthcheck/, output
|
||||
assert_match /Detect stale containers/, output
|
||||
assert_match /Prune old containers and images/, output
|
||||
assert_match /Running the post-deploy hook.../, output
|
||||
assert_hook_ran "post-deploy", output, **hook_variables, runtime: 0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -124,10 +126,15 @@ class CliMainTest < CliTestCase
|
||||
|
||||
Mrsk::Commands::Hook.any_instance.stubs(:hook_exists?).returns(true)
|
||||
|
||||
hook_variables = { version: 999, service_version: "app@999", hosts: "1.1.1.1,1.1.1.2", command: "redeploy" }
|
||||
|
||||
run_command("redeploy").tap do |output|
|
||||
assert_hook_ran "pre-connect", output, **hook_variables
|
||||
assert_match /Build and push app image/, output
|
||||
assert_hook_ran "pre-deploy", output, **hook_variables
|
||||
assert_match /Running the pre-deploy hook.../, output
|
||||
assert_match /Ensure app can pass healthcheck/, output
|
||||
assert_match /Running the post-deploy hook.../, output
|
||||
assert_hook_ran "post-deploy", output, **hook_variables, runtime: "0"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -173,13 +180,15 @@ class CliMainTest < CliTestCase
|
||||
end
|
||||
|
||||
Mrsk::Commands::Hook.any_instance.stubs(:hook_exists?).returns(true)
|
||||
hook_variables = { version: 123, service_version: "app@123", hosts: "1.1.1.1,1.1.1.2,1.1.1.3,1.1.1.4", command: "rollback" }
|
||||
|
||||
run_command("rollback", "123", config_file: "deploy_with_accessories").tap do |output|
|
||||
assert_match "Start container with version 123", output
|
||||
assert_hook_ran "pre-deploy", output, **hook_variables
|
||||
assert_match "docker tag dhh/app:123 dhh/app:latest", output
|
||||
assert_match "docker start app-web-123", output
|
||||
assert_match "docker container ls --all --filter name=^app-web-version-to-rollback$ --quiet | xargs docker stop", output, "Should stop the container that was previously running"
|
||||
assert_match "Running the post-deploy hook...", output
|
||||
assert_hook_ran "post-deploy", output, **hook_variables, runtime: "0"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
3
test/integration/docker/deployer/app/.mrsk/hooks/pre-deploy
Executable file
3
test/integration/docker/deployer/app/.mrsk/hooks/pre-deploy
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
echo "Deployed!"
|
||||
mkdir -p /tmp/${TEST_ID} && touch /tmp/${TEST_ID}/pre-deploy
|
||||
@@ -8,16 +8,16 @@ class MainTest < IntegrationTest
|
||||
|
||||
mrsk :deploy
|
||||
assert_app_is_up version: first_version
|
||||
assert_hooks_ran "pre-connect", "pre-build", "post-deploy"
|
||||
assert_hooks_ran "pre-connect", "pre-build", "pre-deploy", "post-deploy"
|
||||
|
||||
second_version = update_app_rev
|
||||
|
||||
mrsk :redeploy
|
||||
assert_app_is_up version: second_version
|
||||
assert_hooks_ran "pre-connect", "pre-build", "post-deploy"
|
||||
assert_hooks_ran "pre-connect", "pre-build", "pre-deploy", "post-deploy"
|
||||
|
||||
mrsk :rollback, first_version
|
||||
assert_hooks_ran "pre-connect", "post-deploy"
|
||||
assert_hooks_ran "pre-connect", "pre-deploy", "post-deploy"
|
||||
assert_app_is_up version: first_version
|
||||
|
||||
details = mrsk :details, capture: true
|
||||
|
||||
Reference in New Issue
Block a user