renuo-cli 1.7.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +3 -3
  4. data/.ruby-version +1 -1
  5. data/.semaphore/bin/cache_restore +16 -0
  6. data/.semaphore/bin/cache_store +16 -0
  7. data/.semaphore/master-deploy.yml +0 -1
  8. data/.semaphore/semaphore.yml +7 -7
  9. data/lib/renuo/cli/app/configure_semaphore.rb +12 -5
  10. data/lib/renuo/cli/app/create_aws_project.rb +6 -4
  11. data/lib/renuo/cli/app/create_heroku_app.rb +4 -7
  12. data/lib/renuo/cli/app/environments.rb +2 -1
  13. data/lib/renuo/cli/app/fetch_emails.rb +23 -5
  14. data/lib/renuo/cli/app/generate_password.rb +1 -1
  15. data/lib/renuo/cli/app/heroku_users.rb +1 -1
  16. data/lib/renuo/cli/app/release_project.rb +29 -19
  17. data/lib/renuo/cli/app/release_xing.rb +1 -1
  18. data/lib/renuo/cli/app/renuo_version.rb +52 -0
  19. data/lib/renuo/cli/app/services/renuo_cli_config.rb +1 -0
  20. data/lib/renuo/cli/app/setup_uptimerobot.rb +1 -0
  21. data/lib/renuo/cli/app/templates/semaphore/bin/cache_restore.erb +31 -0
  22. data/lib/renuo/cli/app/templates/semaphore/bin/cache_store.erb +31 -0
  23. data/lib/renuo/cli/app/templates/{semaphore-deploy.yml.erb → semaphore/semaphore-deploy.yml.erb} +3 -1
  24. data/lib/renuo/cli/app/templates/semaphore/semaphore.yml.erb +107 -0
  25. data/lib/renuo/cli/app/toggl_redmine_comparator.rb +2 -1
  26. data/lib/renuo/cli/app/upgrade_laptop/upgrade_mac_os.rb +2 -2
  27. data/lib/renuo/cli/app/work.rb +1 -1
  28. data/lib/renuo/cli/version.rb +1 -1
  29. data/lib/renuo/cli.rb +6 -6
  30. data/renuo-cli.gemspec +4 -1
  31. metadata +29 -12
  32. data/CODE_OF_CONDUCT.md +0 -13
  33. data/lib/renuo/cli/app/templates/semaphore.yml.erb +0 -70
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e4c4aa2edb020c6ac6c4c454d5e6f7818547d747
4
- data.tar.gz: 5b7d8a34f2e3319a7e51e467eabaafb9cf39fbd8
2
+ SHA256:
3
+ metadata.gz: ea4e597c6888d4eb5472df3d1fdc496afe3ff1ab16ce2ce9f20602da6c2ccc40
4
+ data.tar.gz: 3fef697d445ab64c2d62c4adf62d5c4718e56c2243b64237bc3f9cf8e1255b06
5
5
  SHA512:
6
- metadata.gz: 8ead9a79d1de88514dba17d43e95e1adcc2e28f59959cd04314966e47770d8a105b6b8b32db6e0dfcd0c79c763ea17a12f0a9a29c874c4a4ccde355f8859c4b3
7
- data.tar.gz: b1634389fe6c29a4c7e21e8ffa928cc29980fc5fb5eb53bf5b9190b70cf741b2ba95871d3fef75c4c5e839a606131b11fd6b2fdec9c5efaaf4876c917c60ad4c
6
+ metadata.gz: 8f57de9f499fd37447d94675a063e3e2f6eb76d94b7d47c182048036faa92d91b89877beb579683717990f872caba2c4adfddcfc0adc23b79e5e5ff9351584c9
7
+ data.tar.gz: 28f034598160faef73f8ae55c26f7c3dae0a772e0500498881e56a3ce4d83e32cefecbdb63a18c3205e27f860c42ad79ae248650f071e38b1db98c41d14d9c03
data/.gitignore CHANGED
@@ -101,4 +101,3 @@ build/
101
101
  /pkg/
102
102
  /spec/reports/
103
103
  /tmp/
104
- .rubocop-https---raw-githubusercontent-com-renuo-applications-setup-guide-master-templates--rubocop-yml
data/.rubocop.yml CHANGED
@@ -11,6 +11,9 @@ AllCops:
11
11
  - 'lib/renuo/cli/app/create_heroku_app'
12
12
  - 'vendor/**/*'
13
13
 
14
+ Layout/LineLength:
15
+ Max: 120
16
+
14
17
  Naming/FileName:
15
18
  Exclude:
16
19
  - 'Gemfile'
@@ -25,9 +28,6 @@ Metrics/BlockLength:
25
28
  Metrics/ClassLength:
26
29
  Max: 160
27
30
 
28
- Metrics/LineLength:
29
- Max: 120
30
-
31
31
  Style/Documentation:
32
32
  Enabled: false
33
33
 
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.1
1
+ 2.7.2
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+
3
+ for cache_group in "$@"
4
+ do
5
+ case $cache_group in
6
+
7
+ ruby)
8
+ cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-develop,gems-master
9
+ ;;
10
+
11
+ *)
12
+ echo "Invalid argument: Cache group $cache_group not found."
13
+ exit 1
14
+ ;;
15
+ esac
16
+ done
@@ -0,0 +1,16 @@
1
+ #!/bin/sh
2
+
3
+ for cache_group in "$@"
4
+ do
5
+ case $cache_group in
6
+
7
+ ruby)
8
+ cache store gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock) vendor/bundle
9
+ ;;
10
+
11
+ *)
12
+ echo "Invalid argument: Cache group $cache_group not found."
13
+ exit 1
14
+ ;;
15
+ esac
16
+ done
@@ -15,5 +15,4 @@ blocks:
15
15
  commands:
16
16
  - checkout --use-cache
17
17
  - gem build renuo-cli
18
- - chmod 0600 ~/.gem/credentials
19
18
  - gem push renuo-cli-*.gem
@@ -7,24 +7,24 @@ agent:
7
7
  auto_cancel:
8
8
  running:
9
9
  when: "true"
10
+ fail_fast:
11
+ cancel:
12
+ when: "branch != 'master'"
10
13
 
11
14
  blocks:
12
15
  - name: tests
13
16
  execution_time_limit:
14
- minutes: 10
17
+ minutes: 5
18
+ dependencies: []
15
19
  task:
16
20
  secrets:
17
21
  - name: renuo-cli
18
- env_vars:
19
- - name: RAILS_ENV
20
- value: test
21
22
  prologue:
22
23
  commands:
23
24
  - checkout --use-cache
24
- - cache restore
25
- - gem update bundler
25
+ - source .semaphore/bin/cache_restore ruby
26
26
  - bundle install -j 4 --path vendor/bundle
27
- - cache store
27
+ - source .semaphore/bin/cache_store ruby
28
28
  jobs:
29
29
  - name: tests
30
30
  commands:
@@ -8,17 +8,24 @@ class ConfigureSemaphore
8
8
  @project_name = File.basename(Dir.getwd)
9
9
  end
10
10
 
11
+ # rubocop:disable Metrics/MethodLength
11
12
  def call
12
13
  return unless semaphore_cli_installed?
13
- FileUtils.mkdir_p('.semaphore')
14
- write_or_warn('.semaphore/semaphore.yml', render('templates/semaphore.yml.erb'))
15
- %w[master develop testing].each do |environment|
14
+
15
+ FileUtils.mkdir_p(%w[.semaphore .semaphore/bin])
16
+
17
+ write_or_warn('.semaphore/semaphore.yml', render('templates/semaphore/semaphore.yml.erb'))
18
+ %w[main develop testing].each do |environment|
16
19
  @environment = environment
17
- write_or_warn(".semaphore/#{environment}-deploy.yml", render('templates/semaphore-deploy.yml.erb'))
20
+ write_or_warn(".semaphore/#{environment}-deploy.yml", render('templates/semaphore/semaphore-deploy.yml.erb'))
18
21
  end
22
+ write_or_warn('.semaphore/bin/cache_restore', render('templates/semaphore/bin/cache_restore.erb'))
23
+ write_or_warn('.semaphore/bin/cache_store', render('templates/semaphore/bin/cache_store.erb'))
24
+
19
25
  create_semaphore_notification
20
26
  create_semaphore_secrets
21
27
  end
28
+ # rubocop:enable Metrics/MethodLength
22
29
 
23
30
  private
24
31
 
@@ -31,7 +38,7 @@ class ConfigureSemaphore
31
38
  def create_semaphore_notification
32
39
  system("sem create notifications #{project_name} "\
33
40
  "--projects #{project_name} "\
34
- '--branches "master,develop,testing" '\
41
+ '--branches "main,develop,testing" '\
35
42
  "--slack-channels \"#project-#{project_name}\" "\
36
43
  '--slack-endpoint "https://hooks.slack.com/services/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"')
37
44
  end
@@ -8,7 +8,7 @@ class CreateAwsProject
8
8
  end
9
9
 
10
10
  def run
11
- %w[master develop testing].each do |branch|
11
+ %w[main develop testing].each do |branch|
12
12
  print_setup_commands branch
13
13
  end
14
14
  end
@@ -27,7 +27,7 @@ class CreateAwsProject
27
27
  end
28
28
 
29
29
  def collect_s3_information
30
- @project_purpose = ask('Suffix describing purpose (eg: assets): ') { |q| q.default = 'none' }
30
+ @project_purpose = ask('Suffix describing a non-default purpose (eg: "archives"): ') { |q| q.default = 'none' }
31
31
  @project_purpose = nil if @project_purpose.empty? || @project_purpose == 'none'
32
32
  @redmine_project = ask('Redmine project name for billing (eg: internal): ') do |q|
33
33
  q.default = @project_name
@@ -42,10 +42,11 @@ class CreateAwsProject
42
42
  @setup_cloudfront = agree('Would you like to setup also AWS CloudFront? '\
43
43
  '(Default: yes, if you want to deliver assets/images from S3)')
44
44
  return unless @setup_cloudfront
45
+
45
46
  @cloudfront_alias = {}
46
47
  return unless agree('Would you like to use an alias to call your assets/images on S3? (Default: no)')
47
48
 
48
- %i[master develop testing].each do |branch|
49
+ %i[main develop testing].each do |branch|
49
50
  cloudfront_alias_for branch
50
51
  end
51
52
  end
@@ -77,13 +78,14 @@ class CreateAwsProject
77
78
  $terminal.wrap_at = nil if $terminal
78
79
  puts aws_iam_setup(@aws_profile, aws_user(branch), @aws_app_group)
79
80
  puts aws_s3_setup(@aws_profile, aws_user(branch), @aws_region, @redmine_project)
80
- puts aws_s3_versioning_setup(@aws_profile, aws_user(branch)) if branch == 'master'
81
+ puts aws_s3_versioning_setup(@aws_profile, aws_user(branch)) if branch == 'main'
81
82
  cloudfront_setup(aws_user(branch), branch)
82
83
  $terminal.wrap_at = :auto if $terminal
83
84
  end
84
85
 
85
86
  def cloudfront_setup(bucket, branch)
86
87
  return unless @setup_cloudfront
88
+
87
89
  puts aws_cloudfront_setup(@aws_profile, bucket, branch, @redmine_project)
88
90
  if @cloudfront_alias[branch.to_sym]
89
91
  say "\n# Warning: Don't forget to set up `#{cloudfront_alias(branch)}` on the DNS "\
@@ -1,15 +1,11 @@
1
- require 'commander'
2
- require_relative './environments'
3
- require_relative './fetch_emails'
4
-
5
1
  class CreateHerokuApp
6
2
  ADMIN_EMAIL = 'admin@renuo.ch'.freeze
7
3
 
8
4
  def initialize; end
9
5
 
10
- def run(args)
6
+ def run(*args)
11
7
  project_name = args[0]
12
- abort('>> No project name given.') unless project_name
8
+ abort('>> Project name must be between 2 and 22 characters.') unless project_name&.length&.between?(2, 22)
13
9
  emails = FetchEmails.new.fetch_emails
14
10
 
15
11
  say "# Commands to setup your Heroku application\n".colorize :green
@@ -25,6 +21,7 @@ class CreateHerokuApp
25
21
  heroku_name = "#{project_name}-#{env}"
26
22
  say "heroku apps:create --region eu #{heroku_name}"
27
23
  say "heroku domains:add #{heroku_name}.renuoapp.ch --app #{heroku_name}"
24
+ say "heroku domains:add #{project_name}-#{MASTER}.renuoapp.ch --app #{heroku_name}" if env == MAIN
28
25
  say "heroku addons:create heroku-postgresql --app #{heroku_name}"
29
26
  say "heroku addons:create papertrail --app #{heroku_name}"
30
27
  say "heroku labs:enable runtime-dyno-metadata --app #{heroku_name}"
@@ -33,7 +30,7 @@ class CreateHerokuApp
33
30
  end
34
31
 
35
32
  def print_pipelines_commands(project_name)
36
- say "heroku pipelines:create #{project_name} --app #{project_name}-#{MASTER} -s production"
33
+ say "heroku pipelines:create #{project_name} --app #{project_name}-#{MAIN} -s production"
37
34
  say "heroku pipelines:add #{project_name} --app #{project_name}-#{DEVELOP} -s staging"
38
35
  say "heroku pipelines:add #{project_name} --app #{project_name}-#{TESTING} -s staging"
39
36
  say "\n"
@@ -1,4 +1,5 @@
1
+ MAIN = 'main'.freeze
1
2
  MASTER = 'master'.freeze
2
3
  DEVELOP = 'develop'.freeze
3
4
  TESTING = 'testing'.freeze
4
- ENVIRONMENTS = [MASTER, DEVELOP, TESTING].freeze
5
+ ENVIRONMENTS = [MAIN, DEVELOP, TESTING].freeze
@@ -2,16 +2,34 @@ require 'net/http'
2
2
  require 'uri'
3
3
 
4
4
  class FetchEmails
5
- def initialize; end
5
+ def initialize
6
+ @email_list_url = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vSqPiedBeGk0N75cxZApEohj5LrIWlHWUxTjfhkmK9aOsUltcqCn24sD1haIasUjVfd8UT8VdUKUc4h/pub?gid=703649940&single=true&output=csv'
7
+ end
6
8
 
7
9
  def fetch_emails
8
- uri = URI.parse('https://docs.google.com/spreadsheets/d/1rJFJQCgpz6GajMlGf0anKwVl5AY6TrYjMnJ4W-_0MK4/pub?gid=703649940&single=true&output=csv')
9
- response = Net::HTTP.get_response(uri)
10
- response.body.gsub(/\r\n/, "\n").split("\n").reject { |add| add == 'n/a' }
10
+ response = get_emails(@email_list_url)
11
+ response = handle_redirection(response) if response.is_a?(Net::HTTPRedirection)
12
+ format_response(response)
11
13
  end
12
14
 
13
15
  def run(_args)
14
- say '# Here is a complete lit of Renuo email addresses'.colorize :green
16
+ say '# Here is a complete list of Renuo email addresses'.colorize :green
15
17
  say fetch_emails.join("\n")
16
18
  end
19
+
20
+ private
21
+
22
+ def get_emails(url)
23
+ uri = URI.parse(url)
24
+ Net::HTTP.get_response(uri)
25
+ end
26
+
27
+ def handle_redirection(response)
28
+ location = response['location']
29
+ get_emails(location)
30
+ end
31
+
32
+ def format_response(response)
33
+ response.body.gsub(/\r\n/, "\n").split("\n").reject { |add| add == 'n/a' }
34
+ end
17
35
  end
@@ -2,6 +2,6 @@ require 'securerandom'
2
2
 
3
3
  class GeneratePassword
4
4
  def run
5
- say SecureRandom.base64(200).gsub(%r{[\+\/=]}, '')[0...100]
5
+ say SecureRandom.base64(200).gsub(%r{[+/=]}, '')[0...100]
6
6
  end
7
7
  end
@@ -1,4 +1,4 @@
1
- require_relative './heroku_apps.rb'
1
+ require_relative './heroku_apps'
2
2
 
3
3
  class HerokuUsers
4
4
  def initialize; end
@@ -1,6 +1,6 @@
1
1
  class ReleaseProject
2
2
  UPDATE_TYPES = %w[major minor patch custom].freeze
3
- TMP_FOLDER_NAME = ('_RENUO_RELEASE_TEMP_' + rand(100_000_000).to_s).freeze
3
+ TMP_FOLDER_NAME = "_RENUO_RELEASE_TEMP_#{rand(100_000_000)}".freeze
4
4
  MOVE_TO_TMP_FOLDER = "mkdir -p #{TMP_FOLDER_NAME} && cd #{TMP_FOLDER_NAME}".freeze
5
5
 
6
6
  def run(args)
@@ -8,8 +8,8 @@ class ReleaseProject
8
8
  validate_project_name
9
9
  validate_update_type
10
10
  validate_custom_version_format
11
- compare_develop_master
12
11
  checkout_project
12
+ compare_develop_main
13
13
  @version ||= calculate_version
14
14
  release
15
15
  ensure
@@ -44,34 +44,38 @@ class ReleaseProject
44
44
  end
45
45
 
46
46
  def validate_custom_version_format
47
- return if @version.nil?
48
- abort('>> Invalid Version Number. Use format X.Y.Z for your version.') unless @version =~ /\d+\.\d+\.\d+/
47
+ return if @version.nil? || @version =~ RenuoVersion::SEMVER_SCHEMA
48
+
49
+ abort('>> Invalid Version Number. Use format X.Y.Z for your version.')
49
50
  end
50
51
 
51
- def compare_develop_master
52
+ def compare_develop_main
52
53
  puts 'Please double-check what is going to be deployed.'
53
54
  open_comparison_page
54
55
  abort unless agree('Are you fine with those changes?')
55
56
  end
56
57
 
57
58
  def open_comparison_page
58
- system "open https://github.com/#{@project_name}/compare/master...develop"
59
+ system_command = case RbConfig::CONFIG['host_os']
60
+ when /mswin|mingw|cygwin/
61
+ 'start'
62
+ when /darwin/
63
+ 'open'
64
+ when /linux|bsd/
65
+ 'xdg-open'
66
+ end
67
+ system "#{system_command} https://github.com/#{@project_name}/compare/#{main_branch}...develop"
59
68
  end
60
69
 
61
70
  def checkout_project
62
- unless system("#{MOVE_TO_TMP_FOLDER} && hub clone #{@project_name} && " \
63
- "cd #{folder_name} && git checkout master && git pull origin master &&" \
64
- 'git checkout develop && git pull origin develop && git flow init -d')
65
- abort('>> Project not found on Github.')
66
- end
71
+ abort('>> Project not found on Github.') unless system("#{MOVE_TO_TMP_FOLDER} && gh repo clone #{@project_name}")
72
+
73
+ system(cmd_in_folder("git checkout #{main_branch} && git pull origin #{main_branch} &&" \
74
+ 'git checkout develop && git pull origin develop && git flow init -d'))
67
75
  end
68
76
 
69
77
  def calculate_version
70
- current_version_parts = current_version.split('.').map(&:to_i)
71
- type_index = UPDATE_TYPES.index(@update_type)
72
- current_version_parts[type_index + 1..-1] = [0] * (2 - type_index)
73
- current_version_parts[type_index] += 1
74
- current_version_parts.join('.')
78
+ RenuoVersion.create(current_version).bump(@update_type).to_s
75
79
  end
76
80
 
77
81
  def release
@@ -81,7 +85,7 @@ class ReleaseProject
81
85
  if finish_release_branch
82
86
  puts ">> Project successfully released with version #{@version}."
83
87
  else
84
- abort('>> Unable to finish release and push to master. Cancelling release.')
88
+ abort(">> Unable to finish release and push to #{main_branch}. Cancelling release.")
85
89
  end
86
90
  end
87
91
 
@@ -92,7 +96,7 @@ class ReleaseProject
92
96
  '0.0.0'
93
97
  else
94
98
  sorted_tags = `#{cmd_in_folder('git tag --sort=taggerdate')}`.split("\n").reverse
95
- sorted_tags.find { |tag| tag =~ /\d+\.\d+\.\d+/ }.strip
99
+ sorted_tags.find { |tag| tag =~ RenuoVersion::SEMVER_SCHEMA }.strip
96
100
  end
97
101
  end
98
102
 
@@ -100,6 +104,7 @@ class ReleaseProject
100
104
  version_bumped = find_and_replace_version
101
105
 
102
106
  return unless version_bumped
107
+
103
108
  system(cmd_in_folder("git add . && git commit -m \"bump version\" && git push -u origin release/#{@version}"))
104
109
  end
105
110
 
@@ -137,7 +142,7 @@ class ReleaseProject
137
142
  def finish_release_branch
138
143
  system(cmd_in_folder("GIT_MERGE_AUTOEDIT=no git flow release finish -m #{@version} #{@version} && " \
139
144
  'git checkout develop && git push origin develop && ' \
140
- 'git checkout master && git push origin master --tags'))
145
+ "git checkout #{main_branch} && git push origin #{main_branch} --tags"))
141
146
  end
142
147
 
143
148
  def ask_for_final_confirmation
@@ -147,6 +152,7 @@ class ReleaseProject
147
152
  end
148
153
 
149
154
  return unless Time.now.friday? && Time.now.hour >= 16
155
+
150
156
  unless agree('>> Are you sure you want to deploy on late Friday afternoon? ' \
151
157
  'Did you think about your family...waiting for you at home?')
152
158
  abort('>> Very good. Go home now.')
@@ -168,4 +174,8 @@ class ReleaseProject
168
174
  def cleanup
169
175
  system("rm -rf #{TMP_FOLDER_NAME}")
170
176
  end
177
+
178
+ def main_branch
179
+ @main_branch ||= system(cmd_in_folder('git checkout main && git show-ref refs/heads/main')) ? 'main' : 'master'
180
+ end
171
181
  end
@@ -1,5 +1,5 @@
1
1
  class ReleaseXing
2
- TMP_FOLDER_NAME = ('_RENUO_RELEASE_TEMP_' + rand(100_000_000).to_s).freeze
2
+ TMP_FOLDER_NAME = "_RENUO_RELEASE_TEMP_#{rand(100_000_000)}".freeze
3
3
  MOVE_TO_TMP_FOLDER = "mkdir -p #{TMP_FOLDER_NAME} && cd #{TMP_FOLDER_NAME}".freeze
4
4
 
5
5
  def run
@@ -0,0 +1,52 @@
1
+ class RenuoVersion
2
+ SEMVER_SCHEMA = /^\d+\.\d+\.\d+(\.[a-z]+\d+)?$/.freeze
3
+ SEGMENTS = %w[major minor patch].freeze
4
+
5
+ def self.create(str)
6
+ raise "Invalid segments (#{str} =~ #{SEMVER_SCHEMA})" unless str =~ SEMVER_SCHEMA
7
+
8
+ new(*str.split('.'))
9
+ end
10
+
11
+ attr_reader :segments
12
+
13
+ def initialize(major, minor, patch, prerelease = nil)
14
+ @segments = [major, minor, patch].map(&:to_i)
15
+ @segments.push(prerelease.to_s) if prerelease
16
+ end
17
+
18
+ def bump(segment)
19
+ raise "Invalid segment #{segment} (must be one of #{SEGMENTS})" unless SEGMENTS.include?(segment)
20
+
21
+ send("bump_#{segment}")
22
+ self
23
+ end
24
+
25
+ # Returns true if it's a release candidate (e.g. 3.0.0.rc4)
26
+ def prerelease?
27
+ @segments.length > 3
28
+ end
29
+
30
+ def to_s
31
+ @segments.join('.')
32
+ end
33
+
34
+ private
35
+
36
+ def bump_major
37
+ @segments = [@segments[0] + 1, 0, 0]
38
+ end
39
+
40
+ def bump_minor
41
+ @segments = [@segments[0], @segments[1] + 1, 0]
42
+ end
43
+
44
+ def bump_patch
45
+ if prerelease?
46
+ old_number = @segments[3][/\d+/]
47
+ @segments[3].gsub!(old_number, (old_number.to_i + 1).to_s)
48
+ else # default patch
49
+ @segments = [*@segments[0..1], @segments[2] + 1]
50
+ end
51
+ end
52
+ end
@@ -19,6 +19,7 @@ class RenuoCliConfig
19
19
  config = YAML.load_file(CONFIG_FILE_PATH, fallback: {})
20
20
  value = config[name]
21
21
  return value if value
22
+
22
23
  system("open #{open_url}")
23
24
  value = ask("You haven't set your #{name}, yet. Please provide one:")
24
25
  config[name] = value
@@ -61,6 +61,7 @@ class SetupUptimerobot
61
61
 
62
62
  def validate_new_project(robot_obj)
63
63
  return if robot_obj['stat'] == 'ok'
64
+
64
65
  abort("An error occoured. Uptimerobot returned '#{robot_obj['error']['message']}'")
65
66
  end
66
67
 
@@ -0,0 +1,31 @@
1
+ #!/bin/sh
2
+
3
+ for cache_group in "$@"
4
+ do
5
+ case $cache_group in
6
+
7
+ rails)
8
+ cache restore nvm-$SEMAPHORE_GIT_BRANCH-$(checksum .nvmrc),nvm-$SEMAPHORE_GIT_BRANCH,nvm-develop,nvm-main
9
+ cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-develop,gems-main
10
+ cache restore yarn-cache-$SEMAPHORE_GIT_BRANCH-$(checksum yarn.lock),yarn-cache-$SEMAPHORE_GIT_BRANCH,yarn-cache-develop,yarn-cache-main
11
+ cache restore node-modules-$SEMAPHORE_GIT_BRANCH-$(checksum yarn.lock),node-modules-$SEMAPHORE_GIT_BRANCH,node-modules-develop,node-modules-main
12
+ ;;
13
+
14
+ python)
15
+ cache restore requirements-$SEMAPHORE_GIT_BRANCH-$(checksum requirements.txt),requirements-$SEMAPHORE_GIT_BRANCH,requirements-develop,requirements-main
16
+ ;;
17
+
18
+ assets)
19
+ cache restore packs-$SEMAPHORE_GIT_BRANCH,packs-develop,packs-main
20
+ cache restore packstest-$SEMAPHORE_GIT_BRANCH,packstest-develop,packstest-main
21
+ cache restore assets-$SEMAPHORE_GIT_BRANCH,assets-develop,assets-main
22
+ cache restore sprocketscache-$SEMAPHORE_GIT_BRANCH,sprocketscache-develop,sprocketscache-main
23
+ cache restore webpackercache-$SEMAPHORE_GIT_BRANCH,webpackercache-develop,webpackercache-main
24
+ ;;
25
+
26
+ *)
27
+ echo "Invalid argument: Cache group $cache_group not found."
28
+ exit 1
29
+ ;;
30
+ esac
31
+ done
@@ -0,0 +1,31 @@
1
+ #!/bin/sh
2
+
3
+ for cache_group in "$@"
4
+ do
5
+ case $cache_group in
6
+
7
+ rails)
8
+ cache store nvm-$SEMAPHORE_GIT_BRANCH-$(checksum .nvmrc) $HOME/.nvm
9
+ cache store gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock) vendor/bundle
10
+ cache store yarn-cache-$SEMAPHORE_GIT_BRANCH-$(checksum yarn.lock) $HOME/.cache/yarn
11
+ cache store node-modules-$SEMAPHORE_GIT_BRANCH-$(checksum yarn.lock) node_modules
12
+ ;;
13
+
14
+ python)
15
+ cache store requirements-$SEMAPHORE_GIT_BRANCH-$(checksum requirements.txt) .pip_cache
16
+ ;;
17
+
18
+ assets)
19
+ cache store packs-$SEMAPHORE_GIT_BRANCH public/packs
20
+ cache store packstest-$SEMAPHORE_GIT_BRANCH public/packs-test
21
+ cache store assets-$SEMAPHORE_GIT_BRANCH public/assets
22
+ cache store sprocketscache-$SEMAPHORE_GIT_BRANCH tmp/cache/assets/sprockets
23
+ cache store webpackercache-$SEMAPHORE_GIT_BRANCH tmp/cache/webpacker
24
+ ;;
25
+
26
+ *)
27
+ echo "Invalid argument: Cache group $cache_group not found."
28
+ exit 1
29
+ ;;
30
+ esac
31
+ done
@@ -22,4 +22,6 @@ blocks:
22
22
  - ssh-add ~/.ssh/id_rsa_semaphore_heroku
23
23
  - git config --global url.ssh://git@heroku.com/.insteadOf https://git.heroku.com/
24
24
  - git remote add heroku $HEROKU_REMOTE
25
- - git push heroku -f $SEMAPHORE_GIT_BRANCH:master
25
+ - git push heroku -f $SEMAPHORE_GIT_BRANCH:main
26
+ - heroku run -x rails db:migrate
27
+ - heroku dyno:restart
@@ -0,0 +1,107 @@
1
+ version: "v1.0"
2
+ name: <%= project_name %>
3
+ agent:
4
+ machine:
5
+ type: e1-standard-2
6
+ os_image: ubuntu1804
7
+ auto_cancel:
8
+ running:
9
+ when: "true"
10
+ fail_fast:
11
+ cancel:
12
+ when: "branch != 'main'"
13
+
14
+ blocks:
15
+ - name: cache
16
+ execution_time_limit:
17
+ minutes: 10
18
+ dependencies: []
19
+ task:
20
+ secrets:
21
+ - name: <%= project_name %>
22
+ jobs:
23
+ - name: cache
24
+ commands:
25
+ - checkout --use-cache
26
+ - gem update --system --no-document
27
+ - source .semaphore/bin/cache_restore rails
28
+ - bundle config set deployment 'true'
29
+ - bundle config set path 'vendor/bundle'
30
+ - bundle install -j 4
31
+ - nvm install
32
+ - bin/yarn install --cache-folder ~/.cache/yarn
33
+ - source .semaphore/bin/cache_store rails
34
+ - name: linting
35
+ execution_time_limit:
36
+ minutes: 5
37
+ dependencies: ['cache']
38
+ task:
39
+ secrets:
40
+ - name: <%= project_name %>
41
+ env_vars:
42
+ - name: RAILS_ENV
43
+ value: test
44
+ prologue:
45
+ commands:
46
+ - checkout --use-cache
47
+ - gem update --system --no-document
48
+ - source .semaphore/bin/cache_restore rails
49
+ - bundle config set deployment 'true'
50
+ - bundle config set path 'vendor/bundle'
51
+ - bundle install -j 4
52
+ - nvm install
53
+ - bin/yarn install --cache-folder ~/.cache/yarn
54
+ jobs:
55
+ - name: linting
56
+ commands:
57
+ - bin/fastcheck
58
+ epilogue:
59
+ on_fail:
60
+ commands:
61
+ - mkdir -p log
62
+ - mkdir -p tmp/screenshots
63
+ - mkdir -p coverage
64
+ - artifact push job --expire-in 2w log
65
+ - artifact push job --expire-in 2w tmp/screenshots
66
+ - artifact push job --expire-in 2w coverage
67
+ - name: tests
68
+ execution_time_limit:
69
+ minutes: 10
70
+ dependencies: ['cache']
71
+ task:
72
+ secrets:
73
+ - name: <%= project_name %>
74
+ env_vars:
75
+ - name: DATABASE_URL
76
+ value: postgresql://postgres@localhost/test?encoding=utf8
77
+ - name: RAILS_ENV
78
+ value: test
79
+ prologue:
80
+ commands:
81
+ - checkout --use-cache
82
+ - gem update --system --no-document
83
+ - source .semaphore/bin/cache_restore rails
84
+ - bundle config set deployment 'true'
85
+ - bundle config set path 'vendor/bundle'
86
+ - bundle install -j 4
87
+ - nvm install
88
+ - bin/yarn install --cache-folder ~/.cache/yarn
89
+ - sem-service start postgres
90
+ - bundle exec rails db:create db:schema:load
91
+ jobs:
92
+ - name: tests
93
+ commands:
94
+ - bin/check
95
+ promotions:
96
+ - name: develop
97
+ pipeline_file: develop-deploy.yml
98
+ auto_promote:
99
+ when: "result = 'passed' and branch = 'develop'"
100
+ - name: main
101
+ pipeline_file: main-deploy.yml
102
+ auto_promote:
103
+ when: "result = 'passed' and branch = 'main'"
104
+ - name: testing
105
+ pipeline_file: testing-deploy.yml
106
+ auto_promote:
107
+ when: "result = 'passed' and branch = 'testing'"
@@ -7,6 +7,7 @@ require 'renuo/cli/app/toggl/detail'
7
7
  require 'renuo/cli/app/toggl/user'
8
8
  require 'terminal-table'
9
9
  require 'colorize'
10
+ require 'active_support/core_ext/numeric/time'
10
11
 
11
12
  class TogglRedmineComparator
12
13
  class << self
@@ -129,7 +130,7 @@ class TogglRedmineComparator
129
130
  end
130
131
 
131
132
  def non_working_day?(value)
132
- [value[:redmine], value[:toggl]].all? { |v| v == 0.0 }
133
+ [value[:redmine], value[:toggl]].all?(&:zero?)
133
134
  end
134
135
 
135
136
  BUFFER = 20_000
@@ -11,7 +11,7 @@ class UpgradeMacOS
11
11
  end
12
12
 
13
13
  def reboot_required?
14
- @output.include? '[restart]'
14
+ @output.downcase.include? 'restart'
15
15
  end
16
16
 
17
17
  private
@@ -32,7 +32,7 @@ class UpgradeMacOS
32
32
  end
33
33
 
34
34
  def agree_for_reboot?
35
- agree "\nYour Mac needs to be rebooted, Still continue?".red + ' (Yes / No)'
35
+ agree "#{"\nYour Mac needs to be rebooted, Still continue?".red} (Yes / No)"
36
36
  end
37
37
 
38
38
  def execute_upgrade
@@ -6,7 +6,7 @@ class Work
6
6
  ACTIONS = %w[start].freeze
7
7
 
8
8
  def run(args)
9
- ActiveResource::Base.logger = Logger.new(STDOUT)
9
+ ActiveResource::Base.logger = Logger.new($stdout)
10
10
  @action, @project_name, @ticket_number = args
11
11
  validate_action
12
12
  validate_project_name
@@ -1,6 +1,6 @@
1
1
  module Renuo
2
2
  module Cli
3
- VERSION = '1.7.2'.freeze
3
+ VERSION = '3.0.0'.freeze
4
4
  NAME = 'renuo-cli'.freeze
5
5
  end
6
6
  end
data/lib/renuo/cli.rb CHANGED
@@ -20,6 +20,7 @@ require 'renuo/cli/app/setup_uptimerobot'
20
20
  require 'renuo/cli/app/release_xing'
21
21
  require 'renuo/cli/app/configure_semaphore'
22
22
  require 'renuo/cli/app/toggl_redmine_comparator'
23
+ require 'renuo/cli/app/renuo_version'
23
24
 
24
25
  module Renuo
25
26
  class CLI
@@ -37,7 +38,6 @@ module Renuo
37
38
  abort 'Nice! I updated myself. 🤩 Now you can run the command again.'
38
39
  end
39
40
  abort('Good. Just do it yourself then...😒')
40
- exit
41
41
  end
42
42
 
43
43
  command 'display-name'.to_sym do |c|
@@ -109,7 +109,7 @@ module Renuo
109
109
  c.syntax = 'renuo create-aws-project'
110
110
  c.summary = 'Generates necessary commands for our project setup on AWS incl. necessary installations.'
111
111
  c.description = <<-DESCRIPTION
112
- This creates commands for creating AWS users, buckets an versioning policies and CloudFront.
112
+ This creates commands for creating AWS users, buckets an versioning policies and CloudFront.
113
113
  It also guides you to set up the necessary environment.
114
114
 
115
115
  You will be asked for:
@@ -120,10 +120,10 @@ module Renuo
120
120
  - whether you want to setup CloudFront to deliver assets via S3
121
121
 
122
122
  The generated commands do the following:
123
- - create an IAM user for each environment (master, develop, testing) and add it to the renuo apps group.
123
+ - create an IAM user for each environment (main, develop, testing) and add it to the renuo apps group.
124
124
  - create S3 buckets for each user who owns it
125
125
  - tag the buckets
126
- - enable versioning for master buckets
126
+ - enable versioning for main buckets
127
127
  (- set up a CloudFront distribution for each environment with the default config or plus alias if configured)
128
128
  DESCRIPTION
129
129
  c.example 'Setup a project (you will be asked for details)', 'renuo create-aws-project'
@@ -147,8 +147,8 @@ module Renuo
147
147
 
148
148
  command 'release' do |c|
149
149
  c.syntax = 'renuo release'
150
- c.summary = 'Release a projects state of develop (on github) to master in one command.'
151
- c.description = 'Creates a new release version of a project on master as either a Major, Minor, '\
150
+ c.summary = 'Release a projects state of develop (on github) to main in one command.'
151
+ c.description = 'Creates a new release version of a project on main as either a Major, Minor, '\
152
152
  'Patch or Custom release based on the current state of develop on Github'
153
153
  c.example 'renuo release my-project minor', 'release a minor release of my-project'
154
154
  c.example 'renuo release my-project custom 2.5.0', 'release my-project as release 2.5.0'
data/renuo-cli.gemspec CHANGED
@@ -17,6 +17,8 @@ Gem::Specification.new do |spec|
17
17
  spec.executables << 'renuo'
18
18
  spec.require_paths = ['lib']
19
19
 
20
+ spec.required_ruby_version = '>= 2.7.0'
21
+
20
22
  spec.add_dependency 'activeresource', '~> 5.1.0'
21
23
  spec.add_dependency 'colorize', '~> 0'
22
24
  spec.add_dependency 'commander', '~> 4.0'
@@ -26,13 +28,14 @@ Gem::Specification.new do |spec|
26
28
 
27
29
  spec.add_development_dependency 'aruba', '~> 0.14.5'
28
30
  spec.add_development_dependency 'bundler', '~> 2.0'
31
+ spec.add_development_dependency 'byebug'
29
32
  spec.add_development_dependency 'cucumber', '~> 3.1'
30
33
  spec.add_development_dependency 'dotenv', '~> 2.7.2'
31
34
  spec.add_development_dependency 'mdl', '~> 0.4.0'
32
35
  spec.add_development_dependency 'pry', '~> 0.11.3'
33
36
  spec.add_development_dependency 'rake', '~> 10.0'
34
37
  spec.add_development_dependency 'rspec', '~> 3.5'
35
- spec.add_development_dependency 'rubocop', '0.55.0'
38
+ spec.add_development_dependency 'rubocop', '~> 1.2'
36
39
  spec.add_development_dependency 'simplecov'
37
40
  spec.add_development_dependency 'simplecov-console'
38
41
  spec.add_development_dependency 'vcr', '~> 4.0.0'
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: 1.7.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renuo AG
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-15 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '2.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: cucumber
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -210,16 +224,16 @@ dependencies:
210
224
  name: rubocop
211
225
  requirement: !ruby/object:Gem::Requirement
212
226
  requirements:
213
- - - '='
227
+ - - "~>"
214
228
  - !ruby/object:Gem::Version
215
- version: 0.55.0
229
+ version: '1.2'
216
230
  type: :development
217
231
  prerelease: false
218
232
  version_requirements: !ruby/object:Gem::Requirement
219
233
  requirements:
220
- - - '='
234
+ - - "~>"
221
235
  - !ruby/object:Gem::Version
222
- version: 0.55.0
236
+ version: '1.2'
223
237
  - !ruby/object:Gem::Dependency
224
238
  name: simplecov
225
239
  requirement: !ruby/object:Gem::Requirement
@@ -291,9 +305,10 @@ files:
291
305
  - ".rspec"
292
306
  - ".rubocop.yml"
293
307
  - ".ruby-version"
308
+ - ".semaphore/bin/cache_restore"
309
+ - ".semaphore/bin/cache_store"
294
310
  - ".semaphore/master-deploy.yml"
295
311
  - ".semaphore/semaphore.yml"
296
- - CODE_OF_CONDUCT.md
297
312
  - Gemfile
298
313
  - LICENSE.txt
299
314
  - README.md
@@ -321,12 +336,15 @@ files:
321
336
  - lib/renuo/cli/app/redmine/issue.rb
322
337
  - lib/renuo/cli/app/release_project.rb
323
338
  - lib/renuo/cli/app/release_xing.rb
339
+ - lib/renuo/cli/app/renuo_version.rb
324
340
  - lib/renuo/cli/app/services/cloudfront_config_service.rb
325
341
  - lib/renuo/cli/app/services/markdown_parser_service.rb
326
342
  - lib/renuo/cli/app/services/renuo_cli_config.rb
327
343
  - lib/renuo/cli/app/setup_uptimerobot.rb
328
- - lib/renuo/cli/app/templates/semaphore-deploy.yml.erb
329
- - lib/renuo/cli/app/templates/semaphore.yml.erb
344
+ - lib/renuo/cli/app/templates/semaphore/bin/cache_restore.erb
345
+ - lib/renuo/cli/app/templates/semaphore/bin/cache_store.erb
346
+ - lib/renuo/cli/app/templates/semaphore/semaphore-deploy.yml.erb
347
+ - lib/renuo/cli/app/templates/semaphore/semaphore.yml.erb
330
348
  - lib/renuo/cli/app/toggl/detail.rb
331
349
  - lib/renuo/cli/app/toggl/time_entry.rb
332
350
  - lib/renuo/cli/app/toggl/user.rb
@@ -353,15 +371,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
353
371
  requirements:
354
372
  - - ">="
355
373
  - !ruby/object:Gem::Version
356
- version: '0'
374
+ version: 2.7.0
357
375
  required_rubygems_version: !ruby/object:Gem::Requirement
358
376
  requirements:
359
377
  - - ">="
360
378
  - !ruby/object:Gem::Version
361
379
  version: '0'
362
380
  requirements: []
363
- rubyforge_project:
364
- rubygems_version: 2.6.14
381
+ rubygems_version: 3.1.4
365
382
  signing_key:
366
383
  specification_version: 4
367
384
  summary: The Renuo CLI automates some common workflows.
data/CODE_OF_CONDUCT.md DELETED
@@ -1,13 +0,0 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
-
5
- We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
-
7
- Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
-
9
- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
-
11
- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
-
13
- This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
@@ -1,70 +0,0 @@
1
- version: "v1.0"
2
- name: <%= project_name %>
3
- agent:
4
- machine:
5
- type: e1-standard-2
6
- os_image: ubuntu1804
7
- auto_cancel:
8
- running:
9
- when: "true"
10
-
11
- blocks:
12
- - name: cache
13
- execution_time_limit:
14
- minutes: 10
15
- dependencies: []
16
- task:
17
- secrets:
18
- - name: <%= project_name %>
19
- jobs:
20
- - name: cache
21
- commands:
22
- - checkout --use-cache
23
- - cache restore nvm-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),nvm-$SEMAPHORE_GIT_BRANCH,nvm-develop,nvm-master
24
- - cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-develop,gems-master
25
- - cache restore yarn-cache-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),yarn-cache-$SEMAPHORE_GIT_BRANCH,yarn-cache-develop,yarn-cache-master
26
- - cache restore node-modules-$SEMAPHORE_GIT_BRANCH-$(checksum yarn.lock),node-modules-$SEMAPHORE_GIT_BRANCH,node-modules-develop,node-modules-master
27
- - bundle install --deployment -j 4 --path vendor/bundle
28
- - nvm install
29
- - bin/yarn install --cache-folder ~/.cache/yarn
30
- - cache store
31
- - name: tests
32
- execution_time_limit:
33
- minutes: 10
34
- dependencies: ['cache']
35
- task:
36
- secrets:
37
- - name: <%= project_name %>
38
- env_vars:
39
- - name: DATABASE_URL
40
- value: postgresql://postgres@localhost/test?encoding=utf8
41
- - name: RAILS_ENV
42
- value: test
43
- prologue:
44
- commands:
45
- - checkout --use-cache
46
- - cache restore nvm-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),nvm-$SEMAPHORE_GIT_BRANCH,nvm-develop,nvm-master
47
- - cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-develop,gems-master
48
- - cache restore yarn-cache-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),yarn-cache-$SEMAPHORE_GIT_BRANCH,yarn-cache-develop,yarn-cache-master
49
- - cache restore node-modules-$SEMAPHORE_GIT_BRANCH-$(checksum yarn.lock),node-modules-$SEMAPHORE_GIT_BRANCH,node-modules-develop,node-modules-master
50
- - bundle install --deployment --path vendor/bundle
51
- - bin/yarn install --cache-folder ~/.cache/yarn
52
- - sem-service start postgres
53
- - bundle exec rails db:create db:schema:load
54
- jobs:
55
- - name: tests
56
- commands:
57
- - bin/check
58
- promotions:
59
- - name: develop
60
- pipeline_file: develop-deploy.yml
61
- auto_promote:
62
- when: "result = 'passed' and branch = 'develop'"
63
- - name: master
64
- pipeline_file: master-deploy.yml
65
- auto_promote:
66
- when: "result = 'passed' and branch = 'master'"
67
- - name: testing
68
- pipeline_file: testing-deploy.yml
69
- auto_promote:
70
- when: "result = 'passed' and branch = 'testing'"