kamal 2.2.1 → 2.3.0
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/lib/kamal/cli/proxy.rb +2 -2
- data/lib/kamal/cli/templates/deploy.yml +6 -5
- data/lib/kamal/commands/accessory.rb +3 -3
- data/lib/kamal/commands/base.rb +10 -8
- data/lib/kamal/commands/builder/base.rb +6 -2
- data/lib/kamal/commands/builder/clone.rb +16 -14
- data/lib/kamal/configuration/accessory.rb +10 -0
- data/lib/kamal/configuration/builder.rb +5 -1
- data/lib/kamal/configuration/docs/accessory.yml +8 -0
- data/lib/kamal/configuration/docs/builder.yml +6 -0
- data/lib/kamal/configuration.rb +2 -2
- data/lib/kamal/env_file.rb +3 -1
- data/lib/kamal/secrets/adapters/base.rb +5 -0
- data/lib/kamal/secrets/adapters/bitwarden.rb +23 -8
- data/lib/kamal/secrets/adapters/last_pass.rb +9 -0
- data/lib/kamal/secrets/adapters/one_password.rb +9 -0
- data/lib/kamal/secrets/adapters/test.rb +4 -0
- data/lib/kamal/secrets.rb +11 -6
- data/lib/kamal/utils.rb +2 -0
- data/lib/kamal/version.rb +1 -1
- metadata +14 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d5e6961984a3361505ebf35dfc52920c49af92085dd99c923dbfa801c668a95
|
4
|
+
data.tar.gz: adddf71abb26f58e5f7bb16c62553f0d3358499ac4c09f333df75b650cc37b54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdbd4d88c6fe8001def4c53a9f3ee058e871e58ce99f6697a478cbbac48f646947aab415d08074668e2c41147f8fd15fa1cb76f01919d9411aa0e85be6767aba
|
7
|
+
data.tar.gz: b1716d147e84b386f8bac27deb60f70fc6a7fdfad18fc376dca1391d400de388085b654d5ec8e8e9b3b83724e0a22599bc5626d07cd3812330389add2ed915f9
|
data/lib/kamal/cli/proxy.rb
CHANGED
@@ -14,14 +14,14 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|
14
14
|
version = capture_with_info(*KAMAL.proxy.version).strip.presence
|
15
15
|
|
16
16
|
if version && Kamal::Utils.older_version?(version, Kamal::Configuration::PROXY_MINIMUM_VERSION)
|
17
|
-
raise "kamal-proxy version #{version} is too old,
|
17
|
+
raise "kamal-proxy version #{version} is too old, run `kamal proxy reboot` in order to update to at least #{Kamal::Configuration::PROXY_MINIMUM_VERSION}"
|
18
18
|
end
|
19
19
|
execute *KAMAL.proxy.start_or_run
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
desc "boot_config <set|get|reset>", "
|
24
|
+
desc "boot_config <set|get|reset>", "Manage kamal-proxy boot configuration"
|
25
25
|
option :publish, type: :boolean, default: true, desc: "Publish the proxy ports on the host"
|
26
26
|
option :http_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTP_PORT, desc: "HTTP port to publish on the host"
|
27
27
|
option :https_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTPS_PORT, desc: "HTTPS port to publish on the host"
|
@@ -13,13 +13,14 @@ servers:
|
|
13
13
|
# - 192.168.0.1
|
14
14
|
# cmd: bin/jobs
|
15
15
|
|
16
|
-
# Enable SSL auto certification via Let's Encrypt
|
17
|
-
#
|
18
|
-
#
|
16
|
+
# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server.
|
17
|
+
# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer.
|
18
|
+
#
|
19
|
+
# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption.
|
19
20
|
proxy:
|
20
21
|
ssl: true
|
21
22
|
host: app.example.com
|
22
|
-
#
|
23
|
+
# Proxy connects to your container on port 80 by default.
|
23
24
|
# app_port: 3000
|
24
25
|
|
25
26
|
# Credentials for your image host.
|
@@ -90,7 +91,7 @@ builder:
|
|
90
91
|
# directories:
|
91
92
|
# - data:/var/lib/mysql
|
92
93
|
# redis:
|
93
|
-
# image:
|
94
|
+
# image: valkey/valkey:8
|
94
95
|
# host: 192.168.0.2
|
95
96
|
# port: 6379
|
96
97
|
# directories:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Kamal::Commands::Accessory < Kamal::Commands::Base
|
2
2
|
attr_reader :accessory_config
|
3
3
|
delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd,
|
4
|
-
:publish_args, :env_args, :volume_args, :label_args, :option_args,
|
4
|
+
:network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args,
|
5
5
|
:secrets_io, :secrets_path, :env_directory,
|
6
6
|
to: :accessory_config
|
7
7
|
|
@@ -15,7 +15,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
15
15
|
"--name", service_name,
|
16
16
|
"--detach",
|
17
17
|
"--restart", "unless-stopped",
|
18
|
-
|
18
|
+
*network_args,
|
19
19
|
*config.logging_args,
|
20
20
|
*publish_args,
|
21
21
|
*env_args,
|
@@ -64,7 +64,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
64
64
|
docker :run,
|
65
65
|
("-it" if interactive),
|
66
66
|
"--rm",
|
67
|
-
|
67
|
+
*network_args,
|
68
68
|
*env_args,
|
69
69
|
*volume_args,
|
70
70
|
image,
|
data/lib/kamal/commands/base.rb
CHANGED
@@ -11,14 +11,7 @@ module Kamal::Commands
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def run_over_ssh(*command, host:)
|
14
|
-
"ssh".
|
15
|
-
if config.ssh.proxy && config.ssh.proxy.is_a?(Net::SSH::Proxy::Jump)
|
16
|
-
cmd << " -J #{config.ssh.proxy.jump_proxies}"
|
17
|
-
elsif config.ssh.proxy && config.ssh.proxy.is_a?(Net::SSH::Proxy::Command)
|
18
|
-
cmd << " -o ProxyCommand='#{config.ssh.proxy.command_line_template}'"
|
19
|
-
end
|
20
|
-
cmd << " -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
|
21
|
-
end
|
14
|
+
"ssh#{ssh_proxy_args} -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
|
22
15
|
end
|
23
16
|
|
24
17
|
def container_id_for(container_name:, only_running: false)
|
@@ -92,5 +85,14 @@ module Kamal::Commands
|
|
92
85
|
def tags(**details)
|
93
86
|
Kamal::Tags.from_config(config, **details)
|
94
87
|
end
|
88
|
+
|
89
|
+
def ssh_proxy_args
|
90
|
+
case config.ssh.proxy
|
91
|
+
when Net::SSH::Proxy::Jump
|
92
|
+
" -J #{config.ssh.proxy.jump_proxies}"
|
93
|
+
when Net::SSH::Proxy::Command
|
94
|
+
" -o ProxyCommand='#{config.ssh.proxy.command_line_template}'"
|
95
|
+
end
|
96
|
+
end
|
95
97
|
end
|
96
98
|
end
|
@@ -6,7 +6,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
6
6
|
delegate :argumentize, to: Kamal::Utils
|
7
7
|
delegate \
|
8
8
|
:args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
|
9
|
-
:cache_from, :cache_to, :ssh, :driver, :docker_driver?,
|
9
|
+
:cache_from, :cache_to, :ssh, :provenance, :driver, :docker_driver?,
|
10
10
|
to: :builder_config
|
11
11
|
|
12
12
|
def clean
|
@@ -37,7 +37,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def build_options
|
40
|
-
[ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh ]
|
40
|
+
[ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance ]
|
41
41
|
end
|
42
42
|
|
43
43
|
def build_context
|
@@ -97,6 +97,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
97
97
|
argumentize "--ssh", ssh if ssh.present?
|
98
98
|
end
|
99
99
|
|
100
|
+
def builder_provenance
|
101
|
+
argumentize "--provenance", provenance unless provenance.nil?
|
102
|
+
end
|
103
|
+
|
100
104
|
def builder_config
|
101
105
|
config.builder
|
102
106
|
end
|
@@ -1,29 +1,31 @@
|
|
1
1
|
module Kamal::Commands::Builder::Clone
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
included do
|
5
|
-
delegate :clone_directory, :build_directory, to: :"config.builder"
|
6
|
-
end
|
7
|
-
|
8
2
|
def clone
|
9
|
-
git :clone,
|
3
|
+
git :clone, escaped_root, "--recurse-submodules", path: config.builder.clone_directory.shellescape
|
10
4
|
end
|
11
5
|
|
12
6
|
def clone_reset_steps
|
13
7
|
[
|
14
|
-
git(:remote, "set-url", :origin,
|
15
|
-
git(:fetch, :origin, path:
|
16
|
-
git(:reset, "--hard", Kamal::Git.revision, path:
|
17
|
-
git(:clean, "-fdx", path:
|
18
|
-
git(:submodule, :update, "--init", path:
|
8
|
+
git(:remote, "set-url", :origin, escaped_root, path: escaped_build_directory),
|
9
|
+
git(:fetch, :origin, path: escaped_build_directory),
|
10
|
+
git(:reset, "--hard", Kamal::Git.revision, path: escaped_build_directory),
|
11
|
+
git(:clean, "-fdx", path: escaped_build_directory),
|
12
|
+
git(:submodule, :update, "--init", path: escaped_build_directory)
|
19
13
|
]
|
20
14
|
end
|
21
15
|
|
22
16
|
def clone_status
|
23
|
-
git :status, "--porcelain", path:
|
17
|
+
git :status, "--porcelain", path: escaped_build_directory
|
24
18
|
end
|
25
19
|
|
26
20
|
def clone_revision
|
27
|
-
git :"rev-parse", :HEAD, path:
|
21
|
+
git :"rev-parse", :HEAD, path: escaped_build_directory
|
22
|
+
end
|
23
|
+
|
24
|
+
def escaped_root
|
25
|
+
Kamal::Git.root.shellescape
|
26
|
+
end
|
27
|
+
|
28
|
+
def escaped_build_directory
|
29
|
+
config.builder.build_directory.shellescape
|
28
30
|
end
|
29
31
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class Kamal::Configuration::Accessory
|
2
2
|
include Kamal::Configuration::Validation
|
3
3
|
|
4
|
+
DEFAULT_NETWORK = "kamal"
|
5
|
+
|
4
6
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
5
7
|
|
6
8
|
attr_reader :name, :accessory_config, :env
|
@@ -38,6 +40,10 @@ class Kamal::Configuration::Accessory
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
43
|
+
def network_args
|
44
|
+
argumentize "--network", network
|
45
|
+
end
|
46
|
+
|
41
47
|
def publish_args
|
42
48
|
argumentize "--publish", port if port
|
43
49
|
end
|
@@ -173,4 +179,8 @@ class Kamal::Configuration::Accessory
|
|
173
179
|
accessory_config["roles"].flat_map { |role| config.role(role).hosts }
|
174
180
|
end
|
175
181
|
end
|
182
|
+
|
183
|
+
def network
|
184
|
+
accessory_config["network"] || DEFAULT_NETWORK
|
185
|
+
end
|
176
186
|
end
|
@@ -111,6 +111,10 @@ class Kamal::Configuration::Builder
|
|
111
111
|
builder_config["ssh"]
|
112
112
|
end
|
113
113
|
|
114
|
+
def provenance
|
115
|
+
builder_config["provenance"]
|
116
|
+
end
|
117
|
+
|
114
118
|
def git_clone?
|
115
119
|
Kamal::Git.used? && builder_config["context"].nil?
|
116
120
|
end
|
@@ -166,7 +170,7 @@ class Kamal::Configuration::Builder
|
|
166
170
|
end
|
167
171
|
|
168
172
|
def cache_to_config_for_registry
|
169
|
-
[ "type=registry", builder_config["cache"]&.fetch("options", nil)
|
173
|
+
[ "type=registry", "ref=#{cache_image_ref}", builder_config["cache"]&.fetch("options", nil) ].compact.join(",")
|
170
174
|
end
|
171
175
|
|
172
176
|
def repo_basename
|
@@ -102,3 +102,9 @@ builder:
|
|
102
102
|
#
|
103
103
|
# The build driver to use, defaults to `docker-container`:
|
104
104
|
driver: docker
|
105
|
+
|
106
|
+
# Provenance
|
107
|
+
#
|
108
|
+
# It is used to configure provenance attestations for the build result.
|
109
|
+
# The value can also be a boolean to enable or disable provenance attestations.
|
110
|
+
provenance: mode=max
|
data/lib/kamal/configuration.rb
CHANGED
@@ -14,7 +14,7 @@ class Kamal::Configuration
|
|
14
14
|
|
15
15
|
include Validation
|
16
16
|
|
17
|
-
PROXY_MINIMUM_VERSION = "v0.8.
|
17
|
+
PROXY_MINIMUM_VERSION = "v0.8.2"
|
18
18
|
PROXY_HTTP_PORT = 80
|
19
19
|
PROXY_HTTPS_PORT = 443
|
20
20
|
PROXY_LOG_MAX_SIZE = "10m"
|
@@ -254,7 +254,7 @@ class Kamal::Configuration
|
|
254
254
|
end
|
255
255
|
|
256
256
|
def proxy_logging_args(max_size)
|
257
|
-
argumentize "--log-opt", "max-size=#{max_size}"
|
257
|
+
argumentize "--log-opt", "max-size=#{max_size}" if max_size.present?
|
258
258
|
end
|
259
259
|
|
260
260
|
def proxy_options_default
|
data/lib/kamal/env_file.rb
CHANGED
@@ -37,6 +37,8 @@ class Kamal::EnvFile
|
|
37
37
|
def escape_docker_env_file_ascii_value(value)
|
38
38
|
# Doublequotes are treated literally in docker env files
|
39
39
|
# so remove leading and trailing ones and unescape any others
|
40
|
-
value.to_s.dump[1..-2]
|
40
|
+
value.to_s.dump[1..-2]
|
41
|
+
.gsub(/\\"/, "\"")
|
42
|
+
.gsub(/\\#/, "#")
|
41
43
|
end
|
42
44
|
end
|
@@ -2,6 +2,7 @@ class Kamal::Secrets::Adapters::Base
|
|
2
2
|
delegate :optionize, to: Kamal::Utils
|
3
3
|
|
4
4
|
def fetch(secrets, account:, from: nil)
|
5
|
+
check_dependencies!
|
5
6
|
session = login(account)
|
6
7
|
full_secrets = secrets.map { |secret| [ from, secret ].compact.join("/") }
|
7
8
|
fetch_secrets(full_secrets, account: account, session: session)
|
@@ -15,4 +16,8 @@ class Kamal::Secrets::Adapters::Base
|
|
15
16
|
def fetch_secrets(...)
|
16
17
|
raise NotImplementedError
|
17
18
|
end
|
19
|
+
|
20
|
+
def check_dependencies!
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
18
23
|
end
|
@@ -25,18 +25,15 @@ class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base
|
|
25
25
|
{}.tap do |results|
|
26
26
|
items_fields(secrets).each do |item, fields|
|
27
27
|
item_json = run_command("get item #{item.shellescape}", session: session, raw: true)
|
28
|
-
raise RuntimeError, "Could not read #{
|
28
|
+
raise RuntimeError, "Could not read #{item} from Bitwarden" unless $?.success?
|
29
29
|
item_json = JSON.parse(item_json)
|
30
|
-
|
31
30
|
if fields.any?
|
32
|
-
|
33
|
-
item_field = item_json["fields"].find { |f| f["name"] == field }
|
34
|
-
raise RuntimeError, "Could not find field #{field} in item #{item} in Bitwarden" unless item_field
|
35
|
-
value = item_field["value"]
|
36
|
-
results["#{item}/#{field}"] = value
|
37
|
-
end
|
31
|
+
results.merge! fetch_secrets_from_fields(fields, item, item_json)
|
38
32
|
elsif item_json.dig("login", "password")
|
39
33
|
results[item] = item_json.dig("login", "password")
|
34
|
+
elsif item_json["fields"]&.any?
|
35
|
+
fields = item_json["fields"].pluck("name")
|
36
|
+
results.merge! fetch_secrets_from_fields(fields, item, item_json)
|
40
37
|
else
|
41
38
|
raise RuntimeError, "Item #{item} is not a login type item and no fields were specified"
|
42
39
|
end
|
@@ -44,6 +41,15 @@ class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base
|
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
44
|
+
def fetch_secrets_from_fields(fields, item, item_json)
|
45
|
+
fields.to_h do |field|
|
46
|
+
item_field = item_json["fields"].find { |f| f["name"] == field }
|
47
|
+
raise RuntimeError, "Could not find field #{field} in item #{item} in Bitwarden" unless item_field
|
48
|
+
value = item_field["value"]
|
49
|
+
[ "#{item}/#{field}", value ]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
47
53
|
def items_fields(secrets)
|
48
54
|
{}.tap do |items|
|
49
55
|
secrets.each do |secret|
|
@@ -63,4 +69,13 @@ class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base
|
|
63
69
|
result = `#{full_command}`.strip
|
64
70
|
raw ? result : JSON.parse(result)
|
65
71
|
end
|
72
|
+
|
73
|
+
def check_dependencies!
|
74
|
+
raise RuntimeError, "Bitwarden CLI is not installed" unless cli_installed?
|
75
|
+
end
|
76
|
+
|
77
|
+
def cli_installed?
|
78
|
+
`bw --version 2> /dev/null`
|
79
|
+
$?.success?
|
80
|
+
end
|
66
81
|
end
|
@@ -27,4 +27,13 @@ class Kamal::Secrets::Adapters::LastPass < Kamal::Secrets::Adapters::Base
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
def check_dependencies!
|
32
|
+
raise RuntimeError, "LastPass CLI is not installed" unless cli_installed?
|
33
|
+
end
|
34
|
+
|
35
|
+
def cli_installed?
|
36
|
+
`lpass --version 2> /dev/null`
|
37
|
+
$?.success?
|
38
|
+
end
|
30
39
|
end
|
@@ -58,4 +58,13 @@ class Kamal::Secrets::Adapters::OnePassword < Kamal::Secrets::Adapters::Base
|
|
58
58
|
raise RuntimeError, "Could not read #{fields.join(", ")} from #{item} in the #{vault} 1Password vault" unless $?.success?
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
def check_dependencies!
|
63
|
+
raise RuntimeError, "1Password CLI is not installed" unless cli_installed?
|
64
|
+
end
|
65
|
+
|
66
|
+
def cli_installed?
|
67
|
+
`op --version 2> /dev/null`
|
68
|
+
$?.success?
|
69
|
+
end
|
61
70
|
end
|
data/lib/kamal/secrets.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
require "dotenv"
|
2
2
|
|
3
3
|
class Kamal::Secrets
|
4
|
-
attr_reader :secrets_files
|
5
|
-
|
6
4
|
Kamal::Secrets::Dotenv::InlineCommandSubstitution.install!
|
7
5
|
|
8
6
|
def initialize(destination: nil)
|
9
|
-
@
|
10
|
-
[ ".kamal/secrets-common", ".kamal/secrets#{(".#{destination}" if destination)}" ].select { |f| File.exist?(f) }
|
7
|
+
@destination = destination
|
11
8
|
@mutex = Mutex.new
|
12
9
|
end
|
13
10
|
|
@@ -17,10 +14,10 @@ class Kamal::Secrets
|
|
17
14
|
secrets.fetch(key)
|
18
15
|
end
|
19
16
|
rescue KeyError
|
20
|
-
if secrets_files
|
17
|
+
if secrets_files.present?
|
21
18
|
raise Kamal::ConfigurationError, "Secret '#{key}' not found in #{secrets_files.join(", ")}"
|
22
19
|
else
|
23
|
-
raise Kamal::ConfigurationError, "Secret '#{key}' not found, no secret files provided"
|
20
|
+
raise Kamal::ConfigurationError, "Secret '#{key}' not found, no secret files (#{secrets_filenames.join(", ")}) provided"
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
@@ -28,10 +25,18 @@ class Kamal::Secrets
|
|
28
25
|
secrets
|
29
26
|
end
|
30
27
|
|
28
|
+
def secrets_files
|
29
|
+
@secrets_files ||= secrets_filenames.select { |f| File.exist?(f) }
|
30
|
+
end
|
31
|
+
|
31
32
|
private
|
32
33
|
def secrets
|
33
34
|
@secrets ||= secrets_files.inject({}) do |secrets, secrets_file|
|
34
35
|
secrets.merge!(::Dotenv.parse(secrets_file))
|
35
36
|
end
|
36
37
|
end
|
38
|
+
|
39
|
+
def secrets_filenames
|
40
|
+
[ ".kamal/secrets-common", ".kamal/secrets#{(".#{@destination}" if @destination)}" ]
|
41
|
+
end
|
37
42
|
end
|
data/lib/kamal/utils.rb
CHANGED
data/lib/kamal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kamal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '7.
|
53
|
+
version: '7.3'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '7.
|
60
|
+
version: '7.3'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: thor
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,16 +90,22 @@ dependencies:
|
|
90
90
|
name: zeitwerk
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 2.6.18
|
96
|
+
- - "<"
|
94
97
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
98
|
+
version: '3.0'
|
96
99
|
type: :runtime
|
97
100
|
prerelease: false
|
98
101
|
version_requirements: !ruby/object:Gem::Requirement
|
99
102
|
requirements:
|
100
|
-
- - "
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 2.6.18
|
106
|
+
- - "<"
|
101
107
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
108
|
+
version: '3.0'
|
103
109
|
- !ruby/object:Gem::Dependency
|
104
110
|
name: ed25519
|
105
111
|
requirement: !ruby/object:Gem::Requirement
|