kamal-easy 0.0.1
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 +7 -0
- data/Gemfile +3 -0
- data/README.md +142 -0
- data/bin/kamal-easy +6 -0
- data/kamal-easy.gemspec +27 -0
- data/lib/kamal_easy/cli.rb +211 -0
- data/lib/kamal_easy/config.rb +33 -0
- data/lib/kamal_easy/version.rb +3 -0
- data/lib/kamal_easy.rb +6 -0
- metadata +87 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1a04dcf9e1378966de7e532f431dad98804e5e3b9e7c03b71a79c43e8903e5d8
|
|
4
|
+
data.tar.gz: a57516ce3a7fd5fe6a86fa6768629017eaa9f74f20fecd7f1722a9fabd10c583
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 21aafcdc9097152fde8bc371d02d54cbadec09f57f30b44ba024533f9cd2e9fae66ea4aed103fbb0ed957600d7a8ee511baea6a3236383c5d5f15b3992606e46
|
|
7
|
+
data.tar.gz: 23c094ba49f1046f04a7ece78e9fd8e3d1e360cba4f5268c92a578c1b7d0afe79a9e3c44888d887fa7cac1fb74247900349baf570a9daebb3bc7d34c5399f761
|
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Kamal Easy
|
|
2
|
+
|
|
3
|
+
**Unified deployment wrapper for Kamal.**
|
|
4
|
+
Simplifies multi-environment deployments (UAT/Production) and provides unified commands for logs and access to the remote console.
|
|
5
|
+
|
|
6
|
+
## 🚀 Installation
|
|
7
|
+
|
|
8
|
+
Add this line to your application's Gemfile:
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
gem 'kamal-easy', git: 'https://github.com/overnet/kamal-easy.git'
|
|
12
|
+
# OR locally during development:
|
|
13
|
+
# gem 'kamal-easy', path: '../gems/kamal-easy'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bundle install
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## ⚙️ Configuration
|
|
23
|
+
|
|
24
|
+
Run the installer to generate the configuration file:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bundle exec kamal-easy install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This will create `config/kamal-easy.yml`. Configure it for your project:
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
# config/kamal-easy.yml
|
|
34
|
+
environments:
|
|
35
|
+
uat:
|
|
36
|
+
env_file: .env.uat
|
|
37
|
+
credentials_file: config/credentials/uat.yml.enc
|
|
38
|
+
staging:
|
|
39
|
+
env_file: .env.staging
|
|
40
|
+
credentials_file: config/credentials/staging.yml.enc
|
|
41
|
+
production:
|
|
42
|
+
env_file: .env.production
|
|
43
|
+
credentials_file: config/credentials/production.yml.enc
|
|
44
|
+
|
|
45
|
+
components:
|
|
46
|
+
backend:
|
|
47
|
+
path: .
|
|
48
|
+
kamal_cmd: "bundle exec kamal"
|
|
49
|
+
container_name_pattern: "your-app-backend-api" # For console access
|
|
50
|
+
mandatory_files:
|
|
51
|
+
- config/deploy.yml
|
|
52
|
+
- Dockerfile
|
|
53
|
+
frontend:
|
|
54
|
+
path: ../your-app-frontend
|
|
55
|
+
kamal_cmd: "kamal"
|
|
56
|
+
mandatory_files:
|
|
57
|
+
- config/deploy.yml
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Mandatory Files
|
|
61
|
+
- **`.env.uat` / `.env.staging` / `.env.production`**: Must exist in the component directory and contain necessary secrets (e.g., `RAILS_MASTER_KEY`).
|
|
62
|
+
- **`config/deploy.yml`**: Standard Kamal configuration must be present in each component directory.
|
|
63
|
+
- **`Dockerfile`**: Required for building images.
|
|
64
|
+
|
|
65
|
+
## 🛠️ Usage
|
|
66
|
+
|
|
67
|
+
### 1. Deployment (`kamal-easy deploy`)
|
|
68
|
+
Deploy specific components or the entire stack.
|
|
69
|
+
|
|
70
|
+
**Flags**:
|
|
71
|
+
- `--uat`: Deploy to UAT environment
|
|
72
|
+
- `--staging`: Deploy to Staging environment
|
|
73
|
+
- `--prod`: Deploy to Production environment
|
|
74
|
+
- `--all`: Deploy backend, frontend, and restart DB
|
|
75
|
+
- `--backend`: Deploy only backend
|
|
76
|
+
- `--frontend`: Deploy only frontend
|
|
77
|
+
- `--db`: Restart database accessory
|
|
78
|
+
- `--prune` / `-p`: Prune Docker system (images/containers) before deploy
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Deploy EVERYTHING (Backend + Frontend + DB)
|
|
82
|
+
bundle exec kamal-easy deploy --all --prod
|
|
83
|
+
|
|
84
|
+
# Deploy Specific Component
|
|
85
|
+
bundle exec kamal-easy deploy --backend --uat
|
|
86
|
+
bundle exec kamal-easy deploy --frontend --staging
|
|
87
|
+
bundle exec kamal-easy deploy --db --prod
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Logs (`kamal-easy logs`)
|
|
91
|
+
Stream logs from the remote container.
|
|
92
|
+
|
|
93
|
+
**Aliases**:
|
|
94
|
+
- `--follow` -> `-f`
|
|
95
|
+
- `--lines` -> `-n`
|
|
96
|
+
- `--grep` -> `-g`
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Follow live logs (UAT)
|
|
100
|
+
bundle exec kamal-easy logs --uat -f
|
|
101
|
+
|
|
102
|
+
# View last 500 lines
|
|
103
|
+
bundle exec kamal-easy logs --prod -n 500
|
|
104
|
+
|
|
105
|
+
# Grep for errors
|
|
106
|
+
bundle exec kamal-easy logs --prod -g "Error"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Remote Console (`kamal-easy console`)
|
|
110
|
+
Securely access the remote Rails console.
|
|
111
|
+
|
|
112
|
+
**Aliases**:
|
|
113
|
+
- `console` -> `c`, `rails_console`
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Connect to UAT Console
|
|
117
|
+
bundle exec kamal-easy c --uat
|
|
118
|
+
|
|
119
|
+
# Connect to Production
|
|
120
|
+
bundle exec kamal-easy rails_console --prod
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 4. Cleanup (`kamal-easy prune`)
|
|
124
|
+
Manage disk usage by removing old versions.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Keep last 3 versions (Default)
|
|
128
|
+
bundle exec kamal-easy prune --uat
|
|
129
|
+
|
|
130
|
+
# Keep last 5 versions
|
|
131
|
+
bundle exec kamal-easy prune --uat --retain 5
|
|
132
|
+
|
|
133
|
+
# Hard Cleanup (Aggressive docker system prune)
|
|
134
|
+
# WARNING: Deletes all stopped containers and unused images
|
|
135
|
+
bundle exec kamal-easy prune --uat --hard
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 🏗️ Deployment Architecture (Reference)
|
|
139
|
+
This gem assumes a setup where:
|
|
140
|
+
1. **Backend & Frontend** are in sibling directories.
|
|
141
|
+
2. **Zero Downtime** is handled via Kamal Proxy / Traefik (internal port binding).
|
|
142
|
+
3. **Credentials** are managed via `RAILS_MASTER_KEY`.
|
data/bin/kamal-easy
ADDED
data/kamal-easy.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require "kamal_easy/version"
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "kamal-easy"
|
|
8
|
+
spec.version = KamalEasy::VERSION
|
|
9
|
+
spec.authors = ["Ruslan Vikhor"]
|
|
10
|
+
spec.email = ["ruslan@overnet.com"]
|
|
11
|
+
spec.summary = "Unified deployment wrapper for Kamal"
|
|
12
|
+
spec.description = "Simplifies Kamal deployments with multi-environment support (UAT/Prod) and unified commands for logs and console."
|
|
13
|
+
spec.homepage = "https://github.com/overnet/kamal-easy"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = ">= 3.3.0"
|
|
16
|
+
|
|
17
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
18
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) || f.match(%r{\.gem$}) }
|
|
19
|
+
end
|
|
20
|
+
spec.bindir = "bin"
|
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
22
|
+
spec.require_paths = ["lib"]
|
|
23
|
+
|
|
24
|
+
spec.add_dependency "thor", "~> 1.2"
|
|
25
|
+
# Relaxed dependency to avoid conflicts with Rails apps running dotenv 3.x
|
|
26
|
+
spec.add_dependency "dotenv", ">= 2.8", "< 4.0"
|
|
27
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
require "thor"
|
|
2
|
+
require "dotenv"
|
|
3
|
+
require "kamal_easy/config"
|
|
4
|
+
|
|
5
|
+
module KamalEasy
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
check_unknown_options!
|
|
8
|
+
|
|
9
|
+
class_option :uat, type: :boolean, desc: "Run command in UAT environment", default: false
|
|
10
|
+
class_option :staging, type: :boolean, desc: "Run command in Staging environment", default: false
|
|
11
|
+
class_option :prod, type: :boolean, desc: "Run command in Production environment", default: false
|
|
12
|
+
class_option :production, type: :boolean, desc: "Alias for --prod", default: false
|
|
13
|
+
|
|
14
|
+
desc "install", "Generate configuration file"
|
|
15
|
+
def install
|
|
16
|
+
config_path = "config/kamal-easy.yml"
|
|
17
|
+
if File.exist?(config_path)
|
|
18
|
+
puts "⚠️ #{config_path} already exists."
|
|
19
|
+
else
|
|
20
|
+
template = <<~YAML
|
|
21
|
+
environments:
|
|
22
|
+
uat:
|
|
23
|
+
env_file: .env.uat
|
|
24
|
+
credentials_file: config/credentials/uat.yml.enc
|
|
25
|
+
staging:
|
|
26
|
+
env_file: .env.staging
|
|
27
|
+
credentials_file: config/credentials/staging.yml.enc
|
|
28
|
+
production:
|
|
29
|
+
env_file: .env.production
|
|
30
|
+
credentials_file: config/credentials/production.yml.enc
|
|
31
|
+
|
|
32
|
+
components:
|
|
33
|
+
backend:
|
|
34
|
+
path: .
|
|
35
|
+
kamal_cmd: "bundle exec kamal"
|
|
36
|
+
container_name_pattern: "your-app-backend-api"
|
|
37
|
+
mandatory_files:
|
|
38
|
+
- config/deploy.yml
|
|
39
|
+
- Dockerfile
|
|
40
|
+
frontend:
|
|
41
|
+
path: ../your-app-frontend
|
|
42
|
+
kamal_cmd: "kamal"
|
|
43
|
+
mandatory_files:
|
|
44
|
+
- config/deploy.yml
|
|
45
|
+
YAML
|
|
46
|
+
File.write(config_path, template)
|
|
47
|
+
puts "✅ Created #{config_path}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc "deploy [COMPONENT]", "Deploy specific component or everything"
|
|
52
|
+
method_option :all, type: :boolean, desc: "Deploy all components"
|
|
53
|
+
method_option :backend, type: :boolean, desc: "Deploy backend"
|
|
54
|
+
method_option :frontend, type: :boolean, desc: "Deploy frontend"
|
|
55
|
+
method_option :db, type: :boolean, desc: "Restart database"
|
|
56
|
+
method_option :prune, aliases: "-p", type: :boolean, desc: "Prune Docker before deploy"
|
|
57
|
+
def deploy
|
|
58
|
+
config = KamalEasy::Config.load
|
|
59
|
+
env_key, env_vars = load_environment(config)
|
|
60
|
+
|
|
61
|
+
prune_docker(config, env_vars) if options[:prune]
|
|
62
|
+
|
|
63
|
+
if options[:all]
|
|
64
|
+
deploy_backend(config, env_vars)
|
|
65
|
+
deploy_frontend(config, env_vars)
|
|
66
|
+
restart_db(config, env_vars)
|
|
67
|
+
else
|
|
68
|
+
deploy_backend(config, env_vars) if options[:backend]
|
|
69
|
+
deploy_frontend(config, env_vars) if options[:frontend]
|
|
70
|
+
restart_db(config, env_vars) if options[:db]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if !options[:all] && !options[:backend] && !options[:frontend] && !options[:db]
|
|
74
|
+
help("deploy")
|
|
75
|
+
exit(1)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
desc "logs", "View remote logs"
|
|
80
|
+
method_option :follow, aliases: "-f", type: :boolean, desc: "Follow logs", default: false
|
|
81
|
+
method_option :lines, aliases: "-n", type: :numeric, desc: "Number of lines", default: 100
|
|
82
|
+
method_option :grep, aliases: "-g", type: :string, desc: "Filter pattern"
|
|
83
|
+
def logs
|
|
84
|
+
config = KamalEasy::Config.load
|
|
85
|
+
env_key, env_vars = load_environment(config)
|
|
86
|
+
|
|
87
|
+
backend_config = config.components["backend"]
|
|
88
|
+
abort "❌ Backend component not configured" unless backend_config
|
|
89
|
+
|
|
90
|
+
cmd = "#{backend_config['kamal_cmd']} app logs"
|
|
91
|
+
cmd += " --lines #{options[:lines]}"
|
|
92
|
+
cmd += " --follow" if options[:follow]
|
|
93
|
+
cmd += " --grep '#{options[:grep]}'" if options[:grep]
|
|
94
|
+
|
|
95
|
+
puts "📋 Fetching logs from #{env_key.upcase}..."
|
|
96
|
+
exec_in_dir(backend_config["path"], env_vars, cmd)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
desc "console", "Access remote Rails console"
|
|
100
|
+
map ["c", "rails_console"] => :console
|
|
101
|
+
def console
|
|
102
|
+
config = KamalEasy::Config.load
|
|
103
|
+
env_key, env_vars = load_environment(config)
|
|
104
|
+
|
|
105
|
+
backend_config = config.components["backend"]
|
|
106
|
+
abort "❌ Backend component not configured" unless backend_config
|
|
107
|
+
|
|
108
|
+
container_name = backend_config["container_name_pattern"]
|
|
109
|
+
|
|
110
|
+
cmd = "#{backend_config['kamal_cmd']} server exec -i 'docker exec -it $(docker ps -q -f name=#{container_name} | head -n1) bin/rails console'"
|
|
111
|
+
|
|
112
|
+
puts "🔌 Connecting to #{env_key.upcase} Rails Console..."
|
|
113
|
+
exec_in_dir(backend_config["path"], env_vars, cmd)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
desc "prune", "Prune old images and containers"
|
|
117
|
+
method_option :retain, aliases: "-r", type: :numeric, default: 3, desc: "Number of versions to keep"
|
|
118
|
+
method_option :hard, type: :boolean, default: false, desc: "Run aggressive docker system prune"
|
|
119
|
+
def prune
|
|
120
|
+
config = KamalEasy::Config.load
|
|
121
|
+
env_key, env_vars = load_environment(config)
|
|
122
|
+
backend_config = config.components["backend"]
|
|
123
|
+
|
|
124
|
+
puts "🧹 Pruning old versions (keeping last #{options[:retain]})..."
|
|
125
|
+
|
|
126
|
+
# Kamal native prune (removes old containers/images managed by Kamal)
|
|
127
|
+
cmd = "#{backend_config['kamal_cmd']} prune --retain #{options[:retain]}"
|
|
128
|
+
exec_in_dir(backend_config["path"], env_vars, cmd)
|
|
129
|
+
|
|
130
|
+
if options[:hard]
|
|
131
|
+
puts "🧹 Running hard Docker cleanup..."
|
|
132
|
+
exec_in_dir(backend_config["path"], env_vars, "#{backend_config['kamal_cmd']} server exec 'docker system prune -a -f --volumes'")
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
def load_environment(config)
|
|
139
|
+
is_prod = options[:prod] || options[:production]
|
|
140
|
+
is_uat = options[:uat]
|
|
141
|
+
is_staging = options[:staging]
|
|
142
|
+
|
|
143
|
+
if [is_prod, is_uat, is_staging].count(true) > 1
|
|
144
|
+
abort "❌ Error: Cannot target multiple environments simultaneously."
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
unless is_prod || is_uat || is_staging
|
|
148
|
+
puts "ℹ️ No environment flag provided. Using current process environment..."
|
|
149
|
+
return [nil, {}]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
env_key = if is_prod
|
|
153
|
+
"production"
|
|
154
|
+
elsif is_staging
|
|
155
|
+
"staging"
|
|
156
|
+
else
|
|
157
|
+
"uat"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
env_config = config.env_config(env_key)
|
|
161
|
+
env_file = env_config["env_file"]
|
|
162
|
+
|
|
163
|
+
unless File.exist?(env_file)
|
|
164
|
+
abort "❌ Error: Environment file #{env_file} not found."
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
puts "📖 Loading configuration from #{env_file}..."
|
|
168
|
+
[env_key, Dotenv.parse(env_file)]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def deploy_backend(config, env_vars)
|
|
172
|
+
puts "🚀 Deploying Backend..."
|
|
173
|
+
comp = config.components["backend"]
|
|
174
|
+
validate_mandatory_files(comp, comp["path"])
|
|
175
|
+
exec_in_dir(comp["path"], env_vars, "#{comp['kamal_cmd']} deploy")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def deploy_frontend(config, env_vars)
|
|
179
|
+
puts "🚀 Deploying Frontend..."
|
|
180
|
+
comp = config.components["frontend"]
|
|
181
|
+
validate_mandatory_files(comp, comp["path"])
|
|
182
|
+
exec_in_dir(comp["path"], env_vars, "#{comp['kamal_cmd']} deploy")
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def restart_db(config, env_vars)
|
|
186
|
+
puts "🔄 Restarting Database..."
|
|
187
|
+
comp = config.components["backend"]
|
|
188
|
+
exec_in_dir(comp["path"], env_vars, "#{comp['kamal_cmd']} accessory reboot db")
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def validate_mandatory_files(component_config, path)
|
|
192
|
+
return unless component_config["mandatory_files"]
|
|
193
|
+
|
|
194
|
+
Dir.chdir(path) do
|
|
195
|
+
component_config["mandatory_files"].each do |file|
|
|
196
|
+
unless File.exist?(file)
|
|
197
|
+
abort "❌ Error: Mandatory file '#{file}' missing in #{path}"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def exec_in_dir(dir, env_vars, cmd)
|
|
204
|
+
Dir.chdir(dir) do
|
|
205
|
+
unless system(env_vars, cmd)
|
|
206
|
+
abort "❌ Command failed: #{cmd}"
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
require "thor"
|
|
3
|
+
|
|
4
|
+
module KamalEasy
|
|
5
|
+
class Config
|
|
6
|
+
CONFIG_FILE = "config/kamal-easy.yml"
|
|
7
|
+
|
|
8
|
+
def self.load
|
|
9
|
+
unless File.exist?(CONFIG_FILE)
|
|
10
|
+
abort "❌ Error: Configuration file #{CONFIG_FILE} not found. Run `kamal-easy install`."
|
|
11
|
+
end
|
|
12
|
+
new(YAML.load_file(CONFIG_FILE))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(data)
|
|
16
|
+
@data = data
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def environments
|
|
20
|
+
@data["environments"] || {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def components
|
|
24
|
+
@data["components"] || {}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def env_config(env_name)
|
|
28
|
+
config = environments[env_name.to_s]
|
|
29
|
+
abort "❌ Error: Environment '#{env_name}' not defined in #{CONFIG_FILE}" unless config
|
|
30
|
+
config
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/kamal_easy.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: kamal-easy
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ruslan Vikhor
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-02-16 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: thor
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.2'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.2'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: dotenv
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.8'
|
|
34
|
+
- - "<"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '4.0'
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '2.8'
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '4.0'
|
|
47
|
+
description: Simplifies Kamal deployments with multi-environment support (UAT/Prod)
|
|
48
|
+
and unified commands for logs and console.
|
|
49
|
+
email:
|
|
50
|
+
- ruslan@overnet.com
|
|
51
|
+
executables:
|
|
52
|
+
- kamal-easy
|
|
53
|
+
extensions: []
|
|
54
|
+
extra_rdoc_files: []
|
|
55
|
+
files:
|
|
56
|
+
- Gemfile
|
|
57
|
+
- README.md
|
|
58
|
+
- bin/kamal-easy
|
|
59
|
+
- kamal-easy.gemspec
|
|
60
|
+
- lib/kamal_easy.rb
|
|
61
|
+
- lib/kamal_easy/cli.rb
|
|
62
|
+
- lib/kamal_easy/config.rb
|
|
63
|
+
- lib/kamal_easy/version.rb
|
|
64
|
+
homepage: https://github.com/overnet/kamal-easy
|
|
65
|
+
licenses:
|
|
66
|
+
- MIT
|
|
67
|
+
metadata: {}
|
|
68
|
+
post_install_message:
|
|
69
|
+
rdoc_options: []
|
|
70
|
+
require_paths:
|
|
71
|
+
- lib
|
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: 3.3.0
|
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
requirements: []
|
|
83
|
+
rubygems_version: 3.5.3
|
|
84
|
+
signing_key:
|
|
85
|
+
specification_version: 4
|
|
86
|
+
summary: Unified deployment wrapper for Kamal
|
|
87
|
+
test_files: []
|