diff --git a/app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb b/app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb new file mode 100644 index 000000000..f324cef29 --- /dev/null +++ b/app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Maintenance + module RunnableOnDeployConcern + extend ActiveSupport::Concern + + class_methods do + def run_on_first_deploy + @run_on_first_deploy = true + end + + def run_on_deploy? + return false unless @run_on_first_deploy + + task = MaintenanceTasks::TaskDataShow.new(name) + + return false if task.completed_runs.not_errored.any? + return false if task.active_runs.any? + + true + end + end + end +end diff --git a/lib/tasks/deploy.rake b/lib/tasks/deploy.rake index 9ca276237..22c95bc7c 100644 --- a/lib/tasks/deploy.rake +++ b/lib/tasks/deploy.rake @@ -1,4 +1,14 @@ # frozen_string_literal: true +namespace :deploy do + task maintenance_tasks: :environment do + tasks = MaintenanceTasks::Task + .load_all + .filter { _1.respond_to?(:run_on_deploy?) && _1.run_on_deploy? } + + tasks.each do |task| + Rails.logger.info { "MaintenanceTask run on deploy #{task.name}" } + MaintenanceTasks::Runner.run(name: task.name) + end end end diff --git a/lib/templates/maintenance_tasks/task.rb.tt b/lib/templates/maintenance_tasks/task.rb.tt index 2c0b98570..2affa82a5 100644 --- a/lib/templates/maintenance_tasks/task.rb.tt +++ b/lib/templates/maintenance_tasks/task.rb.tt @@ -5,8 +5,13 @@ module <%= tasks_module %> class <%= class_name %>Task < MaintenanceTasks::Task # Documentation: cette tâche modifie les données pour… + include RunnableOnDeployConcern include StatementsHelpersConcern + # Uncomment only if this task MUST run imperatively on its first deployment. + # If possible, leave commented for manual execution later. + # run_on_first_deploy + def collection # Collection to be iterated over # Must be Active Record Relation or Array diff --git a/spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb b/spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb new file mode 100644 index 000000000..7252b1c9a --- /dev/null +++ b/spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Maintenance::RunnableOnDeployConcern do + let(:test_class) do + Class.new do + include Maintenance::RunnableOnDeployConcern + end + end + + describe '.run_on_deploy?' do + context 'when run_on_first_deploy is not set' do + it 'returns false' do + expect(test_class.run_on_deploy?).to be false + end + end + + context 'when run_on_first_deploy is set' do + before do + test_class.run_on_first_deploy + allow(MaintenanceTasks::TaskDataShow).to receive(:new).and_return(task_data_show) + end + + let(:task_data_show) { instance_double(MaintenanceTasks::TaskDataShow, completed_runs: completed_runs, active_runs: active_runs) } + let(:completed_runs) { double(ActiveRecord::Relation, not_errored: not_errored_runs) } + let(:active_runs) { [] } + let(:not_errored_runs) { [] } + + context 'when there are no run yet' do + it 'returns true' do + expect(test_class.run_on_deploy?).to be true + end + end + + context 'when there are completed runs without errors' do + let(:not_errored_runs) { [instance_double(MaintenanceTasks::Run)] } + + it 'returns false' do + expect(test_class.run_on_deploy?).to be false + end + end + + context 'when there are active runs' do + let(:active_runs) { [instance_double(MaintenanceTasks::Run)] } + + it 'returns false' do + expect(test_class.run_on_deploy?).to be false + end + end + end + end +end