Skip to content

Commit 464dbcd

Browse files
Release 2.12.0
2 parents 0bb3e13 + 31df9c6 commit 464dbcd

File tree

7 files changed

+72
-69
lines changed

7 files changed

+72
-69
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
maintenance_tasks (2.11.0)
4+
maintenance_tasks (2.12.0)
55
actionpack (>= 7.0)
66
activejob (>= 7.0)
77
activerecord (>= 7.0)

README.md

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ The generator creates and runs a migration to add the necessary table to your
7474
database. It also mounts Maintenance Tasks in your `config/routes.rb`. By
7575
default the web UI can be accessed in the new `/maintenance_tasks` path.
7676

77-
This gem uses the [Rails Error Reporter](https://guides.rubyonrails.org/error_reporting.html) to report errors. If you are using a bug
78-
tracking service you may want to subscribe to the reporter. See [Reporting Errors](#reporting-errors)
79-
for more information.
77+
This gem uses the [Rails Error Reporter][rails-error-reporting] to report errors.
78+
If you are using a bug tracking service you may want to subscribe to the
79+
reporter. See [Reporting Errors](#reporting-errors) for more information.
80+
81+
[rails-error-reporting]: https://guides.rubyonrails.org/error_reporting.html
8082

8183
### Active Job Dependency
8284

@@ -114,12 +116,12 @@ The typical Maintenance Tasks workflow is as follows:
114116
1. [Generate a class describing the Task](#creating-a-task) and the work to be
115117
done.
116118
2. Run the Task
117-
- either by [using the included web UI](#running-a-task-from-the-web-ui),
118-
- or by [using the command line](#running-a-task-from-the-command-line),
119-
- or by [using Ruby](#running-a-task-from-ruby).
119+
- either by [using the included web UI](#running-a-task-from-the-web-ui),
120+
- or by [using the command line](#running-a-task-from-the-command-line),
121+
- or by [using Ruby](#running-a-task-from-ruby).
120122
3. [Monitor the Task](#monitoring-your-tasks-status)
121-
- either by using the included web UI,
122-
- or by manually checking your task’s run’s status in your database.
123+
- either by using the included web UI,
124+
- or by manually checking your task’s run’s status in your database.
123125
4. Optionally, delete the Task code if you no longer need it.
124126

125127
### Creating a Task
@@ -168,7 +170,8 @@ end
168170
When processing records from an Active Record Relation, records are fetched in
169171
batches internally, and then each record is passed to the `#process` method.
170172
Maintenance Tasks will query the database to fetch records in batches of 100 by
171-
default, but the batch size can be modified using the `collection_batch_size` macro:
173+
default, but the batch size can be modified using the `collection_batch_size`
174+
macro:
172175

173176
```ruby
174177
# app/tasks/maintenance/update_posts_task.rb
@@ -502,33 +505,39 @@ set of values will be used to populate a dropdown in the user interface. The
502505
following types are supported:
503506

504507
* Arrays
505-
* Procs and lambdas that optionally accept the Task instance, and return an Array.
506-
* Callable objects that receive one argument, the Task instance, and return an Array.
508+
* Procs and lambdas that optionally accept the Task instance, and return an
509+
Array.
510+
* Callable objects that receive one argument, the Task instance, and return an
511+
Array.
507512
* Methods that return an Array, called on the Task instance.
508513

509514
For enumerables that don't match the supported types, a text field will be
510515
rendered instead.
511516

512517
### Masking Task Parameters
513-
Task attributes can be masked in the UI by adding `mask_attribute` class method in the
514-
task class.
515-
This will replace the value in the arguments list with `[FILTERED]` in the UI.
518+
519+
Task attributes can be masked in the UI by adding `mask_attribute` class method
520+
in the task class. This will replace the value in the arguments list with
521+
`[FILTERED]` in the UI.
516522

517523
```ruby
518524
# app/tasks/maintenance/sensitive_params_task.rb
519525

520526
module Maintenance
521527
class SensitiveParamsTask < MaintenanceTasks::Task
522528
attribute :sensitive_content, :string
523-
529+
524530
mask_attribute :sensitive_content
525531
end
526532
end
527533
```
528534

529-
If you have any filtered parameters in the global [rails parameter filter](https://guides.rubyonrails.org/configuring.html#config-filter-parameters), they will be
530-
automatically taken into account when masking the parameters, which means that you can mask parameters
531-
across all tasks by adding them to the global rails parameters filter.
535+
If you have any filtered parameters in the global [Rails parameter
536+
filter][rails-parameter-filter], they will be automatically taken into account
537+
when masking the parameters, which means that you can mask parameters across all
538+
tasks by adding them to the global rails parameters filter.
539+
540+
[rails-parameter-filter]:https://guides.rubyonrails.org/configuring.html#config-filter-parameters
532541

533542
```ruby
534543
Rails.application.config.filter_parameters += %i[token]
@@ -924,10 +933,10 @@ a Task can be in:
924933

925934
The Maintenance Tasks engine uses Rails sessions for flash messages and storing
926935
the CSRF token. For the engine to work in an API-only Rails application, you
927-
need to add a [session middleware][] and the `ActionDispatch::Flash`
928-
middleware. The engine also defines a strict [Content Security Policy][], make
929-
sure to include `ActionDispatch::ContentSecurityPolicy::Middleware` in your
930-
app's middleware stack to ensure the CSP is delivered to the user's browser.
936+
need to add a [session middleware][] and the `ActionDispatch::Flash` middleware.
937+
The engine also defines a strict [Content Security Policy][], make sure to
938+
include `ActionDispatch::ContentSecurityPolicy::Middleware` in your app's
939+
middleware stack to ensure the CSP is delivered to the user's browser.
931940

932941
[session middleware]: https://guides.rubyonrails.org/api_app.html#using-session-middlewares
933942
[Content Security Policy]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
@@ -951,8 +960,8 @@ module YourApplication
951960
end
952961
```
953962

954-
You can read more in the [Using Rails for API-only Applications][rails api] Rails
955-
guide.
963+
You can read more in the [Using Rails for API-only Applications][rails api]
964+
Rails guide.
956965

957966
[rails api]: https://guides.rubyonrails.org/api_app.html
958967

@@ -969,9 +978,9 @@ infrastructure or code changes.
969978
This means a Task can safely be interrupted, re-enqueued and resumed without any
970979
intervention at the end of an iteration, after the `process` method returns.
971980

972-
By default, a running Task will be interrupted after running for more than 5 minutes.
973-
This is [configured in the `job-iteration` gem][max-job-runtime] and can be
974-
tweaked in an initializer if necessary.
981+
By default, a running Task will be interrupted after running for more than 5
982+
minutes. This is [configured in the `job-iteration` gem][max-job-runtime] and
983+
can be tweaked in an initializer if necessary.
975984

976985
[max-job-runtime]: https://github.com/Shopify/job-iteration/blob/-/guides/best-practices.md#max-job-runtime
977986

@@ -1018,45 +1027,45 @@ be placed in a `maintenance_tasks.rb` initializer.
10181027
Exceptions raised while a Task is performing are rescued and information about
10191028
the error is persisted and visible in the UI.
10201029

1021-
Errors are also sent to the `Rails.error.reporter`, which can be configured by your
1022-
application. See the [Error Reporting in Rails Applications](https://guides.rubyonrails.org/error_reporting.html) guide for more details.
1030+
Errors are also sent to the `Rails.error.reporter`, which can be configured by
1031+
your application. See the [Error Reporting in Rails
1032+
Applications][rails-error-reporting] guide for more details.
10231033

10241034
Reports to the error reporter will contain the following data:
10251035

10261036
* `error`: The exception that was raised.
1027-
* `context`: A hash with additional information about the Task and the
1028-
error:
1029-
* `task_name`: The name of the Task that errored
1030-
* `started_at`: The time the Task started
1031-
* `ended_at`: The time the Task errored
1032-
* `run_id`: The id of the errored Task run
1033-
* `tick_count`: The tick count at the time of the error
1034-
* `errored_element`: The element, if any, that was being processed when the Task
1035-
raised an exception. If you would like to pass this object to your exception
1036-
monitoring service, make sure you **sanitize the object** to avoid leaking
1037-
sensitive data and **convert it to a format** that is compatible with your bug
1038-
tracker.
1037+
* `context`: A hash with additional information about the Task and the error:
1038+
* `task_name`: The name of the Task that errored
1039+
* `started_at`: The time the Task started
1040+
* `ended_at`: The time the Task errored
1041+
* `run_id`: The id of the errored Task run
1042+
* `tick_count`: The tick count at the time of the error
1043+
* `errored_element`: The element, if any, that was being processed when the
10391044
* `source`: This will be `maintenance-tasks`
10401045

10411046
Note that `context` may be empty if the Task produced an error before any
1042-
context could be gathered (for example, if deserializing the job to process
1043-
your Task failed).
1047+
context could be gathered (for example, if deserializing the job to process your
1048+
Task failed).
10441049

10451050
#### Reporting errors during iteration
10461051

1047-
By default, errors raised during task iteration will be raised to the application
1048-
and iteration will stop. However, you may want to handle some errors and continue
1049-
iteration. `MaintenanceTasks::Task.report_on` can be used to rescue certain
1050-
exceptions and report them to the Rails error reporter. Any keyword arguments are passed to [report](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-report):
1052+
By default, errors raised during task iteration will be raised to the
1053+
application and iteration will stop. However, you may want to handle some errors
1054+
and continue iteration. `MaintenanceTasks::Task.report_on` can be used to rescue
1055+
certain exceptions and report them to the Rails error reporter. Any keyword
1056+
arguments are passed to
1057+
[ActiveSupport::ErrorReporter#report][as-error-reporter-report]:
1058+
1059+
[as-error-reporter-report]: https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-report
10511060

10521061
```ruby
10531062
class MyTask < MaintenanceTasks::Task
10541063
report_on(MyException, OtherException, severity: :info, context: {task_name: "my_task"})
10551064
end
10561065
```
10571066

1058-
`MaintenanceTasks::Task` also includes `ActiveSupport::Rescuable` which you can use
1059-
to implement custom error handling.
1067+
`MaintenanceTasks::Task` also includes `ActiveSupport::Rescuable` which you can
1068+
use to implement custom error handling.
10601069

10611070
```ruby
10621071
class MyTask < MaintenanceTasks::Task

app/helpers/maintenance_tasks/tasks_helper.rb

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,11 @@ def resolve_inclusion_value(task, parameter_name)
150150

151151
# Return the appropriate field tag for the parameter, based on its type.
152152
# If the parameter has a `validates_inclusion_of` validator, return a dropdown list of options instead.
153-
def parameter_field(form_builder, parameter_name, inclusion_values)
154-
return form_builder.select(
155-
parameter_name,
156-
inclusion_values,
157-
{
158-
prompt: "Select a value",
159-
},
160-
) if inclusion_values
153+
def parameter_field(form_builder, parameter_name)
154+
inclusion_values = resolve_inclusion_value(form_builder.object, parameter_name)
155+
if inclusion_values
156+
return tag.div(form_builder.select(parameter_name, inclusion_values, prompt: "Select a value"), class: "select")
157+
end
161158

162159
case form_builder.object.class.attribute_types[parameter_name]
163160
when ActiveModel::Type::Integer
@@ -175,6 +172,7 @@ def parameter_field(form_builder, parameter_name, inclusion_values)
175172
else
176173
form_builder.text_area(parameter_name, class: "textarea")
177174
end
175+
.then { |input| tag.div(input, class: "control") }
178176
end
179177

180178
# Return helper text for the datetime-local form field.

app/views/layouts/maintenance_tasks/application.html.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
<%= csrf_meta_tags %>
1616

1717
<%=
18-
stylesheet_link_tag(URI.join(controller.class::BULMA_CDN, 'npm/[email protected]/css/versions/bulma-no-dark-mode.min.css'),
18+
stylesheet_link_tag(URI.join(controller.class::BULMA_CDN, "npm/[email protected]/css/versions/bulma-no-dark-mode.min.css"),
1919
media: :all,
20-
integrity: 'Mzv683sNGpHoqzflgja8HtOOXwSkg0WYgbi6iV3IjnOLZAsGNzzkdXxfHmJYT5dY',
21-
crossorigin: 'anonymous') unless request.xhr?
20+
integrity: "sha256-HCNMQcqH/4MnGR0EYg2S3/BXYMM1z9lrFV10ANRd79o",
21+
crossorigin: "anonymous") unless request.xhr?
2222
%>
2323

2424
<style>

app/views/maintenance_tasks/tasks/show.html.erb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
<% parameter_names.each do |parameter_name| %>
2020
<div class="cell">
2121
<%= ff.label parameter_name, parameter_name, class: ["label", "is-family-monospace", { "is-required": attribute_required?(ff.object, parameter_name) }] %>
22-
<% inclusion_values = resolve_inclusion_value(ff.object, parameter_name) %>
23-
<div class="<%= inclusion_values.is_a?(Array) ? "select" : "control" %>">
24-
<%= parameter_field(ff, parameter_name, inclusion_values) %>
25-
</div>
22+
<%= parameter_field(ff, parameter_name) %>
2623
</div>
2724
<% end %>
2825
<% end %>
@@ -59,7 +56,7 @@
5956

6057
<h4 class="title is-5 has-text-weight-bold">Previous Runs</h4>
6158

62-
<%= render partial: "maintenance_tasks/runs/run", collection: @task.runs_page.records, as: :run %>
59+
<%= render partial: "maintenance_tasks/runs/run", collection: @task.runs_page.records %>
6360

6461
<%= link_to "Next page", task_path(@task, cursor: @task.runs_page.next_cursor) unless @task.runs_page.last? %>
6562
<% end %>

maintenance_tasks.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Gem::Specification.new do |spec|
44
spec.name = "maintenance_tasks"
5-
spec.version = "2.11.0"
5+
spec.version = "2.12.0"
66
spec.author = "Shopify Engineering"
77
spec.email = "[email protected]"
88
spec.homepage = "https://github.com/Shopify/maintenance_tasks"

test/helpers/maintenance_tasks/tasks_helper_test.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ def with_zone_default(new_zone)
162162
def markup(attribute)
163163
render(inline: <<~TEMPLATE)
164164
<%= fields_for(Maintenance::ParamsTask.new) do |form| %>
165-
<% inclusion_values = resolve_inclusion_value(form.object, '#{attribute}') %>
166-
<%= parameter_field(form, '#{attribute}', inclusion_values) %>
165+
<%= parameter_field(form, '#{attribute}') %>
167166
<% end %>
168167
TEMPLATE
169168
end

0 commit comments

Comments
 (0)