diff --git a/lib/deploy_pin.rb b/lib/deploy_pin.rb index ded978b..2927bdf 100644 --- a/lib/deploy_pin.rb +++ b/lib/deploy_pin.rb @@ -15,6 +15,7 @@ module DeployPin OPTIONS = %i[ + cleanup_safe_time_window deployment_state_transition fallback_group groups @@ -26,6 +27,7 @@ module DeployPin ].freeze DEFAULTS = { + cleanup_safe_time_window: -> { 1.year }, task_wrapper: ->(_task, task_runner) { task_runner.call } }.freeze diff --git a/lib/deploy_pin/collector.rb b/lib/deploy_pin/collector.rb index 7b842ca..0a70ae0 100644 --- a/lib/deploy_pin/collector.rb +++ b/lib/deploy_pin/collector.rb @@ -26,6 +26,10 @@ def list end end + def cleanup + init_tasks.select(&:classified_for_cleanup?).each(&:remove) + end + def executable # cache tasks tasks = init_tasks diff --git a/lib/deploy_pin/runner.rb b/lib/deploy_pin/runner.rb index 6e2f6f6..9372429 100644 --- a/lib/deploy_pin/runner.rb +++ b/lib/deploy_pin/runner.rb @@ -11,6 +11,10 @@ def self.list(identifiers:) DeployPin::Collector.new(identifiers:).list end + def self.cleanup(identifiers:) + DeployPin::Collector.new(identifiers:).cleanup + end + def self.summary(identifiers:) # print summary self.print('======= Summary ========') diff --git a/lib/deploy_pin/task.rb b/lib/deploy_pin/task.rb index 3009685..45f65e4 100644 --- a/lib/deploy_pin/task.rb +++ b/lib/deploy_pin/task.rb @@ -31,6 +31,11 @@ def run eval(script) end + def remove + File.delete(file) if File.exist?(file) + record&.destroy + end + def record DeployPin::Record.find_by(uuid: identifier) end @@ -71,6 +76,12 @@ def under_timeout? !explicit_timeout? && !parallel? end + def classified_for_cleanup? + return false unless done? + + record.completed_at < DeployPin.cleanup_safe_time_window.call.ago + end + def parse each_line do |line| case line.strip diff --git a/lib/tasks/deploy_pin_tasks.rake b/lib/tasks/deploy_pin_tasks.rake index 6167c91..45ad137 100644 --- a/lib/tasks/deploy_pin_tasks.rake +++ b/lib/tasks/deploy_pin_tasks.rake @@ -1,7 +1,7 @@ # frozen_string_literal: true namespace :deploy_pin do - desc 'run pending tasks' + desc 'Run pending tasks' task :run, [:identifiers] => :environment do |_t, args| identifiers = args.identifiers attributes = identifiers.nil? ? DeployPin.groups : identifiers.split(/\s*,\s*/) @@ -9,10 +9,18 @@ namespace :deploy_pin do DeployPin::Runner.run(identifiers: attributes) end + desc 'List defined tasks' task :list, [:identifiers] => :environment do |_t, args| args.with_defaults(identifiers: DeployPin.groups) DeployPin::Runner.list(**args) DeployPin::Runner.summary(**args) end + + desc 'Remove tasks codebase and DB records for a defined time window' + task cleanup: :environment do + args.with_defaults(identifiers: DeployPin.groups) + + DeployPin::Runner.cleanup(**args) + end end diff --git a/test/lib/deploy_pin/collector_test.rb b/test/lib/deploy_pin/collector_test.rb index 6f25c04..a2d98c5 100644 --- a/test/lib/deploy_pin/collector_test.rb +++ b/test/lib/deploy_pin/collector_test.rb @@ -10,8 +10,8 @@ class DeployPin::Collector::Test < ActiveSupport::TestCase ::FileUtils.cp 'test/support/files/task_same.rb', "#{DeployPin.tasks_path}3_task.rb" ::FileUtils.cp 'test/support/files/other_task.rb', "#{DeployPin.tasks_path}4_task.rb" - # create one completed record - DeployPin::Record.create(uuid: '75371573753754', completed_at: Time.current) + @completed_record = + DeployPin::Record.create(uuid: '75371573753754', completed_at: Time.current) @collector = DeployPin::Collector.new(identifiers: DeployPin.groups) @ids_collector = DeployPin::Collector.new(identifiers: ['75371573753753', '75371573753754!']) @@ -55,6 +55,20 @@ class DeployPin::Collector::Test < ActiveSupport::TestCase end end + test 'cleanup' do + assert_no_difference 'DeployPin::Record.count' do + @collector.cleanup + end + + assert File.exist?("#{DeployPin.tasks_path}4_task.rb") + + assert_difference 'DeployPin::Record.count', -1 do + @collector.cleanup + end + + refute File.exist?("#{DeployPin.tasks_path}4_task.rb") + end + test 'custom task wrapper' do DeployPin.setup do task_wrapper( diff --git a/test/lib/deploy_pin/runner_test.rb b/test/lib/deploy_pin/runner_test.rb index 6a9bd2a..d739c91 100644 --- a/test/lib/deploy_pin/runner_test.rb +++ b/test/lib/deploy_pin/runner_test.rb @@ -10,7 +10,7 @@ class DeployPin::Runner::Test < ActiveSupport::TestCase ::FileUtils.cp 'test/support/files/task_same.rb', "#{DeployPin.tasks_path}3_task.rb" end - test 'sumary' do + test 'summary' do assert_nothing_raised do DeployPin::Runner.summary(identifiers: [DeployPin.fallback_group]) end @@ -33,4 +33,10 @@ class DeployPin::Runner::Test < ActiveSupport::TestCase DeployPin::Runner.list(identifiers: [DeployPin.fallback_group]) end end + + test 'cleanup' do + assert_nothing_raised do + DeployPin::Runner.cleanup(identifiers: DeployPin.groups) + end + end end diff --git a/test/lib/deploy_pin/task_test.rb b/test/lib/deploy_pin/task_test.rb index 8c2aec7..6b4392d 100644 --- a/test/lib/deploy_pin/task_test.rb +++ b/test/lib/deploy_pin/task_test.rb @@ -4,7 +4,9 @@ class DeployPin::Task::Test < ActiveSupport::TestCase setup do - @task = DeployPin::Task.new('test/support/files/task.rb') + @task_file = "#{DeployPin.tasks_path}1_task.rb" + ::FileUtils.cp 'test/support/files/task.rb', @task_file + @task = DeployPin::Task.new(@task_file) end test 'run' do @@ -12,9 +14,9 @@ class DeployPin::Task::Test < ActiveSupport::TestCase end test 'prepare' do - assert_equal DeployPin::Record.where(uuid: @task.identifier).count, 0 - assert_nothing_raised { @task.prepare } - assert_equal DeployPin::Record.where(uuid: @task.identifier).count, 1 + assert_difference 'DeployPin::Record.count', 1 do + assert_nothing_raised { @task.prepare } + end end test 'mark' do @@ -25,9 +27,9 @@ class DeployPin::Task::Test < ActiveSupport::TestCase test 'done?' do @task.prepare assert_nothing_raised { @task.done? } - assert_equal @task.done?, false + refute @task.done? @task.mark - assert_equal @task.done?, true + assert @task.done? end test 'increment_progress!' do @@ -48,6 +50,16 @@ class DeployPin::Task::Test < ActiveSupport::TestCase assert_equal @task.progress, 1 end + test 'remove' do + @task.prepare + + assert_difference 'DeployPin::Record.count', -1 do + assert_nothing_raised { @task.remove } + end + + refute File.exist?(@task_file) + end + test 'parse' do assert_nothing_raised { @task.parse } end @@ -58,30 +70,41 @@ class DeployPin::Task::Test < ActiveSupport::TestCase test 'eql?' do assert_nothing_raised do - @task.eql?(DeployPin::Task.new('test/support/files/task.rb')) + @task.eql?(DeployPin::Task.new(@task_file)) end end test 'explicit_timeout?' do @task.parse - assert_equal @task.send(:explicit_timeout?), false + refute @task.send(:explicit_timeout?) task_with_timeout = DeployPin::Task.new('test/support/files/task_with_timeout.rb') task_with_timeout.parse - assert_equal task_with_timeout.send(:explicit_timeout?), true + assert task_with_timeout.send(:explicit_timeout?) end test 'under_timeout?' do @task.parse - assert_equal @task.under_timeout?, true + assert @task.under_timeout? task_with_timeout = DeployPin::Task.new('test/support/files/task_with_timeout.rb') task_with_timeout.parse - assert_equal task_with_timeout.under_timeout?, false + refute task_with_timeout.under_timeout? parallel_task = DeployPin::Task.new('test/support/files/parallel_task.rb') parallel_task.parse - assert_equal parallel_task.under_timeout?, false + refute parallel_task.under_timeout? + end + + test 'classified_for_cleanup?' do + @task.prepare + refute @task.classified_for_cleanup? + + @task.mark + refute @task.classified_for_cleanup? + + @task.record.update(completed_at: (DeployPin.cleanup_safe_time_window.call + 1.day).ago) + assert @task.classified_for_cleanup? end test 'group_index' do @@ -92,7 +115,7 @@ class DeployPin::Task::Test < ActiveSupport::TestCase test '<=>' do assert_nothing_raised do - @task.send(:<=>, DeployPin::Task.new('test/support/files/task.rb')) + @task.send(:<=>, DeployPin::Task.new(@task_file)) end end end