renuo-cli 4.5.2 → 4.6.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: b77e89a9f507723bab01e37522020c8ac82d34a34275bcf3e43fbfff85dba43e
4
- data.tar.gz: 043d1fe1aef50f6180dd7d808b1e8bafc3e82d5688b858b39b85cec998988f1a
3
+ metadata.gz: 955e4807e9528133c7c3334b6ce70acb637e63a0450ea08be389cfdb5a429f63
4
+ data.tar.gz: 364adfbd23ffbeddbd4ce89166160000a8c6b101089527a7e581afe13b54bce0
5
5
  SHA512:
6
- metadata.gz: 0a25b071168803c2705e9ce7377ad61a8c20c2077d1c6c7feabff0b80cc5afa53615a804907022353b188819042a1005daba19e0edb8d2c278c38f240f6b7150
7
- data.tar.gz: d43a2314a03e768d62cf63c9e3de3e757d79f548d965af097ff178d009ea8b2c7cefe11b4d65070ca434ff0938e41047b8c56947ef4035e024470e197b23774b
6
+ metadata.gz: de3070d906d5610b9acfa4bfdd49ee8f09fd4f59e64f2476d062cd1345acdc5e644f20bd16fe00fa70b42309925ee47a5f44e0aa5b10b83676da80667c326de7
7
+ data.tar.gz: da7edb8258f8fe5d0445594deebf63a0488a6cbb6f483750e6b9118bc1e2e6323082ae06607bfddeb0e345211ed074e18ed6f4f95c3be19bcc7081feb28f0d32
data/bin/setup CHANGED
@@ -5,4 +5,3 @@ IFS=$'\n\t'
5
5
  gem install bundler --conservative
6
6
  bundle install
7
7
  ln -s ../../bin/check .git/hooks/pre-commit
8
-
@@ -4,17 +4,18 @@ require "commander"
4
4
  require_relative "environments"
5
5
 
6
6
  class ConfigureSemaphore
7
- attr_accessor :project_name, :environment
7
+ attr_accessor :project_name, :environment, :slack_endpoint
8
8
 
9
9
  def initialize
10
10
  @project_name = File.basename(Dir.getwd)
11
+ @slack_endpoint = "https://hooks.slack.com/services/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"
11
12
  end
12
13
 
13
14
  # rubocop:disable Metrics/MethodLength
14
15
  def call
15
16
  return unless semaphore_cli_installed?
16
17
 
17
- FileUtils.mkdir_p(%w[.semaphore .semaphore/bin])
18
+ FileUtils.mkdir_p(%w[.semaphore .semaphore/bin tmp])
18
19
 
19
20
  write_or_warn(".semaphore/semaphore.yml", render("templates/semaphore/semaphore.yml.erb"))
20
21
  %w[main develop].each do |environment|
@@ -39,11 +40,9 @@ class ConfigureSemaphore
39
40
  end
40
41
 
41
42
  def create_semaphore_notification
42
- system("sem create notifications #{project_name} " \
43
- "--projects #{project_name} " \
44
- '--branches "main,develop" ' \
45
- "--slack-channels \"#project-#{project_name}\" " \
46
- '--slack-endpoint "https://hooks.slack.com/services/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"')
43
+ File.write("tmp/notification.#{project_name}.yml", render("templates/semaphore/notification.yml.erb"))
44
+ system("sem create -f tmp/notification.#{project_name}.yml")
45
+ FileUtils.rm("tmp/notification.#{project_name}.yml")
47
46
  end
48
47
 
49
48
  def create_semaphore_secrets
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GithubReplace
4
+ def run(args, opts)
5
+ validate_arguments args
6
+ validate_options opts
7
+
8
+ opts.projects.split(",").each do |repo|
9
+ base = clone_and_checkout repo
10
+ find_and_replace args, repo, opts.files.split(",")
11
+ create_pr opts, repo, base
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def validate_arguments(args)
18
+ abort ">> specify a search term and replace term" if args.size != 2
19
+ end
20
+
21
+ def validate_options(opts)
22
+ abort ">> specify one or multiple comma-separated projects" unless opts.projects
23
+ abort ">> specify a branch" unless opts.branch
24
+ abort ">> specify a title" unless opts.title
25
+ abort ">> specify a body" unless opts.body
26
+ abort ">> specify comma-separated files to check" unless opts.files
27
+ end
28
+
29
+ def clone_and_checkout(repo)
30
+ puts `cd #{repo} || git clone --depth=1 git@github.com:renuo/#{repo}.git`
31
+ puts `cd #{repo} && echo git checkout -b "#{opts.branch}"`
32
+ `cd #{repo} && git branch -rl origin/main origin/master`.strip
33
+ end
34
+
35
+ def find_and_replace(args, repo, files)
36
+ files.each do |file|
37
+ file = "#{repo}/#{file}"
38
+ puts "Replacing '#{args[0]}' with '#{args[1]}' in #{file}"
39
+ content = File.read(file).gsub args[0], args[1]
40
+ File.write file, content
41
+ end
42
+ end
43
+
44
+ def create_pr(opts, repo, base)
45
+ puts `cd "#{repo}" \
46
+ && echo git add . \
47
+ && echo git commit -S -m "#{opts.title}" \
48
+ && echo git push --set-upstream origin "#{opts.branch}" \
49
+ && gh pr create -a @me -b "#{opts.body}" -t "#{opts.title}" -B "#{base}" -H "#{opts.branch}"`
50
+ end
51
+ end
@@ -4,11 +4,14 @@ require "yaml"
4
4
  require "fileutils"
5
5
  require "json"
6
6
 
7
- CONFIG_FILE = "config/1password-secrets.yml"
8
-
9
7
  class SecretsFetcher
8
+ CONFIG_FILE = "config/1password-secrets.yml"
9
+
10
10
  def run
11
- system("which op > /dev/null") || abort("op is not installed. Please install it (e.g. brew install 1password-cli).")
11
+ unless ENV["CI"]
12
+ system("which op > /dev/null") || abort("op is not installed. Please install it (e.g. brew install " \
13
+ "1password-cli).")
14
+ end
12
15
 
13
16
  abort("Config file #{CONFIG_FILE} not found.") unless File.exist?(CONFIG_FILE)
14
17
  config = YAML.load_file(CONFIG_FILE).deep_symbolize_keys
@@ -20,7 +23,7 @@ class SecretsFetcher
20
23
 
21
24
  private
22
25
 
23
- def elaborate_item(item) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
26
+ def elaborate_item(item) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
24
27
  private_link = item[:private_link]
25
28
  if private_link.nil?
26
29
  warn "Private link not found in your config file."
@@ -43,6 +46,28 @@ class SecretsFetcher
43
46
  end
44
47
  end
45
48
 
49
+ def extract_item_id(private_link)
50
+ /&i=([^&]+)/.match(private_link)[1]
51
+ end
52
+
53
+ def get_item(item_id)
54
+ output = execute_command(command: "op item get #{item_id} --format json",
55
+ success_message: "",
56
+ error_message: "Error fetching item #{item_id}." \
57
+ "Check `private_link` in your #{CONFIG_FILE} file.")
58
+ JSON.parse(output) if output
59
+ end
60
+
61
+ def execute_command(command:, success_message:, error_message:)
62
+ output = `#{command}`
63
+ if $CHILD_STATUS.success?
64
+ puts success_message unless success_message.empty?
65
+ output
66
+ else
67
+ warn error_message
68
+ end
69
+ end
70
+
46
71
  def process_env_variable(name, item_id, item_json)
47
72
  env_json = item_json["fields"].find { |field| field["label"] == name }
48
73
  if env_json.nil?
@@ -51,7 +76,6 @@ class SecretsFetcher
51
76
  value = env_json["value"]
52
77
  update_or_add_variable(".env", name, /^#{name}=/, "#{name}=#{value}")
53
78
  update_or_add_variable("config/application.yml", name, /^#{name}:.*$/, "#{name}: \"#{value}\"")
54
-
55
79
  end
56
80
  end
57
81
 
@@ -73,28 +97,6 @@ class SecretsFetcher
73
97
  File.write(file_path, updated_contents)
74
98
  end
75
99
 
76
- def get_item(item_id)
77
- output = execute_command(command: "op item get #{item_id} --format json",
78
- success_message: "",
79
- error_message: "Error fetching item #{item_id}." \
80
- "Check `private_link` in your #{CONFIG_FILE} file.")
81
- JSON.parse(output) if output
82
- end
83
-
84
- def execute_command(command:, success_message:, error_message:)
85
- output = `#{command}`
86
- if $CHILD_STATUS.success?
87
- puts success_message unless success_message.empty?
88
- output
89
- else
90
- warn error_message
91
- end
92
- end
93
-
94
- def extract_item_id(private_link)
95
- /&i=([^&]+)/.match(private_link)[1]
96
- end
97
-
98
100
  def process_file(output_folder, filename, item, item_id)
99
101
  FileUtils.mkdir_p(output_folder)
100
102
  output_path = File.join(output_folder, filename)
@@ -0,0 +1,25 @@
1
+ apiVersion: v1alpha
2
+ kind: Notification
3
+ metadata:
4
+ name: <%= project_name %>
5
+ spec:
6
+ rules:
7
+ - name: deployment notifications
8
+ filter:
9
+ projects: [<%= project_name %>]
10
+ branches: [main, develop]
11
+ pipelines: [/.*-deploy.yml/]
12
+ notify:
13
+ slack:
14
+ endpoint: <%= slack_endpoint %>
15
+ channels: ["#project-<%= project_name %>"]
16
+ - name: build notifications
17
+ filter:
18
+ projects: [<%= project_name %>]
19
+ branches: [main, develop]
20
+ pipelines: [semaphore.yml]
21
+ results: [failed]
22
+ notify:
23
+ slack:
24
+ endpoint: <%= slack_endpoint %>
25
+ channels: ["#project-<%= project_name %>"]
@@ -19,4 +19,4 @@ blocks:
19
19
  - checkout --use-cache
20
20
  - heroku git:remote -a $HEROKU_APP_NAME
21
21
  - git push heroku -f $SEMAPHORE_GIT_BRANCH:main
22
- - if heroku run -x rails db:migrate; then heroku dyno:restart; else heroku rollback; exit -1; fi
22
+ - if heroku run -x rails db:migrate; then heroku dyno:restart; else heroku rollback; exit 1; fi
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Renuo
4
4
  module Cli
5
- VERSION = "4.5.2"
5
+ VERSION = "4.6.0"
6
6
  NAME = "renuo-cli"
7
7
  end
8
8
  end
data/lib/renuo/cli.rb CHANGED
@@ -28,6 +28,7 @@ require "renuo/cli/app/renuo_version"
28
28
  require "renuo/cli/app/create_slidev_presentation"
29
29
  require "renuo/cli/app/commit_leaderboard_stage"
30
30
  require "renuo/cli/app/commit_leaderboard_sync"
31
+ require "renuo/cli/app/github_replace"
31
32
  require "renuo/cli/app/secrets_fetcher"
32
33
  require "highline"
33
34
 
@@ -292,6 +293,25 @@ module Renuo
292
293
  end
293
294
  end
294
295
 
296
+ command "github-replace" do |c|
297
+ c.syntax = "renuo github-replace"
298
+ c.summary = "Replaces text in multiple GitHub projects and automatically creates a pull request"
299
+ c.description = "Finds and replaces the contents of specific files in Renuo GitHub projects and " \
300
+ "automatically creates a pull request"
301
+ c.option "--projects <name,name,..>", String, "The github project to clone and edit"
302
+ c.option "--branch <name>", String, "The branch to create"
303
+ c.option "--title <name>", String, "The title of the pull request"
304
+ c.option "--body <text>", String, "The body of the pull request"
305
+ c.option "--files <files,files,..>", String, "The files to check"
306
+ c.example "Update Semaphore Ubuntu version",
307
+ "renuo github-replace ubuntu1804 ubuntu2204 --projects=renuo-cli,renuo-website-v3 " \
308
+ '--branch=feature/1234-update-ubuntu --title="Update os_image version" --body=TICKET-1234 ' \
309
+ "--files=.semaphore/semaphore.yml"
310
+ c.action do |args, opts|
311
+ GithubReplace.new.run(args, opts)
312
+ end
313
+ end
314
+
295
315
  command "fetch-secrets" do |c|
296
316
  c.syntax = "renuo fetch-secrets"
297
317
  c.summary = "Fetches the needed secrets in a project from the renuo secrets store"
data/notification.yml ADDED
@@ -0,0 +1,25 @@
1
+ apiVersion: v1alpha
2
+ kind: Notification
3
+ metadata:
4
+ name: <%= project_name %>
5
+ spec:
6
+ rules:
7
+ - name: deployment notifications
8
+ filter:
9
+ projects: [<%= project_name %>]
10
+ branches: [main, develop]
11
+ pipelines: [/.*-deploy.yml/]
12
+ notify:
13
+ slack:
14
+ endpoint: <%= slack_url %>
15
+ channels: ["#project-<%= project_name %>"]
16
+ - name: build notifications
17
+ filter:
18
+ projects: [<%= project_name %>]
19
+ branches: [main, develop]
20
+ pipelines: [semaphore.yml]
21
+ results: [failed]
22
+ notify:
23
+ slack:
24
+ endpoint: <%= slack_url %>
25
+ channels: ["#project-<%= project_name %>"]
data/renuo-cli.gemspec CHANGED
@@ -40,7 +40,6 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency "rake", "~> 13.0"
41
41
  spec.add_development_dependency "renuocop"
42
42
  spec.add_development_dependency "rspec", "~> 3.5"
43
- spec.add_development_dependency "rubocop", "~> 1.62"
44
43
  spec.add_development_dependency "simplecov"
45
44
  spec.add_development_dependency "simplecov-console"
46
45
  spec.add_development_dependency "vcr", "~> 6.2"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renuo-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.2
4
+ version: 4.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renuo AG
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-09 00:00:00.000000000 Z
11
+ date: 2024-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -234,20 +234,6 @@ dependencies:
234
234
  - - "~>"
235
235
  - !ruby/object:Gem::Version
236
236
  version: '3.5'
237
- - !ruby/object:Gem::Dependency
238
- name: rubocop
239
- requirement: !ruby/object:Gem::Requirement
240
- requirements:
241
- - - "~>"
242
- - !ruby/object:Gem::Version
243
- version: '1.62'
244
- type: :development
245
- prerelease: false
246
- version_requirements: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - "~>"
249
- - !ruby/object:Gem::Version
250
- version: '1.62'
251
237
  - !ruby/object:Gem::Dependency
252
238
  name: simplecov
253
239
  requirement: !ruby/object:Gem::Requirement
@@ -323,7 +309,6 @@ files:
323
309
  - ".semaphore/bin/cache_store"
324
310
  - ".semaphore/main-deploy.yml"
325
311
  - ".semaphore/semaphore.yml"
326
- - ".tool-versions"
327
312
  - Gemfile
328
313
  - LICENSE.txt
329
314
  - README.md
@@ -347,6 +332,7 @@ files:
347
332
  - lib/renuo/cli/app/environments.rb
348
333
  - lib/renuo/cli/app/fetch_emails.rb
349
334
  - lib/renuo/cli/app/generate_password.rb
335
+ - lib/renuo/cli/app/github_replace.rb
350
336
  - lib/renuo/cli/app/heroku_apps.rb
351
337
  - lib/renuo/cli/app/heroku_users.rb
352
338
  - lib/renuo/cli/app/list_large_git_files.rb
@@ -365,6 +351,7 @@ files:
365
351
  - lib/renuo/cli/app/setup_uptimerobot.rb
366
352
  - lib/renuo/cli/app/templates/semaphore/bin/cache_restore.erb
367
353
  - lib/renuo/cli/app/templates/semaphore/bin/cache_store.erb
354
+ - lib/renuo/cli/app/templates/semaphore/notification.yml.erb
368
355
  - lib/renuo/cli/app/templates/semaphore/semaphore-deploy.yml.erb
369
356
  - lib/renuo/cli/app/templates/semaphore/semaphore.yml.erb
370
357
  - lib/renuo/cli/app/templates/slidev/README.md.erb
@@ -379,6 +366,7 @@ files:
379
366
  - lib/renuo/cli/app/upgrade_laptop/upgrade_mac_os.rb
380
367
  - lib/renuo/cli/app/work.rb
381
368
  - lib/renuo/cli/version.rb
369
+ - notification.yml
382
370
  - renuo-cli.gemspec
383
371
  - vcr_cassettes/successful_uptimerobot_calls.yml
384
372
  - vcr_cassettes/unsuccessful_uptimerobot_calls.yml
@@ -387,7 +375,7 @@ licenses:
387
375
  - MIT
388
376
  metadata:
389
377
  rubygems_mfa_required: 'true'
390
- post_install_message:
378
+ post_install_message:
391
379
  rdoc_options: []
392
380
  require_paths:
393
381
  - lib
@@ -402,8 +390,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
402
390
  - !ruby/object:Gem::Version
403
391
  version: '0'
404
392
  requirements: []
405
- rubygems_version: 3.5.16
406
- signing_key:
393
+ rubygems_version: 3.5.18
394
+ signing_key:
407
395
  specification_version: 4
408
396
  summary: The Renuo CLI automates some common workflows.
409
397
  test_files: []
data/.tool-versions DELETED
@@ -1 +0,0 @@
1
- ruby 3.2.3