108 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
require_relative "popen"
 | 
						|
require_relative "version_info"
 | 
						|
 | 
						|
module Gitlab
 | 
						|
  class Upgrader
 | 
						|
    def execute
 | 
						|
      puts "GitLab #{current_version.major} upgrade tool"
 | 
						|
      puts "Your version is #{current_version}"
 | 
						|
      puts "Latest available version for GitLab #{current_version.major} is #{latest_version}"
 | 
						|
 | 
						|
      if latest_version?
 | 
						|
        puts "You are using the latest GitLab version"
 | 
						|
      else
 | 
						|
        puts "Newer GitLab version is available"
 | 
						|
        answer = if ARGV.first == "-y"
 | 
						|
                   "yes"
 | 
						|
                 else
 | 
						|
                   prompt("Do you want to upgrade (yes/no)? ", %w{yes no})
 | 
						|
                 end
 | 
						|
 | 
						|
        if answer == "yes"
 | 
						|
          upgrade
 | 
						|
        else
 | 
						|
          exit 0
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    def latest_version?
 | 
						|
      current_version >= latest_version
 | 
						|
    end
 | 
						|
 | 
						|
    def current_version
 | 
						|
      @current_version ||= Gitlab::VersionInfo.parse(current_version_raw)
 | 
						|
    end
 | 
						|
 | 
						|
    def latest_version
 | 
						|
      @latest_version ||= Gitlab::VersionInfo.parse(latest_version_raw)
 | 
						|
    end
 | 
						|
 | 
						|
    def current_version_raw
 | 
						|
      File.read(File.join(gitlab_path, "VERSION")).strip
 | 
						|
    end
 | 
						|
 | 
						|
    def latest_version_raw
 | 
						|
      git_tags = fetch_git_tags
 | 
						|
      git_tags = git_tags.select { |version| version =~ /v\d+\.\d+\.\d+\Z/ }
 | 
						|
      git_versions = git_tags.map { |tag| Gitlab::VersionInfo.parse(tag.match(/v\d+\.\d+\.\d+/).to_s) }
 | 
						|
      "v#{git_versions.sort.last.to_s}"
 | 
						|
    end
 | 
						|
 | 
						|
    def fetch_git_tags
 | 
						|
      remote_tags, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} ls-remote --tags https://gitlab.com/gitlab-org/gitlab-ce.git))
 | 
						|
      remote_tags.split("\n").grep(/tags\/v#{current_version.major}/)
 | 
						|
    end
 | 
						|
 | 
						|
    def update_commands
 | 
						|
      {
 | 
						|
        "Stash changed files" => %W(#{Gitlab.config.git.bin_path} stash),
 | 
						|
        "Get latest code" => %W(#{Gitlab.config.git.bin_path} fetch),
 | 
						|
        "Switch to new version" => %W(#{Gitlab.config.git.bin_path} checkout v#{latest_version}),
 | 
						|
        "Install gems" => %W(bundle),
 | 
						|
        "Migrate DB" => %W(bundle exec rake db:migrate),
 | 
						|
        "Recompile assets" => %W(bundle exec rake assets:clean assets:precompile),
 | 
						|
        "Clear cache" => %W(bundle exec rake cache:clear)
 | 
						|
      }
 | 
						|
    end
 | 
						|
 | 
						|
    def env
 | 
						|
      { 'RAILS_ENV' => 'production' }
 | 
						|
    end
 | 
						|
 | 
						|
    def upgrade
 | 
						|
      update_commands.each do |title, cmd|
 | 
						|
        puts title
 | 
						|
        puts " -> #{cmd.join(' ')}"
 | 
						|
        if system(env, *cmd)
 | 
						|
          puts " -> OK"
 | 
						|
        else
 | 
						|
          puts " -> FAILED"
 | 
						|
          puts "Failed to upgrade. Try to repeat task or proceed with upgrade manually "
 | 
						|
          exit 1
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      puts "Done"
 | 
						|
    end
 | 
						|
 | 
						|
    def gitlab_path
 | 
						|
      File.expand_path(File.join(File.dirname(__FILE__), '../..'))
 | 
						|
    end
 | 
						|
 | 
						|
    # Prompt the user to input something
 | 
						|
    #
 | 
						|
    # message - the message to display before input
 | 
						|
    # choices - array of strings of acceptable answers or nil for any answer
 | 
						|
    #
 | 
						|
    # Returns the user's answer
 | 
						|
    def prompt(message, choices = nil)
 | 
						|
      begin
 | 
						|
        print(message)
 | 
						|
        answer = STDIN.gets.chomp
 | 
						|
      end while !choices.include?(answer)
 | 
						|
      answer
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |