BigW Consortium Gitlab

upgrader.rb 3.01 KB
Newer Older
Dmitriy Zaporozhets committed
1
require_relative "popen"
2 3 4 5 6
require_relative "version_info"

module Gitlab
  class Upgrader
    def execute
7
      puts "GitLab #{current_version.major} upgrade tool"
8 9 10 11
      puts "Your version is #{current_version}"
      puts "Latest available version for GitLab #{current_version.major} is #{latest_version}"

      if latest_version?
12
        puts "You are using the latest GitLab version"
13 14
      else
        puts "Newer GitLab version is available"
15
        answer = if ARGV.first == "-y"
16 17
                   "yes"
                 else
18
                   prompt("Do you want to upgrade (yes/no)? ", %w{yes no})
19
                 end
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

        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
Martins Polakovs committed
46 47 48 49 50 51 52
      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
53
      remote_tags, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} ls-remote --tags https://gitlab.com/gitlab-org/gitlab-ce.git))
Martins Polakovs committed
54
      remote_tags.split("\n").grep(/tags\/v#{current_version.major}/)
55 56 57 58
    end

    def update_commands
      {
59 60 61
        "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}),
62 63 64 65
        "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)
66 67 68
      }
    end

69
    def env
70
      { 'RAILS_ENV' => 'production' }
71 72
    end

73 74
    def upgrade
      update_commands.each do |title, cmd|
75
        puts title
76 77
        puts " -> #{cmd.join(' ')}"
        if system(env, *cmd)
78
          puts " -> OK"
79
        else
80
          puts " -> FAILED"
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
          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