class ReleaseProject

rubocop:disable Metrics/ClassLength

Constants

MOVE_TO_TMP_FOLDER
TMP_FOLDER_NAME
UPDATE_TYPES

Public Instance Methods

run(args) click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 13
def run(args)
  @project_name, @update_type, @version = args
  validate_args
  open_comparison_page
  checkout_project # in the meantime
  veto_comparison
  @version ||= calculate_version
  release
ensure
  cleanup
end

Private Instance Methods

ask_for_final_confirmation() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 168
def ask_for_final_confirmation
  unless agree(">> Are you sure you wish to deploy '#{@project_name}' " \
               "as a #{@update_type} release (#{current_version} => #{@version})?")
    abort(">> Cancelling Release.")
  end

  return unless Time.current.friday? && Time.current.hour >= 16

  unless agree(">> Are you sure you want to deploy on late Friday afternoon? " \
               "Did you think about your family...waiting for you at home?")
    abort(">> Very good. Go home now.")
  end
end
bump_version() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 103
def bump_version
  version_bumped = find_and_replace_version

  return unless version_bumped

  system(cmd_in_folder(%(git add #{find_files_with_version.join(" ")} && git commit -m "Bump version")))
end
bump_version_in_file(file_name) click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 134
def bump_version_in_file(file_name)
  # Use `-i ''` for OS X and `-i` for GNU
  args = "''" unless system("sed --version > /dev/null 2>&1")

  system(cmd_in_folder("sed -i #{args} 's|#{current_version}|#{@version}|g' #{file_name}"))
end
calculate_version() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 80
def calculate_version
  RenuoVersion.create(current_version).bump(@update_type).to_s
end
checkout_project() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 73
def checkout_project
  abort(">> Project not found on Github.") unless system("#{MOVE_TO_TMP_FOLDER} && gh repo clone #{@project_name}")

  system(cmd_in_folder("git checkout #{main_branch} && git pull origin #{main_branch} &&" \
                       "git checkout #{develop_branch} && git pull origin #{develop_branch}"))
end
cleanup() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 194
def cleanup
  system("rm -rf #{TMP_FOLDER_NAME}")
end
cmd_in_folder(command) click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 182
def cmd_in_folder(command)
  "#{move_and_cd} && #{command}"
end
current_version() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 94
def current_version
  @current_version ||= if `#{cmd_in_folder("git tag")}` == ""
                         "0.0.0"
                       else
                         sorted_tags = `#{cmd_in_folder("git tag --sort=taggerdate")}`.split("\n").reverse
                         sorted_tags.find { |tag| tag =~ RenuoVersion::SEMVER_SCHEMA }.strip
                       end
end
custom_version?() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 54
def custom_version?
  @update_type == UPDATE_TYPES[3]
end
develop_branch() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 203
def develop_branch
  "develop"
end
find_and_replace_version() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 111
def find_and_replace_version
  find_files_with_version.any? do |file_name|
    puts "Replace the version in #{file_name}?"
    print_version_found(file_name)
    if agree("confirm?")
      bump_version_in_file(file_name)
      true
    else
      false
    end
  end
end
find_files_with_version() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 124
def find_files_with_version
  excluded_dirs = %w[.git node_modules tmp].map { |dir| "--exclude-dir=#{dir}" }.join(" ")
  grep_current_version = "grep -rl -F #{excluded_dirs} --include='*.rb' #{current_version} ."
  `#{cmd_in_folder(grep_current_version)}`.split("\n")
end
finish_release_branch() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 141
def finish_release_branch
  merge_branches
  push_branches_and_tags
end
folder_name() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 190
def folder_name
  @project_name.split("/").last
end
main_branch() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 198
def main_branch
  remote_repo = "git@github.com:#{@project_name}.git"
  @main_branch ||= `git ls-remote --heads #{remote_repo} main`.empty? ? "master" : "main"
end
merge_branches() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 146
def merge_branches
  system(
    cmd_in_folder(
      [
        "GIT_MERGE_AUTOEDIT=no git checkout #{main_branch}",
        "git merge #{develop_branch} --no-edit",
        "git tag -a #{@version} -m \"Release with version: #{@version}\""
      ].join(" && ")
    )
  )
end
move_and_cd() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 186
def move_and_cd
  "#{MOVE_TO_TMP_FOLDER} && cd #{folder_name}"
end
open_comparison_page() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 68
def open_comparison_page
  puts "Opening browser to double-check what is going to be deployed…"
  open_path "https://github.com/#{@project_name}/compare/#{main_branch}...develop"
end
print_version_found(file_name) click to toggle source
push_branch(branch) click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 164
def push_branch(branch)
  system(cmd_in_folder("git checkout #{branch} && git push origin #{branch}"))
end
push_branches_and_tags() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 158
def push_branches_and_tags
  push_branch(develop_branch)
  push_branch(main_branch)
  system(cmd_in_folder("git checkout #{main_branch} && git push origin #{main_branch} --tags"))
end
release() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 84
def release
  ask_for_final_confirmation
  bump_version
  if finish_release_branch
    puts ">> Project successfully released with version #{@version}."
  else
    abort(">> Unable to finish release and push to #{main_branch}. Cancelling release.")
  end
end
valid_update_type?() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 50
def valid_update_type?
  UPDATE_TYPES.include? @update_type
end
validate_args() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 27
def validate_args
  validate_project_name
  validate_update_type
  validate_custom_version_format
end
validate_custom_version_format() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 58
def validate_custom_version_format
  return if @version.nil? || @version =~ RenuoVersion::SEMVER_SCHEMA

  abort(">> Invalid Version Number. Use format X.Y.Z for your version.")
end
validate_project_name() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 33
def validate_project_name
  abort(">> No project name given.") unless @project_name
end
validate_update_type() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 37
def validate_update_type
  unless valid_update_type?
    abort(">> Please provide the desired update type: major, minor, patch or custom. " \
          "If you are unsure about the type please read https://semver.org")
  end

  if !custom_version? && @version
    abort(">> Do not specify a version for a non-custom release. Given version will be ignored.")
  end

  abort(">> Please enter your desired version for the custom release.") if custom_version? && @version.nil?
end
veto_comparison() click to toggle source
# File lib/renuo/cli/app/release_project.rb, line 64
def veto_comparison
  abort unless agree("Are you fine with the changes you just reviewed in your browser?")
end