process_bot 0.1.26 → 0.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -35
- data/lib/process_bot/process/handlers/custom.rb +8 -1
- data/lib/process_bot/process.rb +68 -2
- data/lib/process_bot/version.rb +1 -1
- data/lib/tasks/release.rake +171 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 016c72db98675857edb0e34b274af5cc835d0cd5496d4bb6fccb7ebdaf05c555
|
|
4
|
+
data.tar.gz: 51a18efde6ff957df0dfe6f8e07e9df2f341a1519b3f17356de1ef7422f21e85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f2387a26b91b32675f6679af84f4e4096bde512f62f344a962a0312abea804395e6013b88f268c20094a04724f27c71680c421f63893c785f47586b472f68ff8
|
|
7
|
+
data.tar.gz: '0491239c4e11851cfef5704cbbc9e79611c356595192f5187199fd3a7c898f7e61e5885a302ed84cdedb53692a4bf7e89369791fe69a169663273d95b5f4ebd8'
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
|
@@ -7,40 +7,6 @@ require "rubocop/rake_task"
|
|
|
7
7
|
RSpec::Core::RakeTask.new(:spec)
|
|
8
8
|
RuboCop::RakeTask.new
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
version_content = File.read(version_path)
|
|
12
|
-
version_match = version_content.match(/VERSION = "(\d+)\.(\d+)\.(\d+)"\.freeze/)
|
|
13
|
-
raise "Could not find current version in #{version_path}" unless version_match
|
|
14
|
-
|
|
15
|
-
major = version_match[1].to_i
|
|
16
|
-
minor = version_match[2].to_i
|
|
17
|
-
patch = version_match[3].to_i + 1
|
|
18
|
-
|
|
19
|
-
new_version = "#{major}.#{minor}.#{patch}"
|
|
20
|
-
new_content = version_content.sub(version_match[0], "VERSION = \"#{new_version}\".freeze")
|
|
21
|
-
File.write(version_path, new_content)
|
|
22
|
-
|
|
23
|
-
new_version
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
namespace :release do
|
|
27
|
-
desc "Bump patch version, run bundle, commit version bump, build gem, and push gem"
|
|
28
|
-
task :patch do
|
|
29
|
-
version_path = "lib/process_bot/version.rb"
|
|
30
|
-
new_version = bump_patch_version(version_path)
|
|
31
|
-
|
|
32
|
-
puts "Bumped version to #{new_version}"
|
|
33
|
-
|
|
34
|
-
sh "bundle install"
|
|
35
|
-
sh "git add #{version_path}"
|
|
36
|
-
sh "git commit -m \"Bump version to #{new_version}\""
|
|
37
|
-
sh "bundle exec rake build"
|
|
38
|
-
|
|
39
|
-
gem_path = "pkg/process_bot-#{new_version}.gem"
|
|
40
|
-
raise "Expected gem file was not built: #{gem_path}" unless File.exist?(gem_path)
|
|
41
|
-
|
|
42
|
-
sh "gem push #{gem_path}"
|
|
43
|
-
end
|
|
44
|
-
end
|
|
10
|
+
Dir[File.expand_path("../lib/tasks/**/*.rake", __FILE__)].each { |f| load f }
|
|
45
11
|
|
|
46
12
|
task default: %i[spec rubocop]
|
|
@@ -48,7 +48,14 @@ class ProcessBot::Process::Handlers::Custom
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def stop(**_args)
|
|
51
|
+
runner = process.active_runner
|
|
52
|
+
|
|
53
|
+
unless runner
|
|
54
|
+
logger.logs "No active runner to stop"
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
|
|
51
58
|
logger.logs "Stop related processes"
|
|
52
|
-
|
|
59
|
+
runner.stop_related_processes
|
|
53
60
|
end
|
|
54
61
|
end
|
data/lib/process_bot/process.rb
CHANGED
|
@@ -3,7 +3,7 @@ require "json"
|
|
|
3
3
|
require "monitor"
|
|
4
4
|
require "string-cases"
|
|
5
5
|
|
|
6
|
-
class ProcessBot::Process
|
|
6
|
+
class ProcessBot::Process # rubocop:disable Metrics/ClassLength
|
|
7
7
|
extend Forwardable
|
|
8
8
|
|
|
9
9
|
def_delegator :handler_instance, :graceful
|
|
@@ -131,8 +131,15 @@ class ProcessBot::Process
|
|
|
131
131
|
def send_control_command(command, **command_options)
|
|
132
132
|
logger.logs "Sending #{command} command"
|
|
133
133
|
response = client.send_command(command: command, options: options.options.merge(command_options))
|
|
134
|
-
|
|
134
|
+
|
|
135
|
+
if response == :nil
|
|
136
|
+
handle_missing_control_command_response(command)
|
|
137
|
+
return if options[:ignore_no_process_bot]
|
|
138
|
+
|
|
139
|
+
raise "No response from ProcessBot while sending #{command}"
|
|
140
|
+
end
|
|
135
141
|
rescue Errno::ECONNREFUSED => e
|
|
142
|
+
handle_missing_control_command_response(command)
|
|
136
143
|
raise e unless options[:ignore_no_process_bot]
|
|
137
144
|
end
|
|
138
145
|
|
|
@@ -274,6 +281,65 @@ class ProcessBot::Process
|
|
|
274
281
|
start_runner_instance
|
|
275
282
|
end
|
|
276
283
|
|
|
284
|
+
def handle_missing_control_command_response(command)
|
|
285
|
+
return unless command == "stop"
|
|
286
|
+
|
|
287
|
+
matching_processes = matching_process_bot_processes
|
|
288
|
+
log_missing_control_response_diagnostics(matching_processes)
|
|
289
|
+
force_stop_process_bot_if_configured(matching_processes)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def log_missing_control_response_diagnostics(matching_processes)
|
|
293
|
+
logger.logs "Control command response missing; attempting diagnostics for application=#{options[:application].inspect} id=#{options[:id].inspect}"
|
|
294
|
+
logger.logs "Matching process_bot lines:\n#{matching_process_bot_processes_text(matching_processes)}"
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def matching_process_bot_processes_text(lines)
|
|
298
|
+
return "(none)" if lines.empty?
|
|
299
|
+
|
|
300
|
+
lines.join("\n")
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def matching_process_bot_processes
|
|
304
|
+
ps_output = Knj::Os.shellcmd("ps -eo pid,args")
|
|
305
|
+
|
|
306
|
+
ps_output
|
|
307
|
+
.to_s
|
|
308
|
+
.split("\n")
|
|
309
|
+
.select { |line| process_bot_process_line_matches?(line) }
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def process_bot_process_line_matches?(line)
|
|
313
|
+
line.include?("ProcessBot {") &&
|
|
314
|
+
line.include?("\"application\":\"#{options[:application]}\"") &&
|
|
315
|
+
line.include?("\"id\":\"#{options[:id]}\"")
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def force_stop_process_bot_if_configured(matching_processes)
|
|
319
|
+
return unless truthy_option?(:force_stop_on_no_response)
|
|
320
|
+
|
|
321
|
+
matching_processes.each do |line|
|
|
322
|
+
pid = line.strip.split(/\s+/, 2).first
|
|
323
|
+
next unless pid&.match?(/\A\d+\z/)
|
|
324
|
+
|
|
325
|
+
logger.logs "Force-stopping unresponsive process_bot PID #{pid}"
|
|
326
|
+
Process.kill("TERM", Integer(pid, 10))
|
|
327
|
+
rescue Errno::ESRCH
|
|
328
|
+
logger.logs "Process bot PID #{pid} already gone during force stop"
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def truthy_option?(key)
|
|
333
|
+
value = options[key]
|
|
334
|
+
return false if value.nil?
|
|
335
|
+
return value if value == true || value == false
|
|
336
|
+
|
|
337
|
+
normalized = value.to_s.strip.downcase
|
|
338
|
+
return false if normalized == "false" || normalized == "0" || normalized == ""
|
|
339
|
+
|
|
340
|
+
true
|
|
341
|
+
end
|
|
342
|
+
|
|
277
343
|
private
|
|
278
344
|
|
|
279
345
|
attr_reader :current_runner_instance, :runner_events, :runner_monitor
|
data/lib/process_bot/version.rb
CHANGED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
require "English"
|
|
2
|
+
require "fileutils"
|
|
3
|
+
require "pathname"
|
|
4
|
+
require "rubygems/version"
|
|
5
|
+
require "shellwords"
|
|
6
|
+
|
|
7
|
+
class ProcessBotRubygemsRelease # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
8
|
+
VERSION_FILE = Pathname.new(File.expand_path("../process_bot/version.rb", __dir__)) unless const_defined?(:VERSION_FILE)
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
ensure_clean_worktree!
|
|
12
|
+
checkout_master!
|
|
13
|
+
fetch!
|
|
14
|
+
merge!
|
|
15
|
+
|
|
16
|
+
next_version = determine_next_version
|
|
17
|
+
|
|
18
|
+
bump_version!(next_version)
|
|
19
|
+
commit!(next_version)
|
|
20
|
+
push!
|
|
21
|
+
gem_file = build_gem!(next_version)
|
|
22
|
+
push_gem!(gem_file)
|
|
23
|
+
delete_gem_file!(gem_file)
|
|
24
|
+
rescue StandardError
|
|
25
|
+
warn "Release failed."
|
|
26
|
+
raise
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def ensure_clean_worktree!
|
|
32
|
+
dirty_entries = git_status_lines.grep_v(%r{\A\?\? process_bot-[^/]+\.gem\z})
|
|
33
|
+
return if dirty_entries.empty?
|
|
34
|
+
|
|
35
|
+
raise "Working tree must be clean before releasing:\n#{dirty_entries.join("\n")}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def checkout_master!
|
|
39
|
+
run!("git", "checkout", "master")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def fetch!
|
|
43
|
+
run!("git", "fetch", remote_name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def merge!
|
|
47
|
+
run!("git", "merge", "--ff-only", "#{remote_name}/master")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def determine_next_version
|
|
51
|
+
requested_version || bumped_version
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def requested_version
|
|
55
|
+
version = ENV["VERSION"]&.strip
|
|
56
|
+
return if version.to_s.empty?
|
|
57
|
+
|
|
58
|
+
Gem::Version.new(version)
|
|
59
|
+
version
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def bumped_version
|
|
63
|
+
case bump_type
|
|
64
|
+
when "major"
|
|
65
|
+
[version_segments[0] + 1, 0, 0].join(".")
|
|
66
|
+
when "minor"
|
|
67
|
+
[version_segments[0], version_segments[1] + 1, 0].join(".")
|
|
68
|
+
when "patch"
|
|
69
|
+
[version_segments[0], version_segments[1], version_segments[2] + 1].join(".")
|
|
70
|
+
else
|
|
71
|
+
raise "Unsupported BUMP=#{bump_type.inspect}. Use patch, minor, major, or VERSION=x.y.z."
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def version_segments
|
|
76
|
+
@version_segments ||= begin
|
|
77
|
+
segments = Gem::Version.new(current_version).segments
|
|
78
|
+
segments << 0 while segments.length < 3
|
|
79
|
+
segments
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def current_version
|
|
84
|
+
@current_version ||= VERSION_FILE.read[/VERSION = "([^"]+)"\.freeze/, 1] || raise("Could not find current version")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def bump_version!(next_version)
|
|
88
|
+
raise "Next version must differ from current version" if next_version == current_version
|
|
89
|
+
|
|
90
|
+
VERSION_FILE.write(
|
|
91
|
+
VERSION_FILE.read.sub(
|
|
92
|
+
/VERSION = "[^"]+"\.freeze/,
|
|
93
|
+
%(VERSION = "#{next_version}".freeze)
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
run!("git", "add", VERSION_FILE.to_s)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def commit!(next_version)
|
|
101
|
+
run!("git", "commit", "-m", "Release #{next_version}")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def push!
|
|
105
|
+
run!("git", "push", remote_name, "master")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def build_gem!(next_version)
|
|
109
|
+
gem_file = "process_bot-#{next_version}.gem"
|
|
110
|
+
run!("gem", "build", "process_bot.gemspec")
|
|
111
|
+
gem_file
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def push_gem!(gem_file)
|
|
115
|
+
run!("gem", "push", gem_file)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def delete_gem_file!(gem_file)
|
|
119
|
+
FileUtils.rm_f(gem_file)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def git_status_lines
|
|
123
|
+
capture!("git", "status", "--porcelain").split("\n").reject(&:empty?)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def bump_type
|
|
127
|
+
ENV.fetch("BUMP", "patch")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def remote_name
|
|
131
|
+
ENV.fetch("REMOTE", "origin")
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def capture!(*command)
|
|
135
|
+
output = `#{command.map { |part| Shellwords.escape(part) }.join(" ")}`
|
|
136
|
+
raise "Command failed: #{command.join(' ')}" unless $CHILD_STATUS&.success?
|
|
137
|
+
|
|
138
|
+
output
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def run!(*command)
|
|
142
|
+
return if system(*command)
|
|
143
|
+
|
|
144
|
+
raise "Command failed: #{command.join(' ')}"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
namespace :release do
|
|
149
|
+
desc "Release a patch version from master by fetching, fast-forward merging, bumping version, pushing, and publishing"
|
|
150
|
+
task :patch do
|
|
151
|
+
ENV["BUMP"] = "patch"
|
|
152
|
+
ProcessBotRubygemsRelease.new.call
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
desc "Release a minor version from master by fetching, fast-forward merging, bumping version, pushing, and publishing"
|
|
156
|
+
task :minor do
|
|
157
|
+
ENV["BUMP"] = "minor"
|
|
158
|
+
ProcessBotRubygemsRelease.new.call
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
desc "Release a major version from master by fetching, fast-forward merging, bumping version, pushing, and publishing"
|
|
162
|
+
task :major do
|
|
163
|
+
ENV["BUMP"] = "major"
|
|
164
|
+
ProcessBotRubygemsRelease.new.call
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
desc "Release the gem from master by fetching, fast-forward merging, bumping version, pushing, and publishing"
|
|
168
|
+
task :rubygems do
|
|
169
|
+
ProcessBotRubygemsRelease.new.call
|
|
170
|
+
end
|
|
171
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: process_bot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.27
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kaspernj
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: knjrbfw
|
|
@@ -175,6 +175,7 @@ files:
|
|
|
175
175
|
- lib/process_bot/process/runner.rb
|
|
176
176
|
- lib/process_bot/process/runner_instance.rb
|
|
177
177
|
- lib/process_bot/version.rb
|
|
178
|
+
- lib/tasks/release.rake
|
|
178
179
|
- peak_flow.yml
|
|
179
180
|
- process_bot.gemspec
|
|
180
181
|
homepage: https://github.com/kaspernj/process_bot
|