renuo-cli 4.17.2 → 4.18.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bd8ae089520815a2934d6aa8bd1b7209af01e717c1e623c0a53bfb0cda0931e
4
- data.tar.gz: 49c94fd014528566a51727e6f7938b56ff8a0ec37aa93c5a4292b3ba10a0abd2
3
+ metadata.gz: 9274f5e3f76a6fc8b38f2bcfbb958dc57d3f22dcff65c8f5f2ff88ded44a7110
4
+ data.tar.gz: 47cd65170765517b17b1aea2ec401122f89ce224632d209b33ca1a1abbd9075e
5
5
  SHA512:
6
- metadata.gz: 6d960d53deb1dc144cfeaa77311732139c0e29f651567934a7fbd3ea9d3a812f8f6fa77f83d90338ccc4fe55bf3f7a528aaa1e2191dbb120f09db031a13c8582
7
- data.tar.gz: e70f032d4d4c1b7323cd5fc177d93e6c9d37ff83b72a54e3ee5be368eb07e88132fd81e50233217ef862ce1b3d5df696bfb957390f664f40b530f4e0a13360b7
6
+ metadata.gz: 803d0f36fc550f57927e86b094f9d7523493e03948cdf7836a526e23ddf92025369a1ef72593b7d38b6221a99401ed30a7947e681cff39404717537dbc4d02d7
7
+ data.tar.gz: ca5ed8907659e2be3f0c598329a4e5b53c0a0bc9a45983418585cee254ec3d099db67c58f0f95eb1491f48cafaf0381f6cef95c7b170dccb7451f42a54ba959c
@@ -3,23 +3,25 @@
3
3
  # :nocov:
4
4
  class Renuo::Cli::Commands::CheckDeploioStatus
5
5
  TIMEOUT_IN_SECONDS = 600
6
- INTERVAL_IN_SECONDS = 30
7
-
8
- APP_NAME = ENV.fetch "DEPLOIO_APP_NAME", nil
9
- PROJECT = ENV.fetch "DEPLOIO_PROJECT", nil
6
+ INTERVAL_IN_SECONDS = 5
10
7
 
11
8
  command "check-deploio-status" do |c|
12
9
  c.syntax = "renuo check-deploio-status"
13
10
  c.summary = "Checks the build and release status of the deployment."
14
11
  c.description = "Checks the build and release status of the deployment."
15
- c.option "--git-revision <revision>", String, "The git revision to check"
12
+ c.option "-a", "--app <name>", String, "The name of the app"
13
+ c.option "-p", "--project <name>", String, "The name of the project"
14
+ c.option "-g", "--git-revision <revision>", String, "The git revision to check"
16
15
  c.action { |_, options| new(options).run }
17
16
  end
18
17
 
19
18
  def initialize(options)
20
- abort "missing env DEPLOIO_APP_NAME" if APP_NAME.nil?
21
- abort "missing env DEPLOIO_PROJECT" if PROJECT.nil?
22
19
  @revision = options.git_revision || `git rev-parse HEAD`.strip
20
+ @app = options.app || ENV.fetch("DEPLOIO_APP_NAME", nil)
21
+ @project = options.project || ENV.fetch("DEPLOIO_PROJECT", nil)
22
+
23
+ abort "missing app name" if @app.nil?
24
+ abort "missing project name" if @project.nil?
23
25
  end
24
26
 
25
27
  def run
@@ -39,7 +41,7 @@ class Renuo::Cli::Commands::CheckDeploioStatus
39
41
  end
40
42
 
41
43
  def fetch(type)
42
- command = "nctl get #{type} -a #{APP_NAME} -p #{PROJECT} -o yaml"
44
+ command = "nctl get #{type} -a #{@app} -p #{@project} -o yaml"
43
45
  stdout, stderr, status = Open3.capture3 command
44
46
 
45
47
  abort "error fetching #{type} information: #{stderr}" unless status.success?
@@ -47,7 +49,7 @@ class Renuo::Cli::Commands::CheckDeploioStatus
47
49
  end
48
50
 
49
51
  def fetch_build_logs
50
- command = "nctl logs build -a #{APP_NAME} -p #{PROJECT} -l 5000 --no-labels"
52
+ command = "nctl logs build -a #{@app} -p #{@project} -l 5000 --no-labels"
51
53
  stdout, stderr, status = Open3.capture3 command
52
54
 
53
55
  abort "error fetching build logs: #{stderr}" unless status.success?
@@ -9,7 +9,7 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
9
9
  PROJECT_NAME_PREFIX = "renuo-"
10
10
 
11
11
  command "create-deploio-app" do |c|
12
- c.syntax = "renuo create-deploio-app"
12
+ c.syntax = "renuo create-deploio-app [project-name] [git-url]"
13
13
  c.summary = "Generates the script necessary to setup an application on Deploio."
14
14
  c.description = <<~DESC
15
15
  Generates the script necessary to setup an application on Deploio.
@@ -20,14 +20,16 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
20
20
  - Configure repository access by generating SSH keys and adding them to 1Password.
21
21
  - Create the application and database for each specified environment.
22
22
  DESC
23
+ c.option "-o", "--org <organization>", String, "The organization name"
23
24
  c.example "renuo create-deploio-app my-app git@github.com:renuo/my-app.git",
24
25
  "Prompts the user for the necessary information and generates the commands " \
25
26
  "to create the project, databases, and apps on Deploio."
26
- c.action { |args| new.run(args) }
27
+ c.action { |args, options| new.run(args, options) }
27
28
  end
28
29
 
29
- def run(args)
30
+ def run(args, options = {})
30
31
  @project_name, @git_url = args
32
+ @options = options
31
33
  parse_arguments
32
34
  setup_commands
33
35
  setup_environments
@@ -51,7 +53,12 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
51
53
 
52
54
  private
53
55
 
56
+ def valid_name?(name)
57
+ name&.length&.between?(3, 63) && name.match?(/^[a-z0-9-]+$/)
58
+ end
59
+
54
60
  def parse_arguments
61
+ set_organization
55
62
  set_project_name
56
63
  set_git_url
57
64
  set_postgres_version
@@ -60,7 +67,7 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
60
67
 
61
68
  def set_project_name
62
69
  loop do
63
- break if @project_name&.length&.between?(3, 63) && @project_name.match?(/^[a-z0-9-]+$/)
70
+ break if valid_name?(@project_name)
64
71
 
65
72
  say ">> Project name must be between 3 and 63 characters and can only contain lowercase letters, " \
66
73
  "numbers, and hyphens. Please try again.".colorize(:red)
@@ -69,7 +76,7 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
69
76
  end
70
77
 
71
78
  @project_display_name = @project_name
72
- @project_name = PROJECT_NAME_PREFIX + @project_name
79
+ @project_name_with_org_prefix = "#{@organization}-#{@project_name}"
73
80
  end
74
81
 
75
82
  def set_git_url
@@ -98,7 +105,23 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
98
105
  end
99
106
 
100
107
  def set_vault_name
101
- @vault_name = ask("Enter the 1Password vault name: ") { |q| q.default = "Deploio" }
108
+ @vault_name = ask("SSH Credentials for deploio to access the git repo will be stored on 1Password. " \
109
+ "Enter the 1Password vault name: ") do |q|
110
+ q.default = "Deploio"
111
+ end
112
+ end
113
+
114
+ def set_organization
115
+ @organization = @options.org if @options.org
116
+
117
+ loop do
118
+ break if valid_name?(@organization)
119
+
120
+ say ">> Organization name must be between 3 and 63 characters and can only contain lowercase letters, " \
121
+ "numbers, and hyphens. Please try again.".colorize(:red)
122
+
123
+ @organization = ask("Enter the organization name (default: renuo): ") { |q| q.default = "renuo" }
124
+ end
102
125
  end
103
126
 
104
127
  def setup_commands
@@ -127,7 +150,7 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
127
150
 
128
151
  def say_project_creation
129
152
  say <<~OUTPUT
130
- nctl create project #{@project_name} --display-name='#{@project_display_name}'
153
+ nctl create project #{@project_name_with_org_prefix} --display-name='#{@project_display_name}' --organization=#{@organization}
131
154
  OUTPUT
132
155
  end
133
156
 
@@ -135,14 +158,14 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
135
158
  if environment == "main"
136
159
  say <<~OUTPUT
137
160
  nctl create postgres #{environment} \\
138
- --project=#{@project_name} \\
161
+ --project=#{@project_name_with_org_prefix} \\
139
162
  --postgres-version=#{@postgres_version} \\
140
163
  --machine-type=nine-db-xs
141
164
  OUTPUT
142
165
  else
143
166
  say <<~OUTPUT
144
167
  nctl create postgresdatabase #{environment} \\
145
- --project=#{@project_name} \\
168
+ --project=#{@project_name_with_org_prefix} \\
146
169
  --postgres-database-version=#{@postgres_version}
147
170
  OUTPUT
148
171
  end
@@ -151,7 +174,7 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
151
174
  def say_app_creation(environment)
152
175
  say <<~OUTPUT
153
176
  nctl create app #{environment} \\
154
- --project #{@project_name} \\
177
+ --project #{@project_name_with_org_prefix} \\
155
178
  --git-ssh-private-key-from-file=#{GITHUB_SSH_KEY_FILE_NAME} \\
156
179
  --git-url=#{@git_url} \\
157
180
  --git-revision="#{environment}" \\
@@ -169,15 +192,15 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
169
192
  --account renuo.1password.com \\
170
193
  --category ssh \\
171
194
  --ssh-generate-key #{SSH_ALGORITHM.downcase} \\
172
- --title "#{@project_name}-deploy-key" \\
195
+ --title "#{@project_name_with_org_prefix}-deploy-key" \\
173
196
  --vault #{@vault_name} \\
174
- --tags #{@project_name}
197
+ --tags #{@project_name_with_org_prefix}
175
198
 
176
199
  # Extract keys to temp files for deploio usage
177
- op item get "#{@project_name}-deploy-key" --vault #{@vault_name} \\
200
+ op item get "#{@project_name_with_org_prefix}-deploy-key" --vault #{@vault_name} \\
178
201
  --account renuo.1password.com \\
179
202
  --reveal --fields "public key" > #{file_name}.pub
180
- op item get "#{@project_name}-deploy-key" --vault #{@vault_name} --reveal \\
203
+ op item get "#{@project_name_with_org_prefix}-deploy-key" --vault #{@vault_name} --reveal \\
181
204
  --account renuo.1password.com \\
182
205
  --fields "private key" --format json | jq -r '.ssh_formats.openssh.value' > #{file_name}
183
206
  OUTPUT
@@ -1,49 +1,111 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cgi"
4
+
3
5
  class Renuo::Cli::Commands::CreatePr
4
6
  command "create-pr" do |c|
5
7
  c.syntax = "renuo create-pr"
6
8
  c.summary = "Creates a PR for the current branch"
7
9
  c.description = "Creates a PR, assigns it to you and automatically inserts the Redmine ticket number into " \
8
10
  "the PR body"
9
- c.option "--title <title>", String, "The title of the pull request (optional)"
10
- c.option "--redmine-ticket <number>", Integer, "The redmine ticket number (optional)"
11
+ c.option "-t", "--title <title>", String, "The title of the pull request (optional)"
12
+ c.option "-r", "--redmine-ticket <number>", Integer, "The redmine ticket number (optional)"
11
13
  c.example "Create a PR with the title 'Implement XYZ'",
12
14
  "renuo create-pr --title 'Implement XYZ'"
13
15
  c.action { |_, options| new.run(options) }
14
16
  end
15
17
 
16
18
  def run(opts)
17
- create_pr(opts)
19
+ pr_url = build_pr_url(opts)
20
+ open_browser(pr_url)
18
21
  end
19
22
 
20
23
  private
21
24
 
22
- def create_pr(opts)
23
- command = [
24
- "gh pr create",
25
- "--assignee @me",
26
- pr_title(opts),
27
- "--body \"#{pr_body(opts)}\"",
28
- "--web"
29
- ].compact.join(" ")
25
+ def build_pr_url(opts)
26
+ repo_url = fetch_remote_url_in_https
27
+ current_branch = fetch_current_branch
28
+ default_branch = fetch_head_branch
29
+ title = pr_title(opts, current_branch, default_branch)
30
+ body = pr_body(opts, current_branch)
31
+
32
+ "#{repo_url}/compare/#{default_branch}...#{current_branch}?expand=1" \
33
+ "&assignees=#{github_user_login}" \
34
+ "&title=#{CGI.escape(title)}" \
35
+ "#{"&body=#{CGI.escape(body)}" unless body.empty?}"
36
+ end
37
+
38
+ def fetch_remote_url_in_https
39
+ url = `git config --get remote.origin.url`.strip
40
+ if url.empty?
41
+ puts "Error: Unable to retrieve the remote repository URL."
42
+ exit 1
43
+ end
30
44
 
31
- puts `#{command}`
45
+ if url.start_with?("git@")
46
+ url = url.gsub(/^git@([^:]+):/, 'https://\1/').gsub(/\.git$/, "")
47
+ end
48
+
49
+ url
50
+ end
51
+
52
+ def fetch_current_branch
53
+ branch = `git rev-parse --abbrev-ref HEAD`.strip
54
+ if branch.empty?
55
+ puts "Error: Unable to determine the current Git branch."
56
+ exit 1
57
+ end
58
+ branch
32
59
  end
33
60
 
34
- def pr_title(opts)
35
- opts.title ? "--title \"#{opts.title}\"" : "--fill"
61
+ def fetch_head_branch
62
+ ref = `git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null`.strip
63
+ if ref.empty?
64
+ puts "Warning: Unable to determine the default branch. Falling back to 'develop'."
65
+ return "develop"
66
+ end
67
+ ref.split("/").last
36
68
  end
37
69
 
38
- def pr_body(opts)
39
- redmine_ticket_number = redmine_ticket_number(opts)
70
+ def pr_title(opts, current_branch, default_branch)
71
+ opts.title || first_commit_message(default_branch) || current_branch
72
+ end
73
+
74
+ def first_commit_message(default_branch)
75
+ message = `git log #{default_branch}..HEAD --format=%s --reverse 2>/dev/null`.strip.split("\n").first
76
+ message unless message.to_s.empty?
77
+ end
78
+
79
+ def pr_body(opts, current_branch)
80
+ redmine_ticket_number = redmine_ticket_number(opts, current_branch)
40
81
  return "" unless redmine_ticket_number
41
82
 
42
83
  "TICKET-#{redmine_ticket_number}"
43
84
  end
44
85
 
45
- def redmine_ticket_number(opts)
46
- current_branch = `git branch --show-current`.strip
86
+ def redmine_ticket_number(opts, current_branch)
47
87
  opts.redmine_ticket || current_branch.match(/(\d+)/)&.captures&.first
48
88
  end
89
+
90
+ def github_user_login
91
+ login = `gh api user -q ".login"`.strip
92
+ if login.empty?
93
+ puts "Error: Unable to retrieve GitHub user."
94
+ exit 1
95
+ end
96
+ login
97
+ end
98
+
99
+ def open_browser(url)
100
+ case RbConfig::CONFIG["host_os"]
101
+ when /darwin/
102
+ system("open", url)
103
+ when /linux/
104
+ system("xdg-open", url)
105
+ else
106
+ puts "Error: Unable to detect the operating system to open the browser."
107
+ puts "Please open this URL manually: #{url}"
108
+ exit 1
109
+ end
110
+ end
49
111
  end
@@ -17,8 +17,8 @@ class Renuo::Cli::Commands::Debug
17
17
  The command will show a menu with all found targets.
18
18
  It will only use a cache. You must manually update the cache with option 1).
19
19
  DESC
20
- c.option "--heroku", "Show only Heroku apps"
21
- c.option "--deploio", "Show only Deploio apps"
20
+ c.option "-H", "--heroku", "Show only Heroku apps"
21
+ c.option "-d", "--deploio", "Show only Deploio apps"
22
22
  c.action do |args, options|
23
23
  new.run(args, options)
24
24
  rescue Interrupt
@@ -16,9 +16,9 @@ class Renuo::Cli::Commands::DisplayName
16
16
  c.example 'Display "Peter Muster" on the dashboard', 'renuo display-name "Peter Muster"'
17
17
  c.example "Remove the current name from the dashboard", "renuo display-name --delete"
18
18
  c.example "Override the current message on the dashboard", "renuo display-name Happy friday 🍻 --override"
19
- c.option "--delete", "Deletes the current name"
20
- c.option "--override", "Overrides the entire message"
21
- c.option "--monitor", "Open the Google slides"
19
+ c.option "-d", "--delete", "Deletes the current name"
20
+ c.option "-o", "--override", "Overrides the entire message"
21
+ c.option "-m", "--monitor", "Open the Google slides"
22
22
  c.action { |args, options| new.run(args, options) }
23
23
  end
24
24
 
@@ -6,7 +6,7 @@ class Renuo::Cli::Commands::FetchSecrets # rubocop:disable Metrics/ClassLength
6
6
  command "fetch-secrets" do |c|
7
7
  c.syntax = "renuo fetch-secrets"
8
8
  c.summary = "Fetches the needed secrets in a project from the renuo secrets store"
9
- c.option "--init <private_vault_link>", String, "Initializes the renuo secrets store"
9
+ c.option "-i", "--init <private_vault_link>", String, "Initializes the renuo secrets store"
10
10
  c.description = <<~DESCRIPTION
11
11
  Run the command within a project folder to fetch the secrets from the renuo secrets store.
12
12
  You need to create a "Secure Note" for your project and right to click copy the private link.
@@ -6,11 +6,11 @@ class Renuo::Cli::Commands::GithubReplace
6
6
  c.summary = "Replaces text in multiple GitHub projects and automatically creates a pull request"
7
7
  c.description = "Finds and replaces the contents of specific files in Renuo GitHub projects and " \
8
8
  "automatically creates a pull request"
9
- c.option "--projects <name,name,..>", String, "The github project to clone and edit"
10
- c.option "--branch <name>", String, "The branch to create"
11
- c.option "--title <name>", String, "The title of the pull request"
9
+ c.option "-p", "--projects <name,name,..>", String, "The github project to clone and edit"
10
+ c.option "-b", "--branch <name>", String, "The branch to create"
11
+ c.option "-t", "--title <name>", String, "The title of the pull request"
12
12
  c.option "--body <text>", String, "The body of the pull request"
13
- c.option "--files <files,files,..>", String, "The files to check"
13
+ c.option "-f", "--files <files,files,..>", String, "The files to check"
14
14
  c.example "Update Semaphore Ubuntu version",
15
15
  "renuo github-replace ubuntu1804 ubuntu2204 --projects=renuo-cli,renuo-website-v3 " \
16
16
  '--branch=feature/1234-update-ubuntu --title="Update os_image version" --body=TICKET-1234 ' \
@@ -3,7 +3,7 @@
3
3
  # :nocov:
4
4
  module Renuo
5
5
  class Cli
6
- VERSION = "4.17.2"
6
+ VERSION = "4.18.0"
7
7
  NAME = "renuo-cli"
8
8
  end
9
9
  end
data/lib/renuo/cli.rb CHANGED
@@ -4,13 +4,11 @@ require "active_support"
4
4
  require "active_support/core_ext"
5
5
  require "colorize"
6
6
  require "fileutils"
7
- require "gems"
8
7
  require "highline"
9
8
  require "json"
10
9
  require "net/http"
11
10
  require "open3"
12
11
  require "psych"
13
- require "rubygems"
14
12
  require "securerandom"
15
13
  require "tmpdir"
16
14
  require "uri"
@@ -29,35 +27,16 @@ module Renuo
29
27
  module Commands; end
30
28
  module Services; end
31
29
 
32
- # include CommandHelper
33
-
34
30
  def start
35
31
  require "commander/import"
36
32
 
37
33
  program :version, Renuo::Cli::VERSION
38
34
  program :description, "Renuo CLI"
39
35
  program :help_paging, false
40
- update
41
36
 
42
37
  Dir[File.expand_path("cli/{commands,services}/*.rb", __dir__)].each { |f| require f }
43
38
  default_command :help
44
39
  end
45
-
46
- private
47
-
48
- def update
49
- info = Gems.info Renuo::Cli::NAME
50
- return unless Gem::Version.new(Renuo::Cli::VERSION) < Gem::Version.new(info["version"])
51
-
52
- say "You are running the version #{Renuo::Cli::VERSION} but the brand new #{info["version"]} is available. 🎉"
53
-
54
- if agree("Why don't you update with `gem update renuo-cli`? I can run it for you. 💪")
55
- system("gem update #{Renuo::Cli::NAME}")
56
- abort "Nice! I updated myself. 🤩 Now you can run the command again."
57
- end
58
-
59
- abort("Good. Just do it yourself then...😒")
60
- end
61
40
  end
62
41
  end
63
42
  # :nocov:
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.17.2
4
+ version: 4.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renuo AG
@@ -51,20 +51,6 @@ dependencies:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '5.0'
54
- - !ruby/object:Gem::Dependency
55
- name: gems
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '1.1'
61
- type: :runtime
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '1.1'
68
54
  description: The Renuo CLI automates some commonly used workflows by providing a command
69
55
  line interface.
70
56
  email: