deploy_pin 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2862b9b718d5a1ce6d6b6af0c10846f1915d7c0a70f13e68c96b2f69d1304bcc
4
- data.tar.gz: c849c787465e4022faf6f10674ce53c7e67c71b68f1a2921de3f3e71ae64f8ac
3
+ metadata.gz: a4dfa8e844cfa02e0324e4af067d6ac5a8e3d8b7829a90970bf7db6cb60cdb47
4
+ data.tar.gz: caf02bfb5aaa6e6edd82f83bacef7113f0c62de799cbfebe45b94d88d71553e1
5
5
  SHA512:
6
- metadata.gz: a6bfd839077a2ca9ccdc75232fb376707ac87475bc6504f365991d01fdd4da81c15617605cc746fb8b1ada5a6dc3da8465b2382b9811f108accbc9a45080e6ff
7
- data.tar.gz: f7ef8afae96a3ab5802a5f91de36248637c8eb003a7cbfdb168006373e65c5669360f9cf618f51daff082d41efe34b6ce2c0172cca7e8570717c793a8bc05542
6
+ metadata.gz: '0909b4f5366aeeb71e51cacf70d72d08a18486eab638d428950a53e6735155afb6af6bcab7c48095511372a18b9deac024a25adb291fab2206c79e63a61a9175'
7
+ data.tar.gz: ce86dd3f2c2f7d6c3ec2957e1c1cb3eab4618aa88979b61418d6ca03fa2e9c5c59651aa5db630df166c1da05e9c126829e0b3823dd18ce3a0c8b733092fdbf33
data/README.md CHANGED
@@ -1,121 +1,122 @@
1
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
1
2
  [![Gem Version](https://badge.fury.io/rb/deploy_pin.svg)](https://badge.fury.io/rb/deploy_pin)
2
3
  ![](https://ruby-gem-downloads-badge.herokuapp.com/deploy_pin)
3
- ![example workflow](https://github.com/skcc321/deploy_pin/actions/workflows/verify.yml/badge.svg)
4
+ [![Verification](https://github.com/skcc321/deploy_pin/actions/workflows/verify.yml/badge.svg)](https://github.com/skcc321/deploy_pin/actions/workflows/verify.yml)
5
+ [![Publish Gem](https://github.com/skcc321/deploy_pin/actions/workflows/publish.yml/badge.svg)](https://github.com/skcc321/deploy_pin/actions/workflows/publish.yml)
4
6
 
5
7
  # DeployPin
6
8
 
7
9
  ![DeployPin](http://hereisfree.com/content1//pic/zip/2009109935062477801.jpg)
8
10
 
9
- Sometimes we need to execute set of commands (tasks) after/before deployment.
10
- Most likely you use migrations for such things, but that is not what is related to migration at all.
11
- Also sometimes you need to execute some code before migration or later, after migration without blocking of main thread.
11
+ Deploying applications often involves the need to execute a series of specific commands or tasks either before or after the deployment process. While you might typically turn to migrations for such operations, these tasks aren't always migration-related. Additionally, there are situations where you need to execute code before or after a migration without causing the main thread to block.
12
12
 
13
- deploy_pins is exactly what you need.
13
+ Introducing deploy_pins your go-to solution for streamlined task management during the deployment process. This Ruby library allows you to seamlessly orchestrate tasks before, after, or independently of migrations, offering the flexibility you need to maintain a smooth and efficient deployment workflow. With deploy_pins, you can take control of your deployment tasks and ensure that your application operates flawlessly in any environment.
14
14
 
15
15
  ## Usage
16
16
 
17
-
18
17
  ![DeployPin](deploy_pin.gif)
19
18
 
20
- To generate new task template file
19
+ To generate a new task template file:
21
20
  ```bash
22
21
  rails g deploy_pin:task some_task_title
23
22
  # or
24
23
  rails g deploy_pin:task some_task_title --parallel
25
24
  ```
26
25
 
27
- Also, you can specify author
26
+ You can also specify the author:
28
27
  ```bash
29
28
  rails g deploy_pin:task some_task_title -a author_name
30
29
  ```
31
30
 
32
- To list all pending tasks
31
+ To list all pending tasks:
33
32
  ```bash
34
33
  rake deploy_pin:list
35
34
  ```
36
35
 
37
- To run all pending tasks
36
+ To run all pending tasks:
38
37
  ```bash
39
38
  rake deploy_pin:run
40
39
  ```
41
40
 
42
- ## Groupped tasks
41
+ ## Grouped Tasks
43
42
 
44
- Please define allowed groups in `config/initializers/deploy_pin.rb`
45
- if you want to group tasks around "allowed_group"
43
+ To define allowed groups, navigate to `config/initializers/deploy_pin.rb`. You can group tasks around the "allowed_group" like this:
46
44
  ```bash
47
45
  rails g deploy_pin:task task_title -g allowed_group
48
46
  # or
49
47
  rails g deploy_pin:task task_title -g allowed_group --parallel
50
48
  ```
51
49
 
52
- To list all pending tasks
50
+ To list all pending tasks within the "allowed_group":
53
51
  ```bash
54
52
  rake deploy_pin:list[allowed_group]
55
53
  ```
56
54
 
57
- To run all pending tasks
55
+ To run all pending tasks within the "allowed_group":
58
56
  ```bash
59
57
  rake deploy_pin:run[allowed_group]
60
58
  ```
61
59
 
62
- ## Run by uuid
60
+ ## Run by Identifier
63
61
 
64
- To run some specific task by uuid
62
+ To execute a specific task using its identifier:
65
63
  ```bash
66
- rake deploy_pin:run['uuid_1, uuid_2']
64
+ rake deploy_pin:run['identifier_1, identifier_2']
67
65
  ```
68
- Or you can combine uuid and group
66
+
67
+ Alternatively, you can combine an identifier and a group:
69
68
  ```bash
70
- rake deploy_pin:run['uuid, allowed_group']
69
+ rake deploy_pin:run['identifier, allowed_group']
71
70
  ```
72
- In case if you want to rerun task you should add exclamation mark in the end of uuid
71
+
72
+ If you wish to rerun a task, add an exclamation mark at the end of the identifier:
73
73
  ```bash
74
- rake deploy_pin:run['uuid_1!, uuid_2!']
74
+ rake deploy_pin:run['identifier_1!, identifier_2!']
75
75
  ```
76
76
 
77
77
  ## Installation
78
78
 
79
-
80
79
  Add this line to your application's Gemfile:
81
80
 
82
81
  ```ruby
83
82
  gem 'deploy_pin'
84
83
  ```
85
84
 
86
- And then execute:
85
+ Then execute:
87
86
  ```bash
88
87
  $ bundle
89
88
  ```
90
89
 
91
- Or install it yourself as:
90
+ You can also install it manually with:
92
91
  ```bash
93
92
  $ gem install deploy_pin
94
93
  ```
95
94
 
96
- then generate configuration file
95
+ Afterward, generate the configuration file:
97
96
  ```bash
98
97
  rails g deploy_pin:install
99
98
  ```
100
99
 
101
- and run migration
100
+ Finally, run the migration:
102
101
  ```bash
103
102
  rake db:migrate
104
103
  ```
105
104
 
106
105
  ## Database Timeout
107
- By default, deploy_pin will run all the non-parallel tasks under a database statement timeout.
108
- A default value must be defined in the deploy_pin initializer. Ex.:
106
+
107
+ By default, deploy_pin runs all non-parallel tasks under a database statement timeout. To set a default value, you should define it in the deploy_pin initializer, for example:
108
+
109
109
  ```ruby
110
110
  # config/initializers/deploy_pin.rb
111
111
  DeployPin.setup do
112
- statement_timeout 0.2.second # 200 ms
112
+ statement_timeout 0.2.seconds # 200 ms
113
113
  end
114
114
  ```
115
115
 
116
- In order to not use the default value, it's required to use explicitly in the task, like:
116
+ If you want to use a different value than the default, you need to specify it explicitly in the task, as shown below:
117
+
117
118
  ```ruby
118
- # Some deploy_pin task
119
+ # Some deploy_pin task
119
120
  # 20190401135040:I
120
121
  # task_title: Execute some query with timeout
121
122
 
@@ -125,28 +126,26 @@ DeployPin::Database::execute_with_timeout do
125
126
  end
126
127
  ```
127
128
 
128
- To know more about the params, please check the documentation [here](lib/deploy_pin/database.rb).
129
+ For more information about the parameters, please refer to the documentation [here](lib/deploy_pin/database.rb).
129
130
 
130
131
  ## Parallel
131
- To run parallel tasks using timeout, it's required to use the parallel wrapper, which mimics parallel interface,
132
- but adding the timeout option.
133
132
 
134
- In a deploy_pin task, instead of using `Parallel.each(1..2, in_processes: 2)`, use:
133
+ To run parallel tasks using a timeout, you need to use the parallel wrapper, which mimics the parallel interface but adds the timeout option. In a deploy_pin task, instead of using `Parallel.each(1..2, in_processes: 2)`, use:
134
+
135
135
  ```ruby
136
136
  parallel_each(1..2, in_processes: 2, timeout: 0.3.seconds) do |i|
137
- # ActiveRecord::Base.connection_pool.with_connection it's already include in the parallel wrapper.
137
+ # ActiveRecord::Base.connection_pool.with_connection is already included in the parallel wrapper.
138
138
  puts "Item: #{i}, Worker: #{Parallel.worker_number}"
139
139
  ActiveRecord::Base.connection.execute("<some db query>")
140
140
  end
141
141
  ```
142
142
 
143
- Check the documentation [here](lib/deploy_pin/parallel_wrapper.rb).
143
+ Check the documentation [here](lib/deploy_pin/parallel_wrapper.rb) for more details.
144
144
 
145
145
  ## Formatting
146
- `run_formatter` is used to format the output of a `run` task
147
- `list_formatter` is used to format the output of a `list` task
148
146
 
149
- A default value must be defined in the deploy_pin initializer. Ex.:
147
+ `run_formatter` is used to format the output of a `run` task, and `list_formatter` is used to format the output of a `list` task. To set a default value, you should define it in the deploy_pin initializer:
148
+
150
149
  ```ruby
151
150
  # config/initializers/deploy_pin.rb
152
151
  DeployPin.setup do
@@ -158,14 +157,14 @@ DeployPin.setup do
158
157
  "(Skipped)\n\n"
159
158
  end
160
159
 
161
- puts("[#{index + 1}/#{task_count}] Task #{task.title} #{task.uuid}##{task.group} #{end_of_msg}".blue.bold)
160
+ puts("[#{index + 1}/#{task_count}] Task #{task.title} #{task.identifier}##{task.group} #{end_of_msg}".blue.bold)
162
161
  end
163
162
  )
164
163
  list_formatter(
165
164
  lambda do |index, task|
166
165
  puts("======= Task ##{index} ========".blue.bold)
167
166
 
168
- # print details
167
+ # Print details
169
168
  task.details.each do |key, value|
170
169
  puts("#{key}:\t\t#{value}")
171
170
  end
@@ -176,16 +175,42 @@ DeployPin.setup do
176
175
  end
177
176
  ```
178
177
 
179
- In order to not use the default value, it's required to use explicitly in the task, like:
178
+ To use a different formatting value than the default, you need to specify it explicitly in the task, similar to the database timeout configuration.
179
+
180
+ ## Recurring Tasks
181
+ If you want to generate a recurring task, you can use the `--recurring` option. Make sure to set a correct `--identifier`, which should be a numeric value. Positive and negative numbers are possible here. The identifier affects the order of task execution, allowing you to customize the sequence as desired.
182
+
183
+ Please note that two identifiers, 0 and -10, are already reserved for deployment state tracking. Avoid using these identifiers.
184
+
185
+ ```bash
186
+ rails g deploy_pin:task some_task_title --recurring --identifier 5
187
+ # or
188
+ rails g deploy_pin:task some_task_title --parallel --recurring --identifier 5
189
+ ```
190
+
191
+ ## DeploymentStateTrack
192
+ In the initializer
180
193
  ```ruby
181
- # Some deploy_pin task
182
- # 20190401135040:I
183
- # task_title: Execute some query with timeout
194
+ DeployPin.setup do
195
+ groups %w[I II III post rollback]
196
+ ...
197
+ deployment_state_transition({
198
+ ongoing: %w[I III],
199
+ pending: "rollback", # enters to pending step before "rollback"
200
+ ttl: 20.second, # memoize the state to avoid Redis spam
201
+ redis_url: "redis://localhost:6379"
202
+ })
203
+ end
184
204
 
185
- # === task code goes down here ===
186
- DeployPin::Database::execute_with_timeout do
187
- ActiveRecord::Base.connection.execute("select * from shipments;")
188
- end
205
+ # enabled next methods
206
+ DeployPin.ongoing_deployment?
207
+ DeployPin.pending_deployment?
208
+ ```
209
+
210
+ Around the deployment
211
+ ```bash
212
+ bundle exec rake deploy_pin:run[I, II, III] - # enters to ongoing state before "I" and leaves it after "III" so all tasks in I, II, III have DeployPin.oingoing_deployment? == true
213
+ bundle exec rake deploy_pin:run[rollback] - # enters "pending state"
189
214
  ```
190
215
 
191
216
  ## Contributing
@@ -66,9 +66,9 @@ module DeployPin
66
66
  end
67
67
 
68
68
  def tasks
69
- files.map do |file|
69
+ [*DeployPin.deployment_tasks_code, *files].map do |file|
70
70
  task = DeployPin::Task.new(file)
71
- task.parse_file
71
+ task.parse
72
72
 
73
73
  # check if task is suitable
74
74
  task if task_criteria.suitable?(task)
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'connection_pool'
4
+ require 'redis'
5
+
6
+ # This module is used to track the state of a deployment.
7
+ module DeployPin
8
+ # The mixin that extends DeployPin module with
9
+ # @ongoing_deployment? & @pending_deployment? methods
10
+ module DeploymentState
11
+ STORE_KEY = 'deploy_pin:deployment'
12
+ ONGOING = 'ongoing'
13
+ PENDING = 'pending'
14
+
15
+ DEPLOYMENT_OVER_TASK = %(
16
+ # no_file_task
17
+ # -10:%<group>s:recurring
18
+ # task_title: Cleanup DeployPin.state
19
+
20
+ DeployPin.send(:deployment_over!)
21
+ ).strip
22
+
23
+ DEPLOYMENT_ONGOING_TASK = %(
24
+ # no_file_task
25
+ # 0:%<group>s:recurring
26
+ # task_title: Set DeployPin.state to 'ongoing'
27
+
28
+ DeployPin.send(:deployment_ongoing!)
29
+ ).strip
30
+
31
+ DEPLOYMENT_PENDING_TASK = %(
32
+ # no_file_task
33
+ # 0:%<group>s:recurring
34
+ # task_title: Set DeployPin.state to 'pending'
35
+
36
+ DeployPin.send(:deployment_pending!)
37
+ ).strip
38
+
39
+ def ongoing_deployment?
40
+ deployment_state == ONGOING
41
+ end
42
+
43
+ def pending_deployment?
44
+ deployment_state == PENDING
45
+ end
46
+
47
+ def deployment_tasks_code
48
+ return [] unless DeployPin.enabled?(:deployment_state_transition)
49
+
50
+ ongoing_start_group, ongoing_end_group = DeployPin.deployment_state_transition[:ongoing]
51
+ rollback_group = DeployPin.deployment_state_transition[:pending]
52
+
53
+ [
54
+ format(DEPLOYMENT_ONGOING_TASK, group: ongoing_start_group),
55
+ format(DEPLOYMENT_OVER_TASK, group: ongoing_end_group),
56
+ format(DEPLOYMENT_PENDING_TASK, group: rollback_group)
57
+ ]
58
+ end
59
+
60
+ protected
61
+
62
+ def deployment_over!
63
+ in_memory_store.delete(:deployment)
64
+ persistent_store.del(STORE_KEY)
65
+ end
66
+
67
+ def deployment_ongoing!
68
+ persistent_store.set(STORE_KEY, ONGOING)
69
+ end
70
+
71
+ def deployment_pending!
72
+ persistent_store.set(STORE_KEY, PENDING)
73
+ end
74
+
75
+ private
76
+
77
+ def in_memory_store
78
+ Thread.current[:deploy_pin] ||= {}
79
+ end
80
+
81
+ def persistent_store
82
+ @persistent_store ||= ConnectionPool::Wrapper.new do
83
+ Redis.new(url: DeployPin.deployment_state_transition[:redis_url])
84
+ end
85
+ end
86
+
87
+ def deployment_state
88
+ state = in_memory_store[:deployment] || {}
89
+
90
+ if state.blank? || state[:expiration] < Time.current
91
+ in_memory_store[:deployment] = {
92
+ expiration: DeployPin.deployment_state_transition[:ttl].from_now,
93
+ state: persistent_store.get(STORE_KEY)
94
+ }
95
+ end
96
+
97
+ in_memory_store[:deployment][:state]
98
+ end
99
+ end
100
+
101
+ extend DeploymentState
102
+ end
@@ -7,15 +7,16 @@ module DeployPin
7
7
  include ::DeployPin::ParallelWrapper
8
8
 
9
9
  attr_reader :file,
10
- :uuid,
10
+ :identifier,
11
11
  :group,
12
12
  :title,
13
13
  :script,
14
+ :recurring,
14
15
  :explicit_timeout
15
16
 
16
17
  def initialize(file)
17
18
  @file = file
18
- @uuid = nil
19
+ @identifier = nil
19
20
  @group = nil
20
21
  @title = ''
21
22
  @script = ''
@@ -29,24 +30,29 @@ module DeployPin
29
30
  end
30
31
 
31
32
  def mark
33
+ return if recurring
34
+
32
35
  # store record in the DB
33
- DeployPin::Record.create(uuid: uuid)
36
+ DeployPin::Record.create(uuid: identifier)
34
37
  end
35
38
 
36
39
  def done?
37
- DeployPin::Record.where(uuid: uuid).exists?
40
+ return if recurring
41
+
42
+ DeployPin::Record.where(uuid: identifier).exists?
38
43
  end
39
44
 
40
45
  def under_timeout?
41
46
  !explicit_timeout? && !parallel?
42
47
  end
43
48
 
44
- def parse_file
45
- File.foreach(file) do |line|
49
+ def parse
50
+ each_line do |line|
46
51
  case line.strip
47
- when /\A# (\d+):(\w+)/
48
- @uuid = Regexp.last_match(1)
52
+ when /\A# (-?\d+):(\w+):?(recurring)?/
53
+ @identifier = Regexp.last_match(1).to_i
49
54
  @group = Regexp.last_match(2)
55
+ @recurring = Regexp.last_match(3)
50
56
  when /\A# task_title:(.+)/
51
57
  @title = Regexp.last_match(1).strip
52
58
  when /\A[^#].*/
@@ -58,25 +64,46 @@ module DeployPin
58
64
  end
59
65
  end
60
66
 
67
+ def each_line(&block)
68
+ if file.starts_with?('# no_file_task')
69
+ file.each_line(&block)
70
+ else
71
+ File.foreach(file, &block)
72
+ end
73
+ end
74
+
61
75
  def details
62
76
  {
63
- uuid: uuid,
77
+ identifier: identifier,
64
78
  group: group,
65
79
  title: title
66
80
  }
67
81
  end
68
82
 
69
83
  def eql?(other)
70
- # same script & different uuid
71
- script == other.script && uuid != other.uuid
84
+ # same script & different identifier
85
+ script == other.script && identifier != other.identifier
72
86
  end
73
87
 
74
- protected
88
+ def unreachable_future
89
+ 1.year.from_now.to_date.strftime('%Y%m%d%H%M%S').to_i
90
+ end
75
91
 
76
- # for sorting
77
- def <=>(other)
78
- group_index <=> other.group_index
92
+ def sorting_key
93
+ if identifier.to_i.negative?
94
+ [group_index, unreachable_future + identifier]
95
+ else
96
+ [group_index, identifier]
79
97
  end
98
+ end
99
+
100
+ # for sorting
101
+ def <=>(other)
102
+ sorting_key <=> other.sorting_key
103
+ end
104
+
105
+ protected
106
+
80
107
 
81
108
  def group_index
82
109
  DeployPin.groups.index(group)
@@ -3,9 +3,9 @@
3
3
  # check task criteria
4
4
  module DeployPin
5
5
  class TaskCriteria
6
- SKIP_REGEXEP = /\A-(.+[^!])\z/.freeze
7
- FORCE_REGEXP = /\A([^-].+)!\z/.freeze
8
- COMMON_REGEXP = /(^[^-]*.+[^!]*$)/.freeze
6
+ SKIP_REGEXEP = /\A!(.+[^!])\z/
7
+ FORCE_REGEXP = /\A([^!].+)!\z/
8
+ COMMON_REGEXP = /(^[^!]?.+[^!]?$)/
9
9
 
10
10
  attr_reader :identifiers
11
11
 
@@ -17,7 +17,7 @@ module DeployPin
17
17
  task_cover = lambda { |task, regexp|
18
18
  items = identifiers.flat_map { |x| x.to_s.scan(regexp) }.flatten
19
19
 
20
- items & [task.group, task.uuid]
20
+ items & [task.group, task.identifier.to_s]
21
21
  }
22
22
 
23
23
  return false if task_cover.call(task, SKIP_REGEXEP).any?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeployPin
4
- VERSION = '1.4.0'
4
+ VERSION = '1.5.0'
5
5
  end
data/lib/deploy_pin.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'deploy_pin/deployment_state'
3
4
  require 'deploy_pin/runner'
4
5
  require 'deploy_pin/collector'
5
6
  require 'deploy_pin/parallel_wrapper'
@@ -20,8 +21,13 @@ module DeployPin
20
21
  run_formatter
21
22
  list_formatter
22
23
  task_wrapper
24
+ deployment_state_transition
23
25
  ].freeze
24
26
 
27
+ DEFAULTS = {
28
+ task_wrapper: ->(_task, task_runner) { task_runner.call }
29
+ }.freeze
30
+
25
31
  OPTIONS.each do |option|
26
32
  instance_eval %{
27
33
  def #{option}(val = nil)
@@ -37,8 +43,14 @@ module DeployPin
37
43
  end
38
44
 
39
45
  def self.setup_defaults!
40
- @task_wrapper = ->(_task, task_runner) { task_runner.call }
46
+ DEFAULTS.each do |option, value|
47
+ instance_variable_set(:"@#{option}", value)
48
+ end
41
49
  end
42
50
 
43
51
  setup_defaults!
52
+
53
+ def self.enabled?(option)
54
+ instance_variable_defined?("@#{option}")
55
+ end
44
56
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreateDeployPins < ActiveRecord::Migration[5.2]
3
+ class CreateDeployPins < ActiveRecord::Migration[7.0]
4
4
  def change
5
5
  create_table :deploy_pins do |t|
6
6
  t.string :uuid
@@ -2,9 +2,15 @@
2
2
 
3
3
  DeployPin.setup do
4
4
  tasks_path 'lib/deploy_pin'
5
- groups %w[I II III]
6
- fallback_group 'II'
5
+ groups %w[pre I II III]
6
+ fallback_group 'III'
7
7
  statement_timeout 10.minutes
8
+ deployment_state_transition({
9
+ ongoing: %w[I III],
10
+ pending: 'rollback', # enters to pending step before "rollback"
11
+ ttl: 20.second, # memoize the state to avoid the store spam
12
+ redis_url: 'redis://localhost:6379'
13
+ })
8
14
  run_formatter(
9
15
  lambda do |index, task_count, task, executable, start, duration = nil|
10
16
  end_of_msg = if executable
@@ -13,7 +19,7 @@ DeployPin.setup do
13
19
  "(Skipped)\n\n"
14
20
  end
15
21
 
16
- puts("[#{index + 1}/#{task_count}] Task #{task.title} #{task.uuid}##{task.group} #{end_of_msg}".blue.bold)
22
+ puts("[#{index + 1}/#{task_count}] Task #{task.title} #{task.identifier}##{task.group} #{end_of_msg}".blue.bold)
17
23
  end
18
24
  )
19
25
  list_formatter(
@@ -2,7 +2,9 @@
2
2
 
3
3
  module DeployPin
4
4
  class TaskGenerator < Rails::Generators::Base
5
- class_option :parallel, type: :boolean
5
+ class_option :parallel, type: :boolean, aliases: '-p'
6
+ class_option :recurring, type: :boolean, aliases: '-r'
7
+ class_option :identifier, aliases: '-i'
6
8
  argument :title, required: true
7
9
  class_option :group, aliases: '-g', default: DeployPin.fallback_group
8
10
  class_option :author, aliases: '-a'
@@ -19,8 +21,10 @@ module DeployPin
19
21
 
20
22
  @author = options[:author] || ENV['USER']
21
23
  @group = options[:group]
22
- @uuid = Time.now.strftime('%Y%m%d%H%M%S')
23
- template template_file, "#{DeployPin.tasks_path}/#{@uuid}_#{title}.rb"
24
+ @recurring = options[:recurring]
25
+ @identifier = @recurring ? options[:identifier] : Time.now.strftime('%Y%m%d%H%M%S')
26
+ filename = @recurring ? "r_#{@identifier}_#{title}.rb" : "#{@identifier}_#{title}.rb"
27
+ template template_file, "#{DeployPin.tasks_path}/#{filename}"
24
28
  end
25
29
  end
26
30
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # <%= @uuid %>:<%= @group %>
3
+ # <%= @identifier %>:<%= @group %><%= @recurring ? ":recurring" : "" %>
4
4
  # task_title: <%= @author ? "@#{@author} #{title.titleize}" : "#{title.titleize}" %>
5
5
 
6
6
  # === parallel task code goes down here ===
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # <%= @uuid %>:<%= @group %>
3
+ # <%= @identifier %>:<%= @group %><%= @recurring ? ":recurring" : "" %>
4
4
  # task_title: <%= @author ? "@#{@author} #{title.titleize}" : "#{title.titleize}" %>
5
5
 
6
6
  # === task code goes down here ===
metadata CHANGED
@@ -1,71 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deploy_pin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Viktor Sych
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-12 00:00:00.000000000 Z
11
+ date: 2023-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: connection_pool
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: parallel
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '1.16'
47
+ version: '1.23'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '1.16'
54
+ version: '1.23'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rails
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ">="
59
+ - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 6.0.1
61
+ version: '7.0'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ">="
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '7.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">"
53
81
  - !ruby/object:Gem::Version
54
- version: 6.0.1
82
+ version: '4.0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: ruby-progressbar
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '1.10'
89
+ version: '1.13'
62
90
  type: :runtime
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '1.10'
96
+ version: '1.13'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: bundler
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -207,6 +235,7 @@ files:
207
235
  - lib/deploy_pin.rb
208
236
  - lib/deploy_pin/collector.rb
209
237
  - lib/deploy_pin/database.rb
238
+ - lib/deploy_pin/deployment_state.rb
210
239
  - lib/deploy_pin/engine.rb
211
240
  - lib/deploy_pin/parallel_wrapper.rb
212
241
  - lib/deploy_pin/runner.rb
@@ -227,7 +256,7 @@ licenses:
227
256
  - MIT
228
257
  metadata:
229
258
  allowed_push_host: https://rubygems.org
230
- post_install_message:
259
+ post_install_message:
231
260
  rdoc_options: []
232
261
  require_paths:
233
262
  - lib
@@ -235,15 +264,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
235
264
  requirements:
236
265
  - - ">="
237
266
  - !ruby/object:Gem::Version
238
- version: '2.7'
267
+ version: '3.0'
239
268
  required_rubygems_version: !ruby/object:Gem::Requirement
240
269
  requirements:
241
270
  - - ">="
242
271
  - !ruby/object:Gem::Version
243
272
  version: '0'
244
273
  requirements: []
245
- rubygems_version: 3.1.6
246
- signing_key:
274
+ rubygems_version: 3.4.10
275
+ signing_key:
247
276
  specification_version: 4
248
277
  summary: pin some task around deployment
249
278
  test_files: []