renuo-cli 4.11.1 → 4.12.1
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/bin/renuo +1 -1
- data/lib/renuo/cli/{app → commands}/check_deploio_status.rb +21 -7
- data/lib/renuo/cli/{app → commands}/commit_leaderboard_stage.rb +16 -1
- data/lib/renuo/cli/{app → commands}/commit_leaderboard_sync.rb +18 -11
- data/lib/renuo/cli/{app → commands}/configure_semaphore.rb +15 -14
- data/lib/renuo/cli/{app → commands}/configure_sentry.rb +10 -4
- data/lib/renuo/cli/{app → commands}/create_aws_project.rb +27 -4
- data/lib/renuo/cli/{app → commands}/create_deploio_app.rb +22 -11
- data/lib/renuo/cli/{app → commands}/create_heroku_app.rb +10 -4
- data/lib/renuo/cli/commands/create_new_logins.rb +41 -0
- data/lib/renuo/cli/{app/github_pull_request_creator.rb → commands/create_pr.rb} +15 -6
- data/lib/renuo/cli/{app → commands}/create_slidev_presentation.rb +9 -10
- data/lib/renuo/cli/{app/name_display.rb → commands/display_name.rb} +20 -10
- data/lib/renuo/cli/{app → commands}/fetch_emails.rb +13 -11
- data/lib/renuo/cli/{app/secrets_fetcher.rb → commands/fetch_secrets.rb} +22 -6
- data/lib/renuo/cli/commands/generate_password.rb +15 -0
- data/lib/renuo/cli/{app → commands}/github_replace.rb +18 -1
- data/lib/renuo/cli/commands/heroku_users.rb +29 -0
- data/lib/renuo/cli/commands/list_large_git_files.rb +19 -0
- data/lib/renuo/cli/{app/release_project.rb → commands/release.rb} +11 -5
- data/lib/renuo/cli/{app → commands}/setup_uptimerobot.rb +11 -4
- data/lib/renuo/cli/{app/upgrade_laptop/upgrade_mac_os.rb → commands/upgrade_laptop.rb} +33 -6
- data/lib/renuo/cli/{app/services → services}/cloudfront_config_service.rb +1 -1
- data/lib/renuo/cli/{app/services → services}/markdown_parser_service.rb +1 -1
- data/lib/renuo/cli/{app/services → services}/renuo_cli_config.rb +1 -3
- data/lib/renuo/cli/{app/templates → templates}/semaphore/semaphore.yml.erb +0 -2
- data/lib/renuo/cli/version.rb +2 -2
- data/lib/renuo/cli.rb +32 -321
- metadata +36 -42
- data/lib/renuo/cli/app/create_new_logins.rb +0 -33
- data/lib/renuo/cli/app/generate_password.rb +0 -9
- data/lib/renuo/cli/app/heroku_apps.rb +0 -13
- data/lib/renuo/cli/app/heroku_users.rb +0 -15
- data/lib/renuo/cli/app/list_large_git_files.rb +0 -9
- data/lib/renuo/cli/app/local_storage.rb +0 -32
- data/lib/renuo/cli/app/package.json +0 -14
- data/lib/renuo/cli/app/secrets_initializer.rb +0 -17
- data/lib/renuo/cli/app/upgrade_laptop/upgrade_laptop_execution.rb +0 -40
- data/lib/renuo/cli/app/upgrade_laptop.rb +0 -22
- /data/lib/renuo/cli/{app → helpers}/command_helper.rb +0 -0
- /data/lib/renuo/cli/{app → helpers}/environments.rb +0 -0
- /data/lib/renuo/cli/{app → helpers}/renuo_version.rb +0 -0
- /data/lib/renuo/cli/{app/templates → templates}/semaphore/bin/cache_restore.erb +0 -0
- /data/lib/renuo/cli/{app/templates → templates}/semaphore/bin/cache_store.erb +0 -0
- /data/lib/renuo/cli/{app/templates → templates}/semaphore/notification.yml.erb +0 -0
- /data/lib/renuo/cli/{app/templates → templates}/semaphore/semaphore-deploy.yml.erb +0 -0
- /data/lib/renuo/cli/{app/templates → templates}/slidev/README.md.erb +0 -0
- /data/lib/renuo/cli/{app/templates → templates}/slidev/package.json.erb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1c4d2cc7480aa3e88836256e9a7abede1acd40d1dcd3c6f303a02dd05dbdd07
|
4
|
+
data.tar.gz: dd0682726f598a8cfcf7e4f39e61886fcfce9ab0cd100692117f104d5ecfda74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bc669c28ab9d53fed2add3b0907650a67245a59616aadd6402c692dfb3126aa687ac0ff1c79b9370ef727f782013348b7f40b8637137ff2bda475bc58d117bb
|
7
|
+
data.tar.gz: f0561c592f523d8a6807b2bc1b4c95270bd786a7845130b2c69beed7b186cd15a6784f377926cbf256266db3db018ae9bccf5c1ba36770148a3556afabc2a378
|
data/bin/renuo
CHANGED
@@ -1,20 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "open3"
|
4
|
-
require "psych"
|
5
|
-
|
6
3
|
# :nocov:
|
7
|
-
class CheckDeploioStatus
|
4
|
+
class Renuo::Cli::Commands::CheckDeploioStatus
|
8
5
|
TIMEOUT_IN_SECONDS = 600
|
9
6
|
INTERVAL_IN_SECONDS = 30
|
10
7
|
|
11
8
|
APP_NAME = ENV.fetch "DEPLOIO_APP_NAME", nil
|
12
9
|
PROJECT = ENV.fetch "DEPLOIO_PROJECT", nil
|
13
10
|
|
14
|
-
|
11
|
+
command "check-deploio-status" do |c|
|
12
|
+
c.syntax = "renuo check-deploio-status"
|
13
|
+
c.summary = "Checks the build and release status of the deployment."
|
14
|
+
c.description = "Checks the build and release status of the deployment."
|
15
|
+
c.option "--git-revision <revision>", String, "The git revision to check"
|
16
|
+
c.action { |_, options| new(options).run }
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(options)
|
15
20
|
abort "missing env DEPLOIO_APP_NAME" if APP_NAME.nil?
|
16
21
|
abort "missing env DEPLOIO_PROJECT" if PROJECT.nil?
|
17
|
-
@revision =
|
22
|
+
@revision = options.git_revision || `git rev-parse HEAD`.strip
|
18
23
|
end
|
19
24
|
|
20
25
|
def run
|
@@ -41,6 +46,14 @@ class CheckDeploioStatus
|
|
41
46
|
Psych.load_stream stdout
|
42
47
|
end
|
43
48
|
|
49
|
+
def fetch_build_logs
|
50
|
+
command = "nctl logs build -a #{APP_NAME} -p #{PROJECT} -l 100 --no-labels"
|
51
|
+
stdout, stderr, status = Open3.capture3 command
|
52
|
+
|
53
|
+
abort "error fetching build logs: #{stderr}" unless status.success?
|
54
|
+
stdout
|
55
|
+
end
|
56
|
+
|
44
57
|
def build
|
45
58
|
@build ||= fetch("builds").find do |build|
|
46
59
|
build.dig("spec", "forProvider", "sourceConfig", "git", "revision") == @revision
|
@@ -65,12 +78,13 @@ class CheckDeploioStatus
|
|
65
78
|
release.dig("status", "atProvider", "releaseStatus")
|
66
79
|
end
|
67
80
|
|
68
|
-
def succeeded?(status, type)
|
81
|
+
def succeeded?(status, type) # rubocop:disable Metrics/MethodLength
|
69
82
|
case status
|
70
83
|
when "available", "success"
|
71
84
|
puts "#{type} succeeded"
|
72
85
|
true
|
73
86
|
when "error", "failed"
|
87
|
+
puts fetch_build_logs
|
74
88
|
abort "#{type} failed"
|
75
89
|
else
|
76
90
|
puts "#{type} status is #{status}, waiting..."
|
@@ -1,8 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class CommitLeaderboardStage
|
3
|
+
class Renuo::Cli::Commands::CommitLeaderboardStage
|
4
4
|
attr_accessor :queue_file_path, :author_username, :auhor_avatar_url, :options
|
5
5
|
|
6
|
+
command "commit-leaderboard-stage" do |c|
|
7
|
+
c.syntax = "renuo commit-leaderboard-stage [username] [avatar-url] [queue-path]"
|
8
|
+
c.summary = "Adds local commits to a local queue for the commit leaderboard"
|
9
|
+
c.option "--verbose", "Prints the latest commit"
|
10
|
+
c.description = <<~DESCRIPTION
|
11
|
+
Add post-commit hook to `git config core.hookspath` with the following contents:
|
12
|
+
|
13
|
+
#!/usr/bin/env sh
|
14
|
+
renuo commit-leaderboard-stage CuddlyBunion341 "https://avatars.githubusercontent.com/u/53896675?v=4" ~/.renuo-commit-leaderboard.json
|
15
|
+
|
16
|
+
# You can get the GitHub avatar url using `gh api user | jq .avatar_url`
|
17
|
+
DESCRIPTION
|
18
|
+
c.action { |args, options| new.run(args, options) }
|
19
|
+
end
|
20
|
+
|
6
21
|
def run(args, options)
|
7
22
|
abort "No author username given." if args[0].nil?
|
8
23
|
abort "No author avatar url given." if args[1].nil?
|
@@ -1,23 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
class Renuo::Cli::Commands::CommitLeaderboardSync
|
4
|
+
class SyncError < StandardError; end
|
4
5
|
|
5
|
-
class SyncError < StandardError; end
|
6
|
-
|
7
|
-
class CommitLeaderboardSync
|
8
6
|
attr_accessor :queue_file_path, :leaderboard_api_url, :api_secret
|
9
7
|
|
8
|
+
command "commit-leaderboard-sync" do |c|
|
9
|
+
c.syntax = "renuo commit-leaderboard-sync [api-secret] [queue-path] [api-url]"
|
10
|
+
c.summary = "Sends commits from the queue to the commit leaderboard"
|
11
|
+
c.description = <<~DESCRIPTION
|
12
|
+
Sends commits from the queue to the commit leaderboard
|
13
|
+
Add pre-push hook to `git config core.hookspath` with the following contents:
|
14
|
+
|
15
|
+
#/usr/bin/env sh
|
16
|
+
renuo commit-leaderboard-sync {SECRET} ~/.renuo-commit-leaderboard.json https://dashboard.renuo.ch/api/v1/commit_leaderboard
|
17
|
+
DESCRIPTION
|
18
|
+
c.option "--verbose", "Prints the configuration, request body and response"
|
19
|
+
c.action { |args, options| new.run(args, options) }
|
20
|
+
end
|
21
|
+
|
10
22
|
def run(args, options)
|
11
23
|
process_args(args)
|
12
24
|
print_configuration if options.verbose
|
13
25
|
|
14
|
-
unless File.exist?(@queue_file_path)
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
unless @leaderboard_api_url.match?(URI::DEFAULT_PARSER.make_regexp)
|
19
|
-
abort(">> Invalid API URL.")
|
20
|
-
end
|
26
|
+
abort(">> Commit queue file does not exist.") unless File.exist?(@queue_file_path)
|
27
|
+
abort(">> Invalid API URL.") unless @leaderboard_api_url.match?(URI::DEFAULT_PARSER.make_regexp)
|
21
28
|
|
22
29
|
commits = JSON.parse(File.read(@queue_file_path))
|
23
30
|
send_commits(commits)
|
@@ -1,37 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative "environments"
|
5
|
-
|
6
|
-
class ConfigureSemaphore
|
3
|
+
class Renuo::Cli::Commands::ConfigureSemaphore
|
7
4
|
attr_accessor :project_name, :environment, :slack_endpoint
|
8
5
|
|
6
|
+
command "configure-semaphore" do |c|
|
7
|
+
c.syntax = "renuo configure-semaphore"
|
8
|
+
c.summary = "Adds standard semaphore configuration files to a project and creates the notifications"
|
9
|
+
c.description = "Run this command with a project, to add the semaphore configuration files " \
|
10
|
+
"and create notifications."
|
11
|
+
c.action { new.run }
|
12
|
+
end
|
13
|
+
|
9
14
|
def initialize
|
10
15
|
@project_name = File.basename(Dir.getwd)
|
11
16
|
@slack_endpoint = "https://hooks.slack.com/services/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"
|
12
17
|
end
|
13
18
|
|
14
|
-
# rubocop:disable Metrics/MethodLength
|
15
|
-
def call
|
19
|
+
def run # rubocop:disable Metrics/MethodLength
|
16
20
|
return unless semaphore_cli_installed?
|
17
21
|
|
18
22
|
FileUtils.mkdir_p(%w[.semaphore .semaphore/bin tmp])
|
19
23
|
|
20
|
-
write_or_warn(".semaphore/semaphore.yml", render("templates/semaphore/semaphore.yml.erb"))
|
24
|
+
write_or_warn(".semaphore/semaphore.yml", render("../templates/semaphore/semaphore.yml.erb"))
|
21
25
|
%w[main develop].each do |environment|
|
22
26
|
@environment = environment
|
23
|
-
write_or_warn(".semaphore/#{environment}-deploy.yml", render("templates/semaphore/semaphore-deploy.yml.erb"))
|
27
|
+
write_or_warn(".semaphore/#{environment}-deploy.yml", render("../templates/semaphore/semaphore-deploy.yml.erb"))
|
24
28
|
end
|
25
|
-
write_or_warn(".semaphore/bin/cache_restore", render("templates/semaphore/bin/cache_restore.erb"))
|
26
|
-
write_or_warn(".semaphore/bin/cache_store", render("templates/semaphore/bin/cache_store.erb"))
|
29
|
+
write_or_warn(".semaphore/bin/cache_restore", render("../templates/semaphore/bin/cache_restore.erb"))
|
30
|
+
write_or_warn(".semaphore/bin/cache_store", render("../templates/semaphore/bin/cache_store.erb"))
|
27
31
|
|
28
32
|
create_semaphore_notification
|
29
33
|
create_semaphore_secrets
|
30
34
|
create_semaphore_deployment_targets
|
31
35
|
end
|
32
|
-
# rubocop:enable Metrics/MethodLength
|
33
|
-
|
34
|
-
private
|
35
36
|
|
36
37
|
def semaphore_cli_installed?
|
37
38
|
semaphore_cli_installed = `sem context | grep '*'`.strip == "* renuo_semaphoreci_com"
|
@@ -40,7 +41,7 @@ class ConfigureSemaphore
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def create_semaphore_notification
|
43
|
-
File.write("tmp/notification.#{project_name}.yml", render("templates/semaphore/notification.yml.erb"))
|
44
|
+
File.write("tmp/notification.#{project_name}.yml", render("../templates/semaphore/notification.yml.erb"))
|
44
45
|
system("sem create -f tmp/notification.#{project_name}.yml")
|
45
46
|
FileUtils.rm("tmp/notification.#{project_name}.yml")
|
46
47
|
end
|
@@ -1,11 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative "environments"
|
5
|
-
|
6
|
-
class ConfigureSentry
|
3
|
+
class Renuo::Cli::Commands::ConfigureSentry
|
7
4
|
ADMIN_EMAIL = "admin@renuo.ch"
|
8
5
|
|
6
|
+
command "configure-sentry" do |c|
|
7
|
+
c.syntax = "renuo configure-sentry [project-name] [SENTRY_DSN]"
|
8
|
+
c.summary = "Generates the script necessary to setup sentry on Heroku."
|
9
|
+
c.description = "Generates the script necessary to setup sentry on Heroku."
|
10
|
+
c.example "renuo configure-sentry myproject https://randomkey@sentry.io/11223344",
|
11
|
+
"generates the command to configure sentry for myproject on Heroku"
|
12
|
+
c.action { |args| new.run(args) }
|
13
|
+
end
|
14
|
+
|
9
15
|
def run(args)
|
10
16
|
project_name = args[0]
|
11
17
|
sentry_dsn = args[1]
|
@@ -1,9 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "renuo/cli/app/services/cloudfront_config_service"
|
4
|
-
|
5
3
|
# :nocov:
|
6
|
-
class CreateAwsProject
|
4
|
+
class Renuo::Cli::Commands::CreateAwsProject
|
5
|
+
command "create-aws-project" do |c|
|
6
|
+
c.syntax = "renuo create-aws-project"
|
7
|
+
c.summary = "Generates necessary commands for our project setup on AWS incl. necessary installations."
|
8
|
+
c.description = <<~DESCRIPTION
|
9
|
+
This creates commands for creating AWS users, buckets an versioning policies and CloudFront.
|
10
|
+
It also guides you to set up the necessary environment.
|
11
|
+
|
12
|
+
You will be asked for:
|
13
|
+
(- installation of aws-cli, if not yet done)
|
14
|
+
(- setting up aws user `renuo-app-setup`, if not yet done)
|
15
|
+
- project name and suffix so that the script can respect our naming conventions
|
16
|
+
- the Redmine project name to tag buckets for AWS billing references
|
17
|
+
- whether you want to setup CloudFront to deliver assets via S3
|
18
|
+
|
19
|
+
The generated commands do the following:
|
20
|
+
- create an IAM user for each environment (main, develop) and add it to the renuo apps group.
|
21
|
+
- create S3 buckets for each user who owns it
|
22
|
+
- tag the buckets
|
23
|
+
- enable versioning for main buckets
|
24
|
+
(- set up a CloudFront distribution for each environment with the default config or plus alias if configured)
|
25
|
+
DESCRIPTION
|
26
|
+
c.example "Setup a project (you will be asked for details)", "renuo create-aws-project"
|
27
|
+
c.action { new.run }
|
28
|
+
end
|
29
|
+
|
7
30
|
def initialize
|
8
31
|
ensure_aws_setup?
|
9
32
|
ensure_aws_profile_existing?
|
@@ -109,7 +132,7 @@ class CreateAwsProject
|
|
109
132
|
|
110
133
|
def aws_cloudfront_setup(profile, bucket, redmine_project)
|
111
134
|
tags = [{ Key: "redmine_project", Value: redmine_project }]
|
112
|
-
cloudfront_config_string = CloudfrontConfigService.new(bucket, tags).to_s
|
135
|
+
cloudfront_config_string = Renuo::Cli::Services::CloudfrontConfigService.new(bucket, tags).to_s
|
113
136
|
|
114
137
|
<<~CLOUDFRONT_COMMANDS
|
115
138
|
aws --profile #{profile} cloudfront create-distribution-with-tags --distribution-config-with-tags '#{cloudfront_config_string}'
|
@@ -1,12 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class CreateDeploioApp # rubocop:disable Metrics/ClassLength
|
3
|
+
class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLength
|
4
4
|
DATABASE_SSH_KEY_FILE = "temporary_database_ssh_key"
|
5
5
|
GITHUB_SSH_KEY_FILE_NAME = "temporary_repository_ssh_key"
|
6
6
|
GITHUB_DEPLOY_KEY_TITLE = "deploio-deploy-key"
|
7
7
|
SSH_ALGORITHM = "Ed25519"
|
8
8
|
|
9
|
-
|
9
|
+
command "create-deploio-app" do |c|
|
10
|
+
c.syntax = "renuo create-deploio-app"
|
11
|
+
c.summary = "Generates the script necessary to setup an application on Deploio."
|
12
|
+
c.description = <<~DESC
|
13
|
+
Generates the script necessary to setup an application on Deploio.
|
14
|
+
This command will:
|
15
|
+
- Prompt for the application name, Git URL, PostgreSQL version, and 1Password vault name.
|
16
|
+
- Validate the provided inputs.
|
17
|
+
- Generate the necessary commands to create a project on Deploio.
|
18
|
+
- Configure repository access by generating SSH keys and adding them to 1Password.
|
19
|
+
- Create the application and database for each specified environment.
|
20
|
+
DESC
|
21
|
+
c.example "renuo create-deploio-app",
|
22
|
+
"Prompts the user for the necessary information and generates the commands " \
|
23
|
+
"to create the project, databases, and apps on Deploio."
|
24
|
+
c.action { new.run }
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
10
28
|
parse_arguments
|
11
29
|
setup_commands
|
12
30
|
setup_environments
|
@@ -16,8 +34,7 @@ class CreateDeploioApp # rubocop:disable Metrics/ClassLength
|
|
16
34
|
|
17
35
|
private
|
18
36
|
|
19
|
-
# rubocop:disable Metrics/MethodLength
|
20
|
-
def parse_arguments
|
37
|
+
def parse_arguments # rubocop:disable Metrics/MethodLength
|
21
38
|
@project_name = ask("Enter the project name (e.g: my_app): ")
|
22
39
|
validate_project_name!
|
23
40
|
|
@@ -38,12 +55,6 @@ class CreateDeploioApp # rubocop:disable Metrics/ClassLength
|
|
38
55
|
validate_vault_name
|
39
56
|
end
|
40
57
|
end
|
41
|
-
# rubocop:enable Metrics/MethodLength
|
42
|
-
|
43
|
-
def ask(prompt)
|
44
|
-
print prompt
|
45
|
-
$stdin.gets.chomp
|
46
|
-
end
|
47
58
|
|
48
59
|
def setup_commands
|
49
60
|
say "# Commands to setup your Deploio application\n".bold
|
@@ -118,7 +129,7 @@ class CreateDeploioApp # rubocop:disable Metrics/ClassLength
|
|
118
129
|
--git-revision="#{environment}" \\
|
119
130
|
--basic-auth=false \\ # Disabling Deploio basic auth as Rails app handles authentication
|
120
131
|
--build-env=SECRET_KEY_BASE='rails secret' \\ # Don't forget to generate the secret key
|
121
|
-
--language=ruby
|
132
|
+
--language=ruby
|
122
133
|
OUTPUT
|
123
134
|
end
|
124
135
|
|
@@ -1,16 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class CreateHerokuApp
|
3
|
+
class Renuo::Cli::Commands::CreateHerokuApp
|
4
4
|
ADMIN_EMAIL = "operations@renuo.ch"
|
5
5
|
|
6
|
+
command "create-heroku-app" do |c|
|
7
|
+
c.syntax = "renuo create-heroku-app <application-name>"
|
8
|
+
c.summary = "Generates the script necessary to setup an application on Heroku."
|
9
|
+
c.description = "Generates the script necessary to setup an application on Heroku."
|
10
|
+
c.example "renuo create-heroku-app hello", "generates the command to create hello on Heroku"
|
11
|
+
c.action { |args| new.run(args) }
|
12
|
+
end
|
13
|
+
|
6
14
|
def run(args)
|
7
15
|
project_name = args[0]
|
8
16
|
abort(">> Project name must be between 2 and 22 characters.") unless project_name&.length&.between?(2, 22)
|
9
17
|
|
10
18
|
say "# Commands to setup your Heroku application\n".colorize :green
|
11
|
-
ENVIRONMENTS.each
|
12
|
-
print_environment_commands(env, project_name)
|
13
|
-
end
|
19
|
+
ENVIRONMENTS.each { |env| print_environment_commands(env, project_name) }
|
14
20
|
print_pipelines_commands(project_name)
|
15
21
|
end
|
16
22
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renuo::Cli::Commands::CreateNewLogins
|
4
|
+
include CommandHelper
|
5
|
+
|
6
|
+
LOGINS = [{ name: "Sentry", sign_up_url: "https://sentry.io/organizations/renuo/members/new/",
|
7
|
+
steps: ["Click on add new Member"] },
|
8
|
+
{ name: "NewRelic", sign_up_url: "https://rpm.newrelic.com/",
|
9
|
+
steps: ["Click on Renuo", "Account Settings > Add user"] }].freeze
|
10
|
+
|
11
|
+
command "create-new-logins" do |c|
|
12
|
+
c.syntax = "renuo create-new-logins"
|
13
|
+
c.summary = "Guides you through the sign up pages for Sentry, NewRelic and Gemnasium"
|
14
|
+
c.description = "Guides you through the sign up pages for Sentry, NewRelic and Gemnasium"
|
15
|
+
c.example "renuo create-new-logins", "creates new logins"
|
16
|
+
c.action { new.run }
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
LOGINS.each do |login|
|
21
|
+
say login[:name].yellow
|
22
|
+
login[:steps].each_with_index do |step, index|
|
23
|
+
say "\t#{index + 1}. #{step}"
|
24
|
+
end
|
25
|
+
open_site login[:sign_up_url]
|
26
|
+
end
|
27
|
+
say "every thing is set up".green
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def open_site(website)
|
33
|
+
open_path(website)
|
34
|
+
wait_to_continue
|
35
|
+
end
|
36
|
+
|
37
|
+
def wait_to_continue
|
38
|
+
system "read -n 1 -s -p 'Press any key to continue...'"
|
39
|
+
say "\n"
|
40
|
+
end
|
41
|
+
end
|
@@ -1,13 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class
|
4
|
-
|
5
|
-
|
3
|
+
class Renuo::Cli::Commands::CreatePr
|
4
|
+
command "create-pr" do |c|
|
5
|
+
c.syntax = "renuo create-pr"
|
6
|
+
c.summary = "Creates a PR for the current branch"
|
7
|
+
c.description = "Creates a PR, assigns it to you and automatically inserts the Redmine ticket number into " \
|
8
|
+
"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 "--draft", "Mark the PR as draft"
|
12
|
+
c.example "Create a PR with the title 'Implement XYZ'",
|
13
|
+
"renuo create-pr --title 'Implement XYZ'"
|
14
|
+
c.action { |_, options| new.run(options) }
|
6
15
|
end
|
7
16
|
|
8
|
-
|
9
|
-
|
10
|
-
def create_pr(opts)
|
17
|
+
def run(opts)
|
11
18
|
command = [
|
12
19
|
"gh pr create",
|
13
20
|
"--assignee @me",
|
@@ -20,6 +27,8 @@ class GithubPullRequestCreator
|
|
20
27
|
puts `#{command}`
|
21
28
|
end
|
22
29
|
|
30
|
+
private
|
31
|
+
|
23
32
|
def pr_title(opts)
|
24
33
|
opts.title ? "--title \"#{opts.title}\"" : "--fill"
|
25
34
|
end
|
@@ -1,25 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class CreateSlidevPresentation
|
3
|
+
class Renuo::Cli::Commands::CreateSlidevPresentation
|
6
4
|
EXAMPLE_SLIDES_URL = "https://raw.githubusercontent.com/renuo/slidev-theme-renuo/main/example.md"
|
7
5
|
SLIDEV_THEME_NAME = "renuo"
|
8
|
-
TEMPLATE_DIRECTORY = "templates/slidev"
|
6
|
+
TEMPLATE_DIRECTORY = "../templates/slidev"
|
9
7
|
|
10
8
|
attr_accessor :presentation_name, :presentation_author
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
command "create-slidev-presentation" do |c|
|
11
|
+
c.syntax = "renuo create-slidev-presentation [presentation-name]"
|
12
|
+
c.summary = "Creates a new Slidev presentation with the Renuo theme"
|
13
|
+
c.description = "Creates a new Slidev presentation with the Renuo theme"
|
14
|
+
c.action { |args| new.run(args) }
|
15
15
|
end
|
16
16
|
|
17
17
|
def run(args)
|
18
|
-
presentation_name = args[0]
|
19
|
-
abort(">> No presentation name given.") unless presentation_name
|
18
|
+
@presentation_name = args[0]
|
19
|
+
abort(">> No presentation name given.") unless @presentation_name
|
20
20
|
|
21
21
|
say "# Commands to setup Slidev project with the Renuo theme:".colorize :green
|
22
|
-
@presentation_name = presentation_name
|
23
22
|
@presentation_author = args[1] || "Renuo AG"
|
24
23
|
print_slidev_project_commands
|
25
24
|
end
|
@@ -1,15 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class NameDisplay
|
3
|
+
class Renuo::Cli::Commands::DisplayName
|
6
4
|
include CommandHelper
|
7
5
|
|
6
|
+
HEROKU_APP_NAME = "-a renuo-dashboard-main"
|
7
|
+
HEROKU_CLI = "heroku run"
|
8
|
+
RENUO_CLI = "rails renuo:welcome"
|
9
|
+
SLIDES = "https://docs.google.com/presentation/d/1mPhQjArZnlUWUa2ik5R9IlGmdCKCwc2_H8Qq-AWgV-A/edit"
|
10
|
+
WELCOME_MESSAGE = "Welcome to Renuo"
|
11
|
+
|
12
|
+
command "display-name" do |c|
|
13
|
+
c.syntax = "renuo display-name [options]"
|
14
|
+
c.summary = "Sets the name of a customer on the Renuo dashboard"
|
15
|
+
c.description = "Sets the name of a customer on the Renuo dashboard"
|
16
|
+
c.example 'Display "Peter Muster" on the dashboard', 'renuo display-name "Peter Muster"'
|
17
|
+
c.example "Remove the current name from the dashboard", "renuo display-name --delete"
|
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"
|
22
|
+
c.action { |args, options| new.run(args, options) }
|
23
|
+
end
|
24
|
+
|
8
25
|
def run(args, options)
|
9
26
|
return open_path(SLIDES) if options.monitor
|
10
27
|
return display_name(nil) if options.delete
|
11
28
|
return say("empty argument") if args.empty?
|
12
|
-
|
13
29
|
return run_heroku_command(args.join(" ")) if options.override
|
14
30
|
|
15
31
|
display_name(args.join(" "))
|
@@ -17,12 +33,6 @@ class NameDisplay
|
|
17
33
|
|
18
34
|
private
|
19
35
|
|
20
|
-
HEROKU_APP_NAME = "-a renuo-dashboard-main"
|
21
|
-
HEROKU_CLI = "heroku run"
|
22
|
-
RENUO_CLI = "rails renuo:welcome"
|
23
|
-
SLIDES = "https://docs.google.com/presentation/d/1mPhQjArZnlUWUa2ik5R9IlGmdCKCwc2_H8Qq-AWgV-A/edit"
|
24
|
-
WELCOME_MESSAGE = "Welcome to Renuo"
|
25
|
-
|
26
36
|
def display_name(name)
|
27
37
|
text_message = [WELCOME_MESSAGE, name, "🥳🔥"].compact.join(" ")
|
28
38
|
run_heroku_command(text_message)
|
@@ -1,24 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
class Renuo::Cli::Commands::FetchEmails
|
4
|
+
EMAIL_LIST_URL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vSqPiedBeGk0N75cxZApEohj5LrIWlHWUxTjfhkmK9aOsUltcqCn24sD1haIasUjVfd8UT8VdUKUc4h/pub?gid=703649940&single=true&output=csv"
|
5
|
+
|
6
|
+
command "fetch-emails" do |c|
|
7
|
+
c.syntax = "renuo fetch-emails"
|
8
|
+
c.summary = "Retrieves all renuo employees email addresses"
|
9
|
+
c.description = "Retrieves all renuo employees email addresses. One per line."
|
10
|
+
c.action { new.run }
|
11
|
+
end
|
5
12
|
|
6
|
-
|
7
|
-
|
8
|
-
|
13
|
+
def run
|
14
|
+
say "# Here is a complete list of Renuo email addresses".colorize :green
|
15
|
+
say fetch_emails.join("\n")
|
9
16
|
end
|
10
17
|
|
11
18
|
def fetch_emails
|
12
|
-
response = get_emails(
|
19
|
+
response = get_emails(EMAIL_LIST_URL)
|
13
20
|
response = handle_redirection(response) if response.is_a?(Net::HTTPRedirection)
|
14
21
|
format_response(response)
|
15
22
|
end
|
16
23
|
|
17
|
-
def run(_args)
|
18
|
-
say "# Here is a complete list of Renuo email addresses".colorize :green
|
19
|
-
say fetch_emails.join("\n")
|
20
|
-
end
|
21
|
-
|
22
24
|
private
|
23
25
|
|
24
26
|
def get_emails(url)
|
@@ -1,12 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "fileutils"
|
5
|
-
require "json"
|
6
|
-
|
7
|
-
class SecretsFetcher
|
3
|
+
class Renuo::Cli::Commands::FetchSecrets # rubocop:disable Metrics/ClassLength
|
8
4
|
CONFIG_FILE = "config/1password-secrets.yml"
|
9
5
|
|
6
|
+
command "fetch-secrets" do |c|
|
7
|
+
c.syntax = "renuo fetch-secrets"
|
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"
|
10
|
+
c.description = <<~DESCRIPTION
|
11
|
+
Run the command within a project folder to fetch the secrets from the renuo secrets store.
|
12
|
+
The bin/setup of the project might run this command for you.
|
13
|
+
DESCRIPTION
|
14
|
+
c.action { |_, options| options.init ? new.init(options.init) : new.run }
|
15
|
+
end
|
16
|
+
|
17
|
+
def init(private_vault_link)
|
18
|
+
abort("Config file #{CONFIG_FILE} already exists.") if File.exist?(CONFIG_FILE)
|
19
|
+
File.write(CONFIG_FILE, generate_config_file(private_vault_link))
|
20
|
+
end
|
21
|
+
|
10
22
|
def run
|
11
23
|
unless ENV["CI"]
|
12
24
|
system("which op > /dev/null") || abort("op is not installed. Please install it (e.g. brew install " \
|
@@ -14,7 +26,7 @@ class SecretsFetcher
|
|
14
26
|
end
|
15
27
|
|
16
28
|
abort("Config file #{CONFIG_FILE} not found.") unless File.exist?(CONFIG_FILE)
|
17
|
-
config =
|
29
|
+
config = Psych.load_file(CONFIG_FILE).deep_symbolize_keys
|
18
30
|
|
19
31
|
config[:items].each do |item|
|
20
32
|
elaborate_item(item)
|
@@ -23,6 +35,10 @@ class SecretsFetcher
|
|
23
35
|
|
24
36
|
private
|
25
37
|
|
38
|
+
def generate_config_file(private_vault_link)
|
39
|
+
{ "items" => [{ "private_link" => private_vault_link, "files" => [], "env_variables" => [] }] }.to_yaml
|
40
|
+
end
|
41
|
+
|
26
42
|
def elaborate_item(item) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
27
43
|
private_link = item[:private_link]
|
28
44
|
if private_link.nil?
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renuo::Cli::Commands::GeneratePassword
|
4
|
+
command "generate-password" do |c|
|
5
|
+
c.syntax = "renuo generate-password"
|
6
|
+
c.summary = "Generates a phrase of random 0-9a-zA-Z characters. Choose a substring of it as a new password."
|
7
|
+
c.description = "Generates a phrase of random 0-9a-zA-Z characters. Choose a substring of it as a new password."
|
8
|
+
c.example "renuo generate-password", "generates a random password"
|
9
|
+
c.action { new.run }
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
say SecureRandom.base64(200).gsub(%r{[+/=]}, "")[0...100]
|
14
|
+
end
|
15
|
+
end
|
@@ -1,6 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class GithubReplace
|
3
|
+
class Renuo::Cli::Commands::GithubReplace
|
4
|
+
command "github-replace" do |c|
|
5
|
+
c.syntax = "renuo github-replace"
|
6
|
+
c.summary = "Replaces text in multiple GitHub projects and automatically creates a pull request"
|
7
|
+
c.description = "Finds and replaces the contents of specific files in Renuo GitHub projects and " \
|
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"
|
12
|
+
c.option "--body <text>", String, "The body of the pull request"
|
13
|
+
c.option "--files <files,files,..>", String, "The files to check"
|
14
|
+
c.example "Update Semaphore Ubuntu version",
|
15
|
+
"renuo github-replace ubuntu1804 ubuntu2204 --projects=renuo-cli,renuo-website-v3 " \
|
16
|
+
'--branch=feature/1234-update-ubuntu --title="Update os_image version" --body=TICKET-1234 ' \
|
17
|
+
"--files=.semaphore/semaphore.yml"
|
18
|
+
c.action { |args, options| new.run(args, options) }
|
19
|
+
end
|
20
|
+
|
4
21
|
def run(args, opts)
|
5
22
|
validate_arguments args
|
6
23
|
validate_options opts
|