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 +4 -4
- data/lib/renuo/cli/commands/check_deploio_status.rb +2 -1
- data/lib/renuo/cli/commands/ci/check_deploio_status.rb +120 -0
- data/lib/renuo/cli/commands/ci/update_deploio_app.rb +44 -0
- data/lib/renuo/cli/commands/create_deploio_app.rb +8 -14
- data/lib/renuo/cli/commands/create_deploio_object_storage.rb +1 -1
- data/lib/renuo/cli/commands/debug.rb +15 -6
- data/lib/renuo/cli/templates/semaphore/notification.yml.erb +2 -2
- data/lib/renuo/cli/templates/semaphore/semaphore-deploy.yml.erb +8 -17
- data/lib/renuo/cli/templates/semaphore/semaphore.yml.erb +2 -2
- data/lib/renuo/cli/version.rb +1 -1
- data/lib/renuo/cli.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96e87891f76ac2c03e7d49276a00ec9f28b6d51530636c9fe18861b517202d56
|
|
4
|
+
data.tar.gz: 58a5b66274436e087f13ba451b252d2fc16a3e96c873e1abc43e6901e47dbc6c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 = "
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
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:
|
|
6
|
-
os_image:
|
|
6
|
+
type: e1-standard-2
|
|
7
|
+
os_image: ubuntu2404
|
|
7
8
|
|
|
8
9
|
blocks:
|
|
9
|
-
- name:
|
|
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:
|
|
18
|
+
- name: deploying
|
|
23
19
|
commands:
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
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:
|
|
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
|
|
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:
|
data/lib/renuo/cli/version.rb
CHANGED
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}
|
|
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.
|
|
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.
|
|
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: []
|