kettle-dev 2.5.11 → 2.5.13
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +88 -1
- data/README.md +1 -1
- data/exe/kettle-changelog +25 -3
- data/exe/kettle-release +26 -2
- data/exe/kettle-release-secrets-doctor +39 -0
- data/lib/kettle/dev/bundler_env_guard.rb +1 -0
- data/lib/kettle/dev/changelog_cli.rb +43 -1
- data/lib/kettle/dev/ci_monitor.rb +235 -7
- data/lib/kettle/dev/interactive_release_command.rb +16 -5
- data/lib/kettle/dev/lockfile_reset.rb +22 -0
- data/lib/kettle/dev/pre_release_cli.rb +49 -4
- data/lib/kettle/dev/release_cli.rb +342 -18
- data/lib/kettle/dev/release_notifier.rb +27 -0
- data/lib/kettle/dev/release_secrets.rb +16 -1
- data/lib/kettle/dev/release_secrets_doctor.rb +204 -0
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +10 -6
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rbconfig"
|
|
4
|
+
require "shellwords"
|
|
5
|
+
require "time"
|
|
6
|
+
|
|
7
|
+
module Kettle
|
|
8
|
+
module Dev
|
|
9
|
+
class ReleaseSecretsDoctor
|
|
10
|
+
DEFAULT_SLEEP_SECONDS = 30.0
|
|
11
|
+
DEFAULT_KEEPALIVE_SECONDS = 0.0
|
|
12
|
+
DEFAULT_PROVIDER = "op"
|
|
13
|
+
DEFAULT_SHAPE = "same-process"
|
|
14
|
+
CHILD_SHAPE = "same-process"
|
|
15
|
+
SHAPES = %w[same-process child-process parent-child thread bundler-child env-reset-child].freeze
|
|
16
|
+
BUNDLER_ENV_UNSETS = %w[
|
|
17
|
+
BUNDLE_BIN_PATH
|
|
18
|
+
BUNDLE_FROZEN
|
|
19
|
+
BUNDLE_GEMFILE
|
|
20
|
+
BUNDLE_LOCKFILE
|
|
21
|
+
BUNDLER_SETUP
|
|
22
|
+
BUNDLER_VERSION
|
|
23
|
+
RUBYLIB
|
|
24
|
+
RUBYOPT
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
def self.options_from_env(env = ENV)
|
|
28
|
+
{
|
|
29
|
+
provider: env.fetch("KETTLE_RELEASE_SECRETS_PROVIDER", DEFAULT_PROVIDER),
|
|
30
|
+
sleep_seconds: Float(env.fetch("KETTLE_RELEASE_SECRETS_DOCTOR_SLEEP", DEFAULT_SLEEP_SECONDS.to_s)),
|
|
31
|
+
keepalive_seconds: Float(env.fetch("KETTLE_RELEASE_SECRETS_DOCTOR_KEEPALIVE", DEFAULT_KEEPALIVE_SECONDS.to_s)),
|
|
32
|
+
shape: env.fetch("KETTLE_RELEASE_SECRETS_DOCTOR_SHAPE", DEFAULT_SHAPE),
|
|
33
|
+
otp: false
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize(options:, program_name:, output: $stdout, system_runner: Kernel)
|
|
38
|
+
@options = normalize_options(options)
|
|
39
|
+
@program_name = program_name
|
|
40
|
+
@output = output
|
|
41
|
+
@system_runner = system_runner
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def run
|
|
45
|
+
case options.fetch(:shape)
|
|
46
|
+
when "same-process"
|
|
47
|
+
run_same_process(options)
|
|
48
|
+
when "child-process"
|
|
49
|
+
run_child_process(options)
|
|
50
|
+
when "parent-child"
|
|
51
|
+
run_parent_child(options)
|
|
52
|
+
when "thread"
|
|
53
|
+
run_thread(options)
|
|
54
|
+
when "bundler-child"
|
|
55
|
+
run_bundler_child(options)
|
|
56
|
+
when "env-reset-child"
|
|
57
|
+
run_env_reset_child(options)
|
|
58
|
+
else
|
|
59
|
+
raise Kettle::Dev::Error, "unknown shape #{options.fetch(:shape).inspect}; expected #{SHAPES.join(", ")}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def child_env(shape:, options: self.options)
|
|
64
|
+
env = {
|
|
65
|
+
"KETTLE_RELEASE_SECRETS_PROVIDER" => options.fetch(:provider),
|
|
66
|
+
"KETTLE_RELEASE_SECRETS_DOCTOR_SHAPE" => shape,
|
|
67
|
+
"KETTLE_RELEASE_SECRETS_DOCTOR_SLEEP" => options.fetch(:sleep_seconds).to_s,
|
|
68
|
+
"KETTLE_RELEASE_SECRETS_DOCTOR_KEEPALIVE" => options.fetch(:keepalive_seconds).to_s
|
|
69
|
+
}
|
|
70
|
+
env["KETTLE_RELEASE_SECRETS_DOCTOR_CHILD"] = "true"
|
|
71
|
+
env
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def child_args(otp: options.fetch(:otp))
|
|
75
|
+
args = [RbConfig.ruby, program_name]
|
|
76
|
+
args << "--otp" if otp
|
|
77
|
+
args
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def bundler_child_args(otp: options.fetch(:otp))
|
|
81
|
+
args = ["bundle", "exec", RbConfig.ruby, program_name]
|
|
82
|
+
args << "--otp" if otp
|
|
83
|
+
args
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
attr_reader :options, :program_name, :output, :system_runner
|
|
89
|
+
|
|
90
|
+
def normalize_options(raw_options)
|
|
91
|
+
{
|
|
92
|
+
provider: raw_options.fetch(:provider, DEFAULT_PROVIDER).to_s,
|
|
93
|
+
sleep_seconds: Float(raw_options.fetch(:sleep_seconds, DEFAULT_SLEEP_SECONDS)),
|
|
94
|
+
keepalive_seconds: Float(raw_options.fetch(:keepalive_seconds, DEFAULT_KEEPALIVE_SECONDS)),
|
|
95
|
+
shape: raw_options.fetch(:shape, DEFAULT_SHAPE).to_s,
|
|
96
|
+
otp: !!raw_options.fetch(:otp, false)
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def provider_for(current_options)
|
|
101
|
+
Kettle::Dev::ReleaseSecrets::Factory.build(provider_name: current_options.fetch(:provider))
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def run_same_process(current_options)
|
|
105
|
+
provider = provider_for(current_options)
|
|
106
|
+
output.puts("[#{timestamp}] initial keepalive")
|
|
107
|
+
provider.keepalive!
|
|
108
|
+
wait_with_keepalive(provider, current_options)
|
|
109
|
+
output.puts("[#{timestamp}] final keepalive")
|
|
110
|
+
provider.keepalive!
|
|
111
|
+
run_otp_lookup(provider) if current_options.fetch(:otp)
|
|
112
|
+
true
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def run_parent_child(current_options)
|
|
116
|
+
provider = provider_for(current_options)
|
|
117
|
+
output.puts("[#{timestamp}] parent initial keepalive")
|
|
118
|
+
provider.keepalive!
|
|
119
|
+
wait_with_keepalive(provider, current_options)
|
|
120
|
+
output.puts("[#{timestamp}] parent spawning child after keepalive")
|
|
121
|
+
run_child_process(current_options)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def run_child_process(current_options)
|
|
125
|
+
env = child_env(shape: CHILD_SHAPE, options: current_options)
|
|
126
|
+
args = child_args(otp: current_options.fetch(:otp))
|
|
127
|
+
output.puts("[#{timestamp}] spawning child: #{args.shelljoin}")
|
|
128
|
+
run_system(env, args)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def run_bundler_child(current_options)
|
|
132
|
+
env = child_env(shape: CHILD_SHAPE, options: current_options)
|
|
133
|
+
args = bundler_child_args(otp: current_options.fetch(:otp))
|
|
134
|
+
output.puts("[#{timestamp}] spawning bundler child: #{args.shelljoin}")
|
|
135
|
+
run_system(env, args)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def run_env_reset_child(current_options)
|
|
139
|
+
env = child_env(shape: CHILD_SHAPE, options: current_options)
|
|
140
|
+
BUNDLER_ENV_UNSETS.each { |key| env[key] = nil }
|
|
141
|
+
args = child_args(otp: current_options.fetch(:otp))
|
|
142
|
+
output.puts("[#{timestamp}] spawning env-reset child: #{args.shelljoin}")
|
|
143
|
+
run_system(env, args)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def run_thread(current_options)
|
|
147
|
+
error = nil
|
|
148
|
+
# rubocop:disable ThreadSafety/NewThread -- this doctor intentionally probes threaded secret-provider behavior.
|
|
149
|
+
thread = Thread.new do
|
|
150
|
+
begin
|
|
151
|
+
run_same_process(current_options)
|
|
152
|
+
rescue => e
|
|
153
|
+
error = e
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
# rubocop:enable ThreadSafety/NewThread
|
|
157
|
+
thread.join
|
|
158
|
+
raise error if error
|
|
159
|
+
|
|
160
|
+
true
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def run_system(env, args)
|
|
164
|
+
success = system_runner.system(env, *args)
|
|
165
|
+
raise Kettle::Dev::Error, "child shape failed: #{args.shelljoin}" unless success
|
|
166
|
+
|
|
167
|
+
true
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def wait_with_keepalive(provider, current_options)
|
|
171
|
+
sleep_seconds = current_options.fetch(:sleep_seconds)
|
|
172
|
+
keepalive_seconds = current_options.fetch(:keepalive_seconds)
|
|
173
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + sleep_seconds
|
|
174
|
+
if keepalive_seconds <= 0
|
|
175
|
+
output.puts("[#{timestamp}] sleeping #{sleep_seconds}s without keepalive")
|
|
176
|
+
sleep(sleep_seconds)
|
|
177
|
+
return
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
output.puts("[#{timestamp}] sleeping #{sleep_seconds}s with #{keepalive_seconds}s keepalive")
|
|
181
|
+
loop do
|
|
182
|
+
remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
183
|
+
break if remaining <= 0
|
|
184
|
+
|
|
185
|
+
sleep([remaining, keepalive_seconds].min)
|
|
186
|
+
break if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
187
|
+
|
|
188
|
+
output.puts("[#{timestamp}] keepalive")
|
|
189
|
+
provider.keepalive!
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def run_otp_lookup(provider)
|
|
194
|
+
output.puts("[#{timestamp}] OTP lookup")
|
|
195
|
+
otp = provider.rubygems_otp
|
|
196
|
+
output.puts("[#{timestamp}] OTP lookup returned #{otp.to_s.empty? ? "empty" : "#{otp.length} chars"}")
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def timestamp
|
|
200
|
+
Time.now.iso8601
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
data/lib/kettle/dev/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Kettle
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = "2.5.
|
|
8
|
+
VERSION = "2.5.13"
|
|
9
9
|
end
|
|
10
10
|
# Current gem version exposed at the traditional constant location.
|
|
11
11
|
VERSION = Version::VERSION # Traditional Constant Location
|
data/lib/kettle/dev.rb
CHANGED
|
@@ -46,8 +46,10 @@ module Kettle
|
|
|
46
46
|
autoload :LockfileReset, "kettle/dev/lockfile_reset"
|
|
47
47
|
autoload :ReadmeBackers, "kettle/dev/readme_backers"
|
|
48
48
|
autoload :OpenCollectiveConfig, "kettle/dev/open_collective_config"
|
|
49
|
+
autoload :ReleaseNotifier, "kettle/dev/release_notifier"
|
|
49
50
|
autoload :ReleaseCLI, "kettle/dev/release_cli"
|
|
50
51
|
autoload :ReleaseSecrets, "kettle/dev/release_secrets"
|
|
52
|
+
autoload :ReleaseSecretsDoctor, "kettle/dev/release_secrets_doctor"
|
|
51
53
|
autoload :ResetCLI, "kettle/dev/reset_cli"
|
|
52
54
|
autoload :PreReleaseCLI, "kettle/dev/pre_release_cli"
|
|
53
55
|
autoload :Version, "kettle/dev/version"
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-dev
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.5.
|
|
4
|
+
version: 2.5.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -80,7 +80,7 @@ dependencies:
|
|
|
80
80
|
version: '0.1'
|
|
81
81
|
- - ">="
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
|
-
version: 0.1.
|
|
83
|
+
version: 0.1.9
|
|
84
84
|
type: :runtime
|
|
85
85
|
prerelease: false
|
|
86
86
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -90,7 +90,7 @@ dependencies:
|
|
|
90
90
|
version: '0.1'
|
|
91
91
|
- - ">="
|
|
92
92
|
- !ruby/object:Gem::Version
|
|
93
|
-
version: 0.1.
|
|
93
|
+
version: 0.1.9
|
|
94
94
|
- !ruby/object:Gem::Dependency
|
|
95
95
|
name: kettle-rb
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -327,6 +327,7 @@ executables:
|
|
|
327
327
|
- kettle-pre-release
|
|
328
328
|
- kettle-readme-backers
|
|
329
329
|
- kettle-release
|
|
330
|
+
- kettle-release-secrets-doctor
|
|
330
331
|
- kettle-reset
|
|
331
332
|
extensions: []
|
|
332
333
|
extra_rdoc_files: []
|
|
@@ -346,6 +347,7 @@ files:
|
|
|
346
347
|
- exe/kettle-pre-release
|
|
347
348
|
- exe/kettle-readme-backers
|
|
348
349
|
- exe/kettle-release
|
|
350
|
+
- exe/kettle-release-secrets-doctor
|
|
349
351
|
- exe/kettle-reset
|
|
350
352
|
- lib/kettle-dev.rb
|
|
351
353
|
- lib/kettle/dev.rb
|
|
@@ -381,7 +383,9 @@ files:
|
|
|
381
383
|
- lib/kettle/dev/rakelib/yard.rake
|
|
382
384
|
- lib/kettle/dev/readme_backers.rb
|
|
383
385
|
- lib/kettle/dev/release_cli.rb
|
|
386
|
+
- lib/kettle/dev/release_notifier.rb
|
|
384
387
|
- lib/kettle/dev/release_secrets.rb
|
|
388
|
+
- lib/kettle/dev/release_secrets_doctor.rb
|
|
385
389
|
- lib/kettle/dev/reset_cli.rb
|
|
386
390
|
- lib/kettle/dev/ruby_gems_versions.rb
|
|
387
391
|
- lib/kettle/dev/tasks.rb
|
|
@@ -397,10 +401,10 @@ licenses:
|
|
|
397
401
|
- AGPL-3.0-only
|
|
398
402
|
metadata:
|
|
399
403
|
homepage_uri: https://kettle-dev.galtzo.com
|
|
400
|
-
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.5.
|
|
401
|
-
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.5.
|
|
404
|
+
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.5.13
|
|
405
|
+
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.5.13/CHANGELOG.md
|
|
402
406
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
|
|
403
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.5.
|
|
407
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.5.13
|
|
404
408
|
funding_uri: https://github.com/sponsors/pboling
|
|
405
409
|
wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
|
|
406
410
|
news_uri: https://www.railsbling.com/tags/kettle-dev
|
metadata.gz.sig
CHANGED
|
Binary file
|