renuo-cli 4.19.0 → 4.21.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: 67d1a1aabbf0a54a5f93018178724eef959d87e61b6b5e7819c72c826646b925
4
- data.tar.gz: 8b584d301b391e7bab989af846092bffd7635ba84862d31621fc45b76969b580
3
+ metadata.gz: de68476aa8e37811fd54ca8248bc8a30ddeb8594ada90207201a968e1e106b59
4
+ data.tar.gz: d7d2a77ec3fb9e520053a82be66f4ac2dd782179cf002c75ba7fd7b277d22e32
5
5
  SHA512:
6
- metadata.gz: 6c94a81ccf21115e5bdd9149ea408d31686c0f7b018a292f633bfae5b9da0e2dde58ecb3cd32d88f7ebb2a63207ecffd38c526ba342aa2d552bd07554256cf14
7
- data.tar.gz: 7bb4bb3454243794e9efed8becd728a7d976f972618b8d29af226072c602c2c49d069e7a01ed8500faaf9645556bdcf9f490040e3ada0d2e3609e6a64e65944a
6
+ metadata.gz: 9a1ad1c501f0df98ee51a8ed38e08358ae6b03e020a2ee3e9d598ce98026f0db612c4323385dbe188f142a1b5d5b163a894c99f89b6429dd54abf9db4d428e88
7
+ data.tar.gz: a4618b96d73466267c395546f8a4d918fbb8de282046c471f86023bbabf25db349f9357433d1acff722120c0548aaa8b4c5fa0db6cdd3f782d210e83c4316493
@@ -7,7 +7,7 @@ class Renuo::Cli::Commands::CheckDeploioStatus
7
7
 
8
8
  command "check-deploio-status" do |c|
9
9
  c.syntax = "renuo check-deploio-status"
10
- c.summary = "Checks the build and release status of the deployment."
10
+ c.summary = "DEPRECATED: Use 'renuo ci check-deploio-status' instead."
11
11
  c.description = "Checks the build and release status of the deployment."
12
12
  c.option "-a", "--app <name>", String, "The name of the app"
13
13
  c.option "-p", "--project <name>", String, "The name of the project"
@@ -25,6 +25,7 @@ class Renuo::Cli::Commands::CheckDeploioStatus
25
25
  end
26
26
 
27
27
  def run
28
+ warn "DEPRECATED: Use 'renuo ci check-deploio-status' instead."
28
29
  puts "(1/2) Checking build status for revision #{@revision}..."
29
30
  poll "build"
30
31
  abort "build check timed out after #{TIMEOUT_IN_SECONDS} seconds" if build.nil?
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ module Renuo::Cli::Commands::Ci
5
+ class CheckDeploioStatus
6
+ TIMEOUT_IN_SECONDS = 600
7
+ INTERVAL_IN_SECONDS = 5
8
+
9
+ command "ci check-deploio-status" do |c|
10
+ c.syntax = "renuo ci check-deploio-status"
11
+ c.summary = "Checks the build and release status of the deployment."
12
+ c.description = c.summary
13
+ c.option "-p", "--project <name>", String, "The name of the project"
14
+ c.action { |args, options| new(args, options).run }
15
+ end
16
+
17
+ def run
18
+ puts "(1/2) Checking build status for revision #{@revision}..."
19
+ poll "build"
20
+ abort "build check timed out after #{TIMEOUT_IN_SECONDS} seconds" if build.nil?
21
+
22
+ puts "(2/2) Checking release status for build #{build_name}..."
23
+ poll "release"
24
+ abort "release check timed out after #{TIMEOUT_IN_SECONDS} seconds" if release.nil?
25
+ end
26
+
27
+ private
28
+
29
+ def initialize(args, options)
30
+ @app = args.first
31
+ @project = options.project
32
+ @revision = ENV.fetch("SEMAPHORE_GIT_SHA", nil)
33
+
34
+ abort "missing app name" unless @app
35
+ abort "missing project name" unless @project
36
+ abort "this command must be run in Semaphore" unless @revision
37
+ end
38
+
39
+ def system!(cmd)
40
+ abort unless system cmd
41
+ end
42
+
43
+ def fetch(type)
44
+ command = "nctl get #{type} -a #{@app} -p #{@project} -o yaml"
45
+ stdout, stderr, status = Open3.capture3 command
46
+
47
+ abort "error fetching #{type} information: #{stderr}" unless status.success?
48
+ Psych.load_stream stdout
49
+ end
50
+
51
+ def fetch_build_logs
52
+ command = "nctl logs build -a #{@app} -p #{@project} -l 5000 --no-labels"
53
+ stdout, stderr, status = Open3.capture3 command
54
+
55
+ puts "error fetching build logs: #{stderr}" unless status.success?
56
+ stdout
57
+ end
58
+
59
+ def build
60
+ @build ||= fetch("builds").find do |build|
61
+ build.dig("spec", "forProvider", "sourceConfig", "git", "revision") == @revision
62
+ end
63
+ end
64
+
65
+ def build_name
66
+ @build_name ||= build.dig("metadata", "name")
67
+ end
68
+
69
+ def build_status
70
+ build.dig("status", "atProvider", "buildStatus")
71
+ end
72
+
73
+ def release
74
+ @release ||= fetch("releases").find do |release|
75
+ release.dig("spec", "forProvider", "build", "name") == build_name
76
+ end
77
+ end
78
+
79
+ def release_status
80
+ release.dig("status", "atProvider", "releaseStatus")
81
+ end
82
+
83
+ def succeeded?(status, type) # rubocop:disable Metrics/MethodLength
84
+ time = "[#{Time.now.utc.iso8601}]"
85
+
86
+ case status
87
+ when "available", "success"
88
+ puts "#{time} #{type} succeeded"
89
+ true
90
+ when "superseded"
91
+ puts "#{time} release was superseded"
92
+ true
93
+ when "paused"
94
+ abort "#{time} app is paused"
95
+ when "error", "failed", "failure"
96
+ puts fetch_build_logs
97
+ abort "#{time} #{type} failed"
98
+ else
99
+ puts "#{time} #{type} status is #{status}, waiting..."
100
+ instance_variable_set :"@#{type}", nil
101
+ end
102
+ end
103
+
104
+ def poll(type)
105
+ elapsed = 0
106
+
107
+ while elapsed < TIMEOUT_IN_SECONDS
108
+ if send type
109
+ break if succeeded?(send(:"#{type}_status"), type)
110
+ else
111
+ puts "no matching #{type} found, waiting..."
112
+ end
113
+
114
+ sleep INTERVAL_IN_SECONDS
115
+ elapsed += INTERVAL_IN_SECONDS
116
+ end
117
+ end
118
+ end
119
+ end
120
+ # :nocov:
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renuo::Cli::Commands::Ci
4
+ class UpdateDeploioApp
5
+ command "ci update-deploio-app" do |c|
6
+ c.syntax = "renuo ci update-deploio-app"
7
+ c.summary = "Updates a Deploio app."
8
+ c.description = c.summary
9
+ c.option "-d", "--docker", "If the app uses a Dockerfile"
10
+ c.option "-p", "--project <name>", String, "The name of the project"
11
+ c.example "renuo ci update-deploio-app main -dp renuo-dashboard",
12
+ "Updates the 'main' app of the 'renuo-dashboard' project using a Dockerfile"
13
+ c.action { |args, options| new(args, options).run }
14
+ end
15
+
16
+ def run
17
+ system! "checkout --use-cache" if @docker
18
+ system! "echo 'deb [trusted=yes] https://repo.nine.ch/deb/ /' " \
19
+ "| sudo tee /etc/apt/sources.list.d/repo.nine.ch.list"
20
+ system! "sudo apt-get update -qqo Dir::Etc::sourcelist=/etc/apt/sources.list.d/repo.nine.ch.list"
21
+ system! "sudo apt-get install -qq nctl"
22
+ system! "nctl auth login"
23
+ system! "nctl update app #{@app} -p #{@project} --env APP_REVISION=$SEMAPHORE_GIT_SHA " \
24
+ "#{"--build-env RUBY_VERSION=#{File.read(".ruby-version").strip} " if @docker}" \
25
+ "--git-revision $SEMAPHORE_GIT_SHA --skip-repo-access-check"
26
+ end
27
+
28
+ private
29
+
30
+ def initialize(args, options)
31
+ @app = args.first
32
+ @project = options.project
33
+ @docker = options.docker
34
+
35
+ abort "missing app name" unless @app
36
+ abort "missing project name" unless @project
37
+ abort "this command must be run in Semaphore" unless ENV.key?("SEMAPHORE_GIT_SHA")
38
+ end
39
+
40
+ def system!(cmd)
41
+ abort unless system cmd
42
+ end
43
+ end
44
+ end
@@ -155,25 +155,14 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
155
155
  end
156
156
 
157
157
  def say_database_creation(environment)
158
- if environment == "main"
159
- say <<~OUTPUT
160
- nctl create postgres #{environment} \\
161
- --project=#{@project_name_with_org_prefix} \\
162
- --postgres-version=#{@postgres_version} \\
163
- --machine-type=nine-db-xs \\
164
- --allowed-cidrs=0.0.0.0/0 \\
165
- --location=nine-es34
166
- OUTPUT
167
- else
168
- say <<~OUTPUT
169
- nctl create postgresdatabase #{environment} \\
170
- --project=#{@project_name_with_org_prefix} \\
171
- --postgres-database-version=#{@postgres_version} \\
172
- --location=nine-es34 \\
173
- --backup-schedule=daily
174
- --collation=C.UTF-8
175
- OUTPUT
176
- end
158
+ say <<~OUTPUT
159
+ nctl create postgresdatabase #{environment} \\
160
+ --project=#{@project_name_with_org_prefix} \\
161
+ --postgres-database-version=#{@postgres_version} \\
162
+ --location=nine-es34 \\
163
+ --backup-schedule=daily \\
164
+ --collation=C.UTF-8
165
+ OUTPUT
177
166
  end
178
167
 
179
168
  def say_app_creation(environment)
@@ -3,22 +3,26 @@
3
3
  require_relative "../services/cache"
4
4
  require_relative "../services/deploio"
5
5
  require_relative "../services/heroku"
6
+ require_relative "../services/hetzner"
7
+ require "shellwords"
6
8
 
7
- class Renuo::Cli::Commands::Debug
9
+ class Renuo::Cli::Commands::Debug # rubocop:disable Metrics/ClassLength
8
10
  Cache = Renuo::Cli::Services::Cache
9
11
  Deploio = Renuo::Cli::Services::Deploio
10
12
  Heroku = Renuo::Cli::Services::Heroku
13
+ Hetzner = Renuo::Cli::Services::Hetzner
11
14
 
12
15
  command "debug" do |c|
13
16
  c.syntax = "renuo debug <app-name or domain>"
14
17
  c.summary = "Shortcut to debug apps"
15
18
  c.description = <<~DESC
16
19
  Enter the container or show logs of the available apps on Heroku or Deploio.
17
- The command will show a menu with all found targets.
20
+ The command will show a menu with all found targets across all organizations.
18
21
  It will only use a cache. You must manually update the cache with option 1).
19
22
  DESC
20
23
  c.option "-H", "--heroku", "Show only Heroku apps"
21
24
  c.option "-d", "--deploio", "Show only Deploio apps"
25
+ c.option "-z", "--hetzner", "Show only Hetzner vms"
22
26
  c.action do |args, options|
23
27
  new.run(args, options)
24
28
  rescue Interrupt
@@ -33,46 +37,56 @@ class Renuo::Cli::Commands::Debug
33
37
  query = args[0]
34
38
  abort(">> Please provide an app name or domain.") if query.blank?
35
39
 
36
- cloud_unspecified = !options.heroku && !options.deploio
40
+ cloud_unspecified = !options.heroku && !options.deploio && !options.hetzner
37
41
  should_scan_heroku = options.heroku || cloud_unspecified
38
42
  should_scan_deploio = options.deploio || cloud_unspecified
43
+ should_scan_hetzner = options.hetzner || cloud_unspecified
39
44
 
40
45
  choose do |menu| # rubocop:todo Metrics/BlockLength
41
46
  deploio_cache_info = "Deploio: #{Cache.stored_at("deploio_apps") || "never"}"
42
47
  heroku_cache_info = "Heroku: #{Cache.stored_at("heroku_apps") || "never"}"
48
+ hetzner_cache_info = "Hetzner: #{Cache.stored_at("hetzner_vms") || "never"}"
43
49
 
44
- menu.choice "Update caches (#{deploio_cache_info}, #{heroku_cache_info})" do
50
+ menu.choice "Update caches (#{deploio_cache_info}, #{heroku_cache_info}, #{hetzner_cache_info})" do
45
51
  if should_scan_deploio
46
52
  say "Updating Deploio cache"
47
53
  Cache.store("deploio_apps", Deploio.fetch_apps)
54
+ Cache.store("deploio_vms", Deploio.fetch_vms)
48
55
  end
49
56
  if should_scan_heroku
50
57
  say "Updating Heroku cache..."
51
58
  Cache.store("heroku_apps", Heroku.fetch_apps)
52
59
  end
60
+ if should_scan_hetzner
61
+ say "Updating Hetzner cache..."
62
+ Cache.store("hetzner_vms", Hetzner.fetch_vms)
63
+ end
53
64
  say "Caches updated"
54
65
  end
55
66
 
56
67
  open_cmds = []
57
68
 
58
- # rubocop:disable Layout/LineLength
59
69
  if should_scan_deploio && Cache.stored_at("deploio_apps")
60
70
  select_deploio_targets(query).each do |app|
61
- bash_cmd = "nctl #{bold("exec")} app #{bold(app[:name])} bash --project #{bold(app[:namespace])}"
62
- menu.choice(bash_cmd) { exec bash_cmd.squish }
71
+ display_cmd, exec_cmd = nctl_command(app, "exec", "bash")
72
+ menu.choice(display_cmd) { exec exec_cmd.squish }
63
73
 
64
- rails_console_cmd = "nctl #{bold("exec")} app #{bold(app[:name])} bundle #{bold("exec")} rails console --project #{bold(app[:namespace])}"
65
- menu.choice(rails_console_cmd) { exec rails_console_cmd.squish }
74
+ display_cmd, exec_cmd = nctl_command(app, "exec", "bundle exec rails console")
75
+ menu.choice(display_cmd) { exec exec_cmd.squish }
66
76
 
67
- log_cmd = "nctl #{bold("logs")} app #{bold(app[:name])} -f --project #{bold(app[:namespace])}"
68
- menu.choice(log_cmd) { exec log_cmd.squish }
77
+ display_cmd, exec_cmd = nctl_command(app, "logs", "-f")
78
+ menu.choice(display_cmd) { exec exec_cmd.squish }
69
79
 
70
- app[:hosts].each do |host|
71
- open_cmds << "open https://#{host}"
72
- end
80
+ app[:hosts].each { |host| open_cmds << "open https://#{host}" }
81
+ end
82
+ end
83
+
84
+ if should_scan_deploio && Cache.stored_at("deploio_vms")
85
+ select_deploio_vm_targets(query).each do |vm|
86
+ bash_cmd = "ssh root@#{vm[:fqdn]} docker ps"
87
+ menu.choice(bash_cmd) { exec bash_cmd.squish }
73
88
  end
74
89
  end
75
- # rubocop:enable Layout/LineLength
76
90
 
77
91
  if should_scan_heroku && Cache.stored_at("heroku_apps")
78
92
  select_heroku_targets(query).each do |app|
@@ -91,6 +105,14 @@ class Renuo::Cli::Commands::Debug
91
105
  end
92
106
  end
93
107
 
108
+ if should_scan_hetzner && Cache.stored_at("hetzner_vms")
109
+ select_hetzner_vm_targets(query).each do |vm|
110
+ bash_cmd = "ssh root@#{vm[:fqdn] || vm[:public_ip]} docker ps"
111
+ menu.choice(bash_cmd) { exec bash_cmd.squish }
112
+ open_cmds << "open https://console.hetzner.com/projects/#{vm[:project_id]}/servers/#{vm[:id]}"
113
+ end
114
+ end
115
+
94
116
  open_cmds.uniq.each do |cmd|
95
117
  menu.choice(cmd) { exec cmd.squish }
96
118
  end
@@ -104,7 +126,38 @@ class Renuo::Cli::Commands::Debug
104
126
 
105
127
  def select_deploio_targets(query)
106
128
  Cache.restore("deploio_apps").select do |app|
107
- app[:name].include?(query) || app[:namespace].include?(query) || app[:hosts].any? { |host| host.include?(query) }
129
+ app[:name].include?(query) ||
130
+ app[:namespace].include?(query) ||
131
+ app[:hosts].any? { |host| host.include?(query) }
132
+ end
133
+ end
134
+
135
+ def nctl_command(app, subcommand, trailing_args)
136
+ plain = "nctl #{subcommand} app #{app[:name]} #{trailing_args} --project #{app[:namespace]}"
137
+ display = "nctl #{bold(subcommand)} app #{bold(app[:name])} #{trailing_args} --project #{bold(app[:namespace])}"
138
+ with_deploio_org(app, display, plain)
139
+ end
140
+
141
+ def with_deploio_org(app, display_command, exec_command)
142
+ organization = app[:organization].to_s
143
+ return [display_command, exec_command] if organization.empty?
144
+
145
+ display_cmd = "nctl auth set-org #{bold(Shellwords.escape(organization))} && #{display_command}"
146
+ exec_cmd = "nctl auth set-org #{Shellwords.escape(organization)} && #{exec_command}"
147
+ [display_cmd, exec_cmd]
148
+ end
149
+
150
+ def select_deploio_vm_targets(query)
151
+ Cache.restore("deploio_vms").select do |vm|
152
+ vm[:name].include?(query) || vm[:namespace].include?(query) ||
153
+ vm[:hostname].include?(query) || vm[:ip].include?(query) ||
154
+ vm[:reverse_dns].include?(query) || vm[:fqdn].include?(query)
155
+ end
156
+ end
157
+
158
+ def select_hetzner_vm_targets(query)
159
+ Cache.restore("hetzner_vms").select do |vm|
160
+ vm[:name].include?(query) || vm[:public_ip].include?(query) || vm[:fqdn]&.include?(query)
108
161
  end
109
162
  end
110
163
 
@@ -1,19 +1,75 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "shellwords"
4
+
3
5
  class Renuo::Cli::Services::Deploio
4
6
  class << self
5
7
  def fetch_apps
6
- fetch_apps_cmd = %(nctl get apps -A -o yaml)
7
- stdout, stderr, status = Open3.capture3 fetch_apps_cmd
8
- raise "Error fetching Deploio app list: #{stderr}" unless status.success?
8
+ active_org, available_orgs = fetch_whoami_orgs
9
9
 
10
- YAML.load_stream(stdout).map do |app|
10
+ available_orgs.flat_map do |organization|
11
+ set_organization(organization)
12
+ parse_apps(fetch_apps_yaml, organization)
13
+ end
14
+ ensure
15
+ set_organization(active_org)
16
+ end
17
+
18
+ def fetch_whoami_orgs
19
+ stdout, = run_nctl_command('nctl auth whoami -o "yaml"')
20
+ whoami = YAML.safe_load(stdout)
21
+
22
+ [whoami["organization"], whoami["orgs"]]
23
+ end
24
+
25
+ def parse_apps(yaml, organization)
26
+ YAML.load_stream(yaml).filter_map do |app|
11
27
  name = app.dig("metadata", "name")
12
28
  namespace = app.dig("metadata", "namespace")
13
29
  spec_hosts = app.dig("spec", "forProvider", "hosts") || []
14
30
 
15
- { name: name, namespace: namespace, hosts: spec_hosts }
31
+ { name: name, namespace: namespace, hosts: spec_hosts, organization: organization }
32
+ end
33
+ end
34
+
35
+ def fetch_vms
36
+ fetch_vms_cmd = %(nctl get cloudvm -A -o yaml)
37
+ stdout, stderr, status = Open3.capture3 fetch_vms_cmd
38
+ raise "Error fetching Deploio app list: #{stderr}" unless status.success?
39
+
40
+ YAML.load_stream(stdout).map do |app|
41
+ {
42
+ name: app.dig("metadata", "name"),
43
+ namespace: app.dig("metadata", "namespace"),
44
+ hostname: app.dig("spec", "forProvider", "hostname"),
45
+ ip: app.dig("status", "atProvider", "ipAddress"),
46
+ reverse_dns: app.dig("status", "atProvider", "reverseDNS"),
47
+ fqdn: app.dig("status", "atProvider", "fqdn")
48
+ }
16
49
  end
17
50
  end
51
+
52
+ private
53
+
54
+ def set_organization(organization) # rubocop:disable Naming/AccessorMethodName
55
+ return if organization.strip.empty?
56
+
57
+ _, stderr, status = run_nctl_command("nctl auth set-org #{Shellwords.escape(organization)}")
58
+ return if status.success?
59
+
60
+ raise "Error switching Deploio organization to #{organization}: #{stderr}"
61
+ end
62
+
63
+ def run_nctl_command(cmd)
64
+ stdout, stderr, status = Open3.capture3(cmd)
65
+ raise "Error fetching Deploio app list: #{stderr}" unless status.success?
66
+
67
+ [stdout, stderr, status]
68
+ end
69
+
70
+ def fetch_apps_yaml
71
+ stdout, = run_nctl_command("nctl get apps -A -o yaml")
72
+ stdout
73
+ end
18
74
  end
19
75
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+
5
+ module Renuo::Cli::Services::Hetzner
6
+ class << self
7
+ LIST_TOKENS_CMD = "op item list --tags renuo-cli-debug-hetzner-token --format=json"
8
+ EXTRACT_CREDENTIALS_CMD = "op item get --reveal --field credential,project_id"
9
+ def fetch_vms
10
+ tokens = read_tokens
11
+ tokens.flat_map do |token_and_project|
12
+ token, project_id = token_and_project.split(",")
13
+ client = Client.new(token)
14
+ client.list_servers.map { |s| s.merge(project_id: project_id.to_i) }
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def read_tokens
21
+ stdout, stderr, status = Open3.capture3("#{LIST_TOKENS_CMD} | #{EXTRACT_CREDENTIALS_CMD}")
22
+ raise "Failed to fetch Hetzner tokens: #{stderr}" unless status.success?
23
+
24
+ stdout.split("\n").map(&:strip).reject(&:empty?)
25
+ end
26
+ end
27
+
28
+ class Client
29
+ def initialize(token)
30
+ @token = token
31
+ end
32
+
33
+ BASE_URL = "https://api.hetzner.cloud/v1/"
34
+
35
+ def list_servers
36
+ response = get("servers")
37
+ raise "Error fetching Hetzner servers: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
38
+
39
+ data = JSON.parse(response.body)
40
+ data["servers"].map do |server|
41
+ {
42
+ id: server["id"],
43
+ name: server["name"],
44
+ status: server["status"],
45
+ public_ip: server.dig("public_net", "ipv4", "ip"),
46
+ private_ip: server.dig("private_net", 0, "ip"),
47
+ fqdn: server.dig("public_net", "ipv4", "dns_ptr")
48
+ }
49
+ end
50
+ end
51
+
52
+ def get(resource)
53
+ uri = URI("#{BASE_URL}#{resource}")
54
+ req = Net::HTTP::Get.new(uri)
55
+ req["Authorization"] = "Bearer #{@token}"
56
+
57
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
58
+ http.request(req)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -3,8 +3,8 @@ name: <%= environment %>-deploy
3
3
 
4
4
  agent:
5
5
  machine:
6
- type: f1-standard-4
7
- os_image: ubuntu2204
6
+ type: e1-standard-2
7
+ os_image: ubuntu2404
8
8
 
9
9
  blocks:
10
10
  - name: cd
@@ -17,10 +17,6 @@ blocks:
17
17
  jobs:
18
18
  - name: deploying
19
19
  commands:
20
- - echo 'deb [trusted=yes] https://repo.nine.ch/deb/ /' | sudo tee /etc/apt/sources.list.d/repo.nine.ch.list
21
- - sudo apt-get update -qqo Dir::Etc::sourcelist=/etc/apt/sources.list.d/repo.nine.ch.list
22
- - sudo apt-get install -qq nctl
23
- - nctl auth login --api-client-id=$NCTL_API_CLIENT_ID --api-client-secret=$NCTL_API_CLIENT_SECRET --organization=$NCTL_ORGANIZATION
24
- - nctl update app <%= environment %> -p <%= project_name %> --build-env="RUBY_VERSION=$(cat .ruby-version)" --git-revision=$SEMAPHORE_GIT_SHA --skip-repo-access-check
25
20
  - gem i -q renuo-cli
26
- - renuo check-deploio-status -a <%= environment %> -p <%= project_name %> -g $SEMAPHORE_GIT_SHA
21
+ - renuo ci update-deploio-app <%= environment %> -p renuo-<%= project_name %>
22
+ - renuo ci check-deploio-status <%= environment %> -p renuo-<%= project_name %>
@@ -4,7 +4,7 @@ name: <%= project_name %>
4
4
  agent:
5
5
  machine:
6
6
  type: f1-standard-4
7
- os_image: ubuntu2204
7
+ os_image: ubuntu2404
8
8
 
9
9
  auto_cancel:
10
10
  running:
@@ -3,7 +3,7 @@
3
3
  # :nocov:
4
4
  module Renuo
5
5
  class Cli
6
- VERSION = "4.19.0"
6
+ VERSION = "4.21.0"
7
7
  NAME = "renuo-cli"
8
8
  end
9
9
  end
data/lib/renuo/cli.rb CHANGED
@@ -34,7 +34,7 @@ module Renuo
34
34
  program :description, "Renuo CLI"
35
35
  program :help_paging, false
36
36
 
37
- Dir[File.expand_path("cli/{commands,services}/*.rb", __dir__)].each { |f| require f }
37
+ Dir[File.expand_path("cli/{commands,services}/**/*.rb", __dir__)].each { |f| require f }
38
38
  default_command :help
39
39
  end
40
40
  end
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.19.0
4
+ version: 4.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renuo AG
@@ -65,6 +65,8 @@ files:
65
65
  - bin/renuo
66
66
  - lib/renuo/cli.rb
67
67
  - lib/renuo/cli/commands/check_deploio_status.rb
68
+ - lib/renuo/cli/commands/ci/check_deploio_status.rb
69
+ - lib/renuo/cli/commands/ci/update_deploio_app.rb
68
70
  - lib/renuo/cli/commands/commit_leaderboard_stage.rb
69
71
  - lib/renuo/cli/commands/commit_leaderboard_sync.rb
70
72
  - lib/renuo/cli/commands/configure_semaphore.rb
@@ -94,6 +96,7 @@ files:
94
96
  - lib/renuo/cli/services/cloudfront_config_service.rb
95
97
  - lib/renuo/cli/services/deploio.rb
96
98
  - lib/renuo/cli/services/heroku.rb
99
+ - lib/renuo/cli/services/hetzner.rb
97
100
  - lib/renuo/cli/services/renuo_cli_config.rb
98
101
  - lib/renuo/cli/templates/semaphore/bin/cache_restore.erb
99
102
  - lib/renuo/cli/templates/semaphore/bin/cache_store.erb