renuo-cli 4.15.0 → 4.17.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 +4 -4
- data/README.md +2 -1
- data/lib/renuo/cli/commands/create_deploio_object_storage.rb +124 -0
- data/lib/renuo/cli/commands/fetch_secrets.rb +11 -3
- data/lib/renuo/cli/commands/release.rb +38 -8
- data/lib/renuo/cli/version.rb +1 -1
- 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: d001b3727b2158e75b84057e5520246f4a4983ebc9008a97802134a07a7fe9a1
|
|
4
|
+
data.tar.gz: d258158583a1659efea53a52cfb1e29569753e55e4c30d62c95984fed5498813
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cea757ec3ba510fbec394fe7d313edac2ef4db8e7d31f53e0c9cf83af0ef8d8225e53fa68a3f3c4beea206ef55e022774ef2cd342a1545aa4af925016b936bb1
|
|
7
|
+
data.tar.gz: 38a9b4a0b037a9ec087fd39060b7b154fbb5ce77533e80f9d977246c62f25fc3dee99e88f36ac7cdf96ec7eb01f7651ef6a89eac22bcb43dbf8c2a95ae1a35bd
|
data/README.md
CHANGED
|
@@ -32,7 +32,8 @@ To release a new version, update the version number in `version.rb`, and then ru
|
|
|
32
32
|
|
|
33
33
|
## Release
|
|
34
34
|
|
|
35
|
-
* Bump the version number in `lib/renuo/cli/version.rb
|
|
35
|
+
* Bump the version number in `lib/renuo/cli/version.rb`, run `bundle install`
|
|
36
|
+
to update the `Gemfile.lock` and commit to `main`
|
|
36
37
|
|
|
37
38
|
### Automatic
|
|
38
39
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :nocov:
|
|
4
|
+
|
|
5
|
+
class Renuo::Cli::Commands::CreateDeploioObjectStorage
|
|
6
|
+
include CommandHelper
|
|
7
|
+
|
|
8
|
+
command "create-deploio-object-storage" do |c|
|
|
9
|
+
c.syntax = "renuo create-deploio-object-storage"
|
|
10
|
+
c.summary = "Generates the script necessary to setup object storage on Deploio."
|
|
11
|
+
c.description = <<~DESCRIPTION
|
|
12
|
+
This creates commands for creating buckets and bucket users.
|
|
13
|
+
It also guides you to set up ActiveStorage correctly, by setting the required ENV variables and config/storage.yml setting.
|
|
14
|
+
|
|
15
|
+
You will be asked for:
|
|
16
|
+
- project name so that the script can respect our naming conventions
|
|
17
|
+
|
|
18
|
+
The generated commands do the following:
|
|
19
|
+
- create a bucket user for each environment (main, develop)
|
|
20
|
+
- create buckets for each user who owns it
|
|
21
|
+
- enable versioning for main buckets
|
|
22
|
+
DESCRIPTION
|
|
23
|
+
c.example "Setup Deploio object storage (you will be asked for details)", "renuo create-deploio-object-storage"
|
|
24
|
+
c.example "renuo create-deploio-object-storage",
|
|
25
|
+
"Prompts the user for the necessary information and generates the commands " \
|
|
26
|
+
"to setup object storage on Deploio."
|
|
27
|
+
c.action { new.run }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize
|
|
31
|
+
@project_name = ask('Project name (eg: "renuo-mtextur"): ') { |q| q.validate = /.+/ }
|
|
32
|
+
@location = ask('Location (Default: "nine-es34"): ') { |q| q.default = "nine-es34" }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
BRANCHES = %w[main develop].freeze
|
|
36
|
+
|
|
37
|
+
def run
|
|
38
|
+
BRANCHES.each do |branch|
|
|
39
|
+
print_setup_commands(branch)
|
|
40
|
+
end
|
|
41
|
+
print_active_storage_config
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def project_name_without_organisation
|
|
47
|
+
@project_name_without_organisation ||= @project_name.split("-")[1..].join("-")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def print_setup_commands(branch)
|
|
51
|
+
say "\n# Commands to create #{branch} bucket user and bucket\n".bold
|
|
52
|
+
versioning_flag = branch == "main" ? " --versioning" : ""
|
|
53
|
+
bucket_name = "#{project_name_without_organisation}-#{branch}"
|
|
54
|
+
say "nctl create bucketuser #{branch} --project #{@project_name} --location #{@location}\n"
|
|
55
|
+
say "nctl create bucket #{bucket_name} --project #{@project_name} --location #{@location}" \
|
|
56
|
+
"#{versioning_flag} --permissions reader=#{branch} --permissions writer=#{branch}\n"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def print_active_storage_config
|
|
60
|
+
say "\n# ActiveStorage Configuration".bold
|
|
61
|
+
print_storage_yml_config
|
|
62
|
+
print_retrieve_credentials
|
|
63
|
+
print_env_variables_config
|
|
64
|
+
print_active_storage_service_config
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def print_storage_yml_config
|
|
68
|
+
puts <<~OUTPUT
|
|
69
|
+
Add the following service configuration to your "config/storage.yml" file:
|
|
70
|
+
|
|
71
|
+
deploio:
|
|
72
|
+
service: S3
|
|
73
|
+
access_key_id: <%= ENV["DEPLOIO_ACCESS_KEY"] %>
|
|
74
|
+
secret_access_key: <%= ENV["DEPLOIO_SECRET_KEY"] %>
|
|
75
|
+
endpoint: <%= ENV["DEPLOIO_ENDPOINT"] %>
|
|
76
|
+
region: us-east-1 # running in Switzerland, operated by Nine.
|
|
77
|
+
bucket: <%= ENV["DEPLOIO_BUCKET"] %>
|
|
78
|
+
|
|
79
|
+
INFO: For S3, a region must be specified. Deploio uses the S3 default value of us-east-1,
|
|
80
|
+
even though the servers are in Switzerland, operated by Nine.
|
|
81
|
+
OUTPUT
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def print_retrieve_credentials
|
|
85
|
+
say "\n# Retrieve credentials from the bucket user".bold
|
|
86
|
+
say "After running the bucket user creation commands above, retrieve your credentials:\n\n"
|
|
87
|
+
|
|
88
|
+
BRANCHES.each do |branch|
|
|
89
|
+
say <<~OUTPUT
|
|
90
|
+
## #{branch} environment credentials:
|
|
91
|
+
nctl get bucketuser #{branch} --project #{@project_name} --print-credentials
|
|
92
|
+
|
|
93
|
+
OUTPUT
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def print_env_variables_config
|
|
98
|
+
say "\n# Set environment variables on your Deploio application".bold
|
|
99
|
+
say "Replace the placeholders with the values retrieved above:\n"
|
|
100
|
+
|
|
101
|
+
BRANCHES.each do |branch|
|
|
102
|
+
bucket_name = "#{project_name_without_organisation}-#{branch}"
|
|
103
|
+
say <<~OUTPUT
|
|
104
|
+
|
|
105
|
+
# #{branch} environment:
|
|
106
|
+
nctl update app #{branch} \\
|
|
107
|
+
--project #{@project_name} \\
|
|
108
|
+
--env="DEPLOIO_ACCESS_KEY={ACCESS_KEY}" \\
|
|
109
|
+
--env="DEPLOIO_SECRET_KEY={SECRET_KEY}" \\
|
|
110
|
+
--env="DEPLOIO_ENDPOINT=https://#{@location}.objects.nineapis.ch" \\
|
|
111
|
+
--env="DEPLOIO_BUCKET=#{bucket_name}"
|
|
112
|
+
OUTPUT
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def print_active_storage_service_config
|
|
117
|
+
say "\n# Configure ActiveStorage in your Rails application".bold
|
|
118
|
+
say <<~OUTPUT
|
|
119
|
+
Set the ActiveStorage service in your production environment ("config/environments/production.rb"):
|
|
120
|
+
|
|
121
|
+
config.active_storage.service = :deploio
|
|
122
|
+
OUTPUT
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -51,7 +51,8 @@ class Renuo::Cli::Commands::FetchSecrets # rubocop:disable Metrics/ClassLength
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
item_id = extract_item_id(private_link)
|
|
54
|
-
|
|
54
|
+
account_id = extract_account_id(private_link)
|
|
55
|
+
item_json = get_item(item_id, account_id)
|
|
55
56
|
return if item_json.nil?
|
|
56
57
|
|
|
57
58
|
item[:env_variables]&.each do |env_variable|
|
|
@@ -67,8 +68,15 @@ class Renuo::Cli::Commands::FetchSecrets # rubocop:disable Metrics/ClassLength
|
|
|
67
68
|
/&i=([^&]+)/.match(private_link)[1]
|
|
68
69
|
end
|
|
69
70
|
|
|
70
|
-
def
|
|
71
|
-
|
|
71
|
+
def extract_account_id(private_link)
|
|
72
|
+
/&h=([^&]+)/.match(private_link)&.[](1)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def get_item(item_id, account_id = nil)
|
|
76
|
+
command = "op item get #{item_id} --format json"
|
|
77
|
+
command += " --account #{account_id}" if account_id
|
|
78
|
+
|
|
79
|
+
output = execute_command(command: command,
|
|
72
80
|
success_message: "",
|
|
73
81
|
error_message: "Error fetching item #{item_id}." \
|
|
74
82
|
"Check `private_link` in your #{CONFIG_FILE} file.")
|
|
@@ -6,13 +6,17 @@ class Renuo::Cli::Commands::Release # rubocop:disable Metrics/ClassLength
|
|
|
6
6
|
UPDATE_TYPES = %w[major minor patch custom].freeze
|
|
7
7
|
TMP_FOLDER_NAME = "_RENUO_RELEASE_TEMP_#{rand(100_000_000)}".freeze
|
|
8
8
|
MOVE_TO_TMP_FOLDER = "mkdir -p #{TMP_FOLDER_NAME} && cd #{TMP_FOLDER_NAME}".freeze
|
|
9
|
+
SUPPORTED_HOSTS = %w[github.com gitlab.com].freeze
|
|
9
10
|
|
|
10
11
|
command "release" do |c|
|
|
11
12
|
c.syntax = "renuo release"
|
|
12
|
-
c.summary = "Release a
|
|
13
|
+
c.summary = "Release a project's state of develop to main in one command."
|
|
13
14
|
c.description = "Creates a new release version of a project on main as either a Major, Minor, " \
|
|
14
|
-
"Patch or Custom release based on the current state of develop
|
|
15
|
-
|
|
15
|
+
"Patch or Custom release based on the current state of develop. " \
|
|
16
|
+
"Supports GitHub and GitLab repositories."
|
|
17
|
+
c.example "renuo release my-project minor", "release a minor release of renuo/my-project on GitHub"
|
|
18
|
+
c.example "renuo release renuo/my-project minor", "release a minor release of renuo/my-project on GitHub"
|
|
19
|
+
c.example "renuo release https://gitlab.com/renuo/project patch", "release a patch of a GitLab project"
|
|
16
20
|
c.example "renuo release my-project custom 2.5.0", "release my-project as release 2.5.0"
|
|
17
21
|
c.action { |args| new.run(args) }
|
|
18
22
|
end
|
|
@@ -39,6 +43,23 @@ class Renuo::Cli::Commands::Release # rubocop:disable Metrics/ClassLength
|
|
|
39
43
|
|
|
40
44
|
def validate_project_name
|
|
41
45
|
abort(">> No project name given.") unless @project_name
|
|
46
|
+
|
|
47
|
+
@host, @repo_path = repo_identifier(@project_name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def repo_identifier(input)
|
|
51
|
+
return ["github.com", "renuo/#{input}"] unless input.include?("/")
|
|
52
|
+
return ["github.com", input] unless input.start_with?("http://", "https://", "git@")
|
|
53
|
+
|
|
54
|
+
# Convert git@host:path to https://host/path
|
|
55
|
+
uri = input.sub(/^git@([^:]+):/, 'https://\1/').sub(/\.git$/, "")
|
|
56
|
+
parsed = URI.parse(uri)
|
|
57
|
+
host = parsed.host
|
|
58
|
+
repo_path = parsed.path.sub(%r{^/}, "")
|
|
59
|
+
|
|
60
|
+
return [host, repo_path] if SUPPORTED_HOSTS.include?(host)
|
|
61
|
+
|
|
62
|
+
abort(">> Unsupported host '#{host}'. Supported hosts: #{SUPPORTED_HOSTS.join(", ")}")
|
|
42
63
|
end
|
|
43
64
|
|
|
44
65
|
def validate_update_type
|
|
@@ -74,11 +95,20 @@ class Renuo::Cli::Commands::Release # rubocop:disable Metrics/ClassLength
|
|
|
74
95
|
|
|
75
96
|
def open_comparison_page
|
|
76
97
|
puts "Opening browser to double-check what is going to be deployed…"
|
|
77
|
-
open_path
|
|
98
|
+
open_path comparison_url
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def comparison_url
|
|
102
|
+
case @host
|
|
103
|
+
when "gitlab.com"
|
|
104
|
+
"https://#{@host}/#{@repo_path}/-/compare/#{main_branch}...develop"
|
|
105
|
+
else
|
|
106
|
+
"https://#{@host}/#{@repo_path}/compare/#{main_branch}...develop"
|
|
107
|
+
end
|
|
78
108
|
end
|
|
79
109
|
|
|
80
110
|
def checkout_project
|
|
81
|
-
abort(">> Project not found
|
|
111
|
+
abort(">> Project not found.") unless system("#{MOVE_TO_TMP_FOLDER} && git clone git@#{@host}:#{@repo_path}.git")
|
|
82
112
|
|
|
83
113
|
system(cmd_in_folder("git checkout #{main_branch} && git pull origin #{main_branch} &&" \
|
|
84
114
|
"git checkout #{develop_branch} && git pull origin #{develop_branch}"))
|
|
@@ -173,7 +203,7 @@ class Renuo::Cli::Commands::Release # rubocop:disable Metrics/ClassLength
|
|
|
173
203
|
end
|
|
174
204
|
|
|
175
205
|
def ask_for_final_confirmation
|
|
176
|
-
unless agree(">> Are you sure you wish to deploy '#{@
|
|
206
|
+
unless agree(">> Are you sure you wish to deploy '#{@repo_path}' " \
|
|
177
207
|
"as a #{@update_type} release (#{current_version} => #{@version})?")
|
|
178
208
|
abort(">> Cancelling Release.")
|
|
179
209
|
end
|
|
@@ -195,7 +225,7 @@ class Renuo::Cli::Commands::Release # rubocop:disable Metrics/ClassLength
|
|
|
195
225
|
end
|
|
196
226
|
|
|
197
227
|
def folder_name
|
|
198
|
-
@
|
|
228
|
+
@repo_path.split("/").last
|
|
199
229
|
end
|
|
200
230
|
|
|
201
231
|
def cleanup
|
|
@@ -203,7 +233,7 @@ class Renuo::Cli::Commands::Release # rubocop:disable Metrics/ClassLength
|
|
|
203
233
|
end
|
|
204
234
|
|
|
205
235
|
def main_branch
|
|
206
|
-
remote_repo = "git@
|
|
236
|
+
remote_repo = "git@#{@host}:#{@repo_path}.git"
|
|
207
237
|
@main_branch ||= `git ls-remote --heads #{remote_repo} main`.empty? ? "master" : "main"
|
|
208
238
|
end
|
|
209
239
|
|
data/lib/renuo/cli/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: renuo-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.17.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Renuo AG
|
|
@@ -85,6 +85,7 @@ files:
|
|
|
85
85
|
- lib/renuo/cli/commands/configure_sentry.rb
|
|
86
86
|
- lib/renuo/cli/commands/create_aws_project.rb
|
|
87
87
|
- lib/renuo/cli/commands/create_deploio_app.rb
|
|
88
|
+
- lib/renuo/cli/commands/create_deploio_object_storage.rb
|
|
88
89
|
- lib/renuo/cli/commands/create_heroku_app.rb
|
|
89
90
|
- lib/renuo/cli/commands/create_new_logins.rb
|
|
90
91
|
- lib/renuo/cli/commands/create_pr.rb
|
|
@@ -135,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
135
136
|
- !ruby/object:Gem::Version
|
|
136
137
|
version: '0'
|
|
137
138
|
requirements: []
|
|
138
|
-
rubygems_version: 3.
|
|
139
|
+
rubygems_version: 3.7.2
|
|
139
140
|
specification_version: 4
|
|
140
141
|
summary: The Renuo CLI automates some common workflows.
|
|
141
142
|
test_files: []
|