renuo-cli 4.18.1 → 4.20.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: bae3114f37cfe01f2826e83aab108fe1c9b33a29da840214d768e9f18f418a1b
4
- data.tar.gz: 83d9d199de7af9049419c2784c226a87eb1c749727982bdb31a4c237eb65355b
3
+ metadata.gz: 96e87891f76ac2c03e7d49276a00ec9f28b6d51530636c9fe18861b517202d56
4
+ data.tar.gz: 58a5b66274436e087f13ba451b252d2fc16a3e96c873e1abc43e6901e47dbc6c
5
5
  SHA512:
6
- metadata.gz: da97bacdee6165fb3f3702d41229cb00609a09a5fff479213bb3d8d31a21ceeaf9460454bb57385cc7f6d60d8d61a0e427fddb3c3fbe31fb8245bddd96e18a77
7
- data.tar.gz: 2d8a90db015c046e86e4f0f1937d45d02c69b1e9d3d6829deb8128e65114bb5055af3778a4e441f7f75f0b7b0794f1aea7a6a9663a1607b5a7d15bbcf339716a
6
+ metadata.gz: 3f8ead33a76b828827e9ffeb699d9b4005d84bb3eb92bc984fae844c9d11acf3008d60cb980d75ee52707f98c68ad675a13d75d5d34c3bdc95b3ebab3a6fbef9
7
+ data.tar.gz: 682b8f5e3c1ce078db1bca379297a29c174f382d1a7ce882ee0a52db2056f6b54a6b3e330c6e790d0cb926130535b1e8982768886b1847fca5e7bd51b7f0a9ac
@@ -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,20 +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
- OUTPUT
165
- else
166
- say <<~OUTPUT
167
- nctl create postgresdatabase #{environment} \\
168
- --project=#{@project_name_with_org_prefix} \\
169
- --postgres-database-version=#{@postgres_version}
170
- OUTPUT
171
- 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
172
166
  end
173
167
 
174
168
  def say_app_creation(environment)
@@ -107,7 +107,7 @@ class Renuo::Cli::Commands::CreateDeploioObjectStorage
107
107
  --project #{@project_name} \\
108
108
  --env="DEPLOIO_ACCESS_KEY={ACCESS_KEY}" \\
109
109
  --env="DEPLOIO_SECRET_KEY={SECRET_KEY}" \\
110
- --env="DEPLOIO_ENDPOINT=https://#{@location}.objects.nineapis.ch" \\
110
+ --env="DEPLOIO_ENDPOINT=https://#{@location.gsub("nine-", "")}.objects.nineapis.ch" \\
111
111
  --env="DEPLOIO_BUCKET=#{bucket_name}"
112
112
  OUTPUT
113
113
  end
@@ -55,15 +55,16 @@ class Renuo::Cli::Commands::Debug
55
55
 
56
56
  open_cmds = []
57
57
 
58
+ # rubocop:disable Layout/LineLength
58
59
  if should_scan_deploio && Cache.stored_at("deploio_apps")
59
60
  select_deploio_targets(query).each do |app|
60
- bash_cmd = "nctl exec app #{app[:name]} bash --project #{app[:namespace]}"
61
+ bash_cmd = "nctl #{bold("exec")} app #{bold(app[:name])} bash --project #{bold(app[:namespace])}"
61
62
  menu.choice(bash_cmd) { exec bash_cmd.squish }
62
63
 
63
- rails_console_cmd = "nctl exec app #{app[:name]} bundle exec rails console --project #{app[:namespace]}"
64
+ rails_console_cmd = "nctl #{bold("exec")} app #{bold(app[:name])} bundle #{bold("exec")} rails console --project #{bold(app[:namespace])}"
64
65
  menu.choice(rails_console_cmd) { exec rails_console_cmd.squish }
65
66
 
66
- log_cmd = "nctl logs app #{app[:name]} -f --project #{app[:namespace]}"
67
+ log_cmd = "nctl #{bold("logs")} app #{bold(app[:name])} -f --project #{bold(app[:namespace])}"
67
68
  menu.choice(log_cmd) { exec log_cmd.squish }
68
69
 
69
70
  app[:hosts].each do |host|
@@ -71,16 +72,17 @@ class Renuo::Cli::Commands::Debug
71
72
  end
72
73
  end
73
74
  end
75
+ # rubocop:enable Layout/LineLength
74
76
 
75
77
  if should_scan_heroku && Cache.stored_at("heroku_apps")
76
78
  select_heroku_targets(query).each do |app|
77
- exec_cmd = "heroku run bash --app #{app[:name]}"
79
+ exec_cmd = "heroku #{bold("run")} bash --app #{bold(app[:name])}"
78
80
  menu.choice(exec_cmd) { exec exec_cmd.squish }
79
81
 
80
- rails_console_cmd = "heroku run bundle exec rails console --app #{app[:name]}"
82
+ rails_console_cmd = "heroku #{bold("run")} bundle exec rails console --app #{bold(app[:name])}"
81
83
  menu.choice(rails_console_cmd) { exec rails_console_cmd.squish }
82
84
 
83
- log_cmd = "heroku logs -t --app #{app[:name]}"
85
+ log_cmd = "heroku #{bold("logs")} -t --app #{bold(app[:name])}"
84
86
  menu.choice(log_cmd) { exec log_cmd.squish }
85
87
 
86
88
  app[:domains].each do |host|
@@ -111,4 +113,11 @@ class Renuo::Cli::Commands::Debug
111
113
  app[:name].include?(query) || app[:domains].any? { |domain| domain.include?(query) }
112
114
  end
113
115
  end
116
+
117
+ BOLD_START = "\033[1m"
118
+ BOLD_END = "\033[0m"
119
+
120
+ def bold(text)
121
+ "#{BOLD_START}#{text}#{BOLD_END}"
122
+ end
114
123
  end
@@ -12,7 +12,7 @@ spec:
12
12
  notify:
13
13
  slack:
14
14
  endpoint: <%= slack_endpoint %>
15
- channels: ["#project-<%= project_name %>"]
15
+ channels: ["#project-<%= project_name %>-notifications"]
16
16
  - name: build notifications
17
17
  filter:
18
18
  projects: [<%= project_name %>]
@@ -22,4 +22,4 @@ spec:
22
22
  notify:
23
23
  slack:
24
24
  endpoint: <%= slack_endpoint %>
25
- channels: ["#project-<%= project_name %>"]
25
+ channels: ["#project-<%= project_name %>-notifications"]
@@ -1,31 +1,22 @@
1
1
  version: v1.0
2
2
  name: <%= environment %>-deploy
3
+
3
4
  agent:
4
5
  machine:
5
- type: f1-standard-4
6
- os_image: ubuntu2204
6
+ type: e1-standard-2
7
+ os_image: ubuntu2404
7
8
 
8
9
  blocks:
9
- - name: <%= environment %>-deploy
10
+ - name: cd
10
11
  execution_time_limit:
11
12
  minutes: 10
12
13
  task:
13
14
  secrets:
14
15
  - name: <%= project_name %>
15
16
  - name: nctl
16
- env_vars:
17
- - name: DEPLOIO_PROJECT
18
- value: renuo-<%= project_name %>
19
- - name: DEPLOIO_APP_NAME
20
- value: <%= environment %>
21
17
  jobs:
22
- - name: <%= environment %>-deploy
18
+ - name: deploying
23
19
  commands:
24
- - checkout --use-cache
25
- - echo 'deb [trusted=yes] https://repo.nine.ch/deb/ /' | sudo tee /etc/apt/sources.list.d/repo.nine.ch.list
26
- - sudo apt-get -qq update
27
- - sudo apt-get -qq install -y nctl
28
- - nctl auth login --api-client-id=$NCTL_API_CLIENT_ID --api-client-secret=$NCTL_API_CLIENT_SECRET --organization=$NCTL_ORGANIZATION
29
- - nctl update app $DEPLOIO_APP_NAME -p $DEPLOIO_PROJECT --build-env="RUBY_VERSION=$(cat .ruby-version)" --git-revision=$(git rev-parse HEAD) --skip-repo-access-check
30
- - gem i renuo-cli
31
- - renuo check-deploio-status
20
+ - gem i -q renuo-cli
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:
@@ -49,7 +49,7 @@ blocks:
49
49
  value: test
50
50
  prologue:
51
51
  commands:
52
- - sem-service start postgres 16
52
+ - sem-service start postgres 17
53
53
  - cp .env.example .env
54
54
  - bundle exec rails db:create db:schema:load
55
55
  jobs:
@@ -3,7 +3,7 @@
3
3
  # :nocov:
4
4
  module Renuo
5
5
  class Cli
6
- VERSION = "4.18.1"
6
+ VERSION = "4.20.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.18.1
4
+ version: 4.20.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
@@ -122,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
124
  - !ruby/object:Gem::Version
123
125
  version: '0'
124
126
  requirements: []
125
- rubygems_version: 4.0.2
127
+ rubygems_version: 4.0.8
126
128
  specification_version: 4
127
129
  summary: The Renuo CLI automates some common workflows.
128
130
  test_files: []