Class: FlashFlow::Merge::Master

Inherits:
Base
  • Object
show all
Defined in:
lib/flash_flow/merge/master.rb

Defined Under Namespace

Classes: GitPushFailure

Instance Method Summary collapse

Methods inherited from Base

#check_repo, #check_version, #git_merge, #is_working_branch, #logger, #merge_branches, #pending_release, #ready_to_merge_release, #release_ahead_of_master?, #write_data

Constructor Details

#initialize(opts = {}) ⇒ Master

Returns a new instance of Master.



10
11
12
13
14
# File 'lib/flash_flow/merge/master.rb', line 10

def initialize(opts={})
  super(opts)

  @data = Data::Base.new({}, Config.configuration.branch_info_file, @git, logger: logger)
end

Instance Method Details

#get_release_sha(opts = {}) ⇒ Object



122
123
124
# File 'lib/flash_flow/merge/master.rb', line 122

def get_release_sha(opts={})
  @get_release_sha ||= @git.get_sha("#{@git.remote}/#{@git.release_branch}", opts)
end

#merge_master(release) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/flash_flow/merge/master.rb', line 66

def merge_master(release)
  @git.in_original_merge_branch do
    @git.initialize_rerere
  end

  mergers = []

  @git.in_branch(@git.master_branch) do
    @git.run("reset --hard origin/master")
    merge_branches([Data::Branch.new(@git.release_branch)]) do |branch, merger|
      mergers << [branch, merger]
    end
  end

  errors = mergers.select { |m| m.last.result != :success }

  if errors.empty?
    unless @git.push("#{@git.master_branch}:#{@git.master_branch}", true)
      raise GitPushFailure.new("Unable to push to #{@git.master_branch}. See log for details.")
    end

    release['status'] = 'Success'
    release['released_sha'] = @git.get_sha("#{@git.remote}/#{@git.master_branch}")
    write_data('Release info updated [ci skip]')
  end

  errors
end

#ready!(release) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/flash_flow/merge/master.rb', line 95

def ready!(release)
  if !release
    raise NothingToMergeError.new("There is no pending release.")
  elsif !release_ahead_of_master?
    raise NothingToMergeError.new("The release branch '#{@git.release_branch}' has no commits that are not in master")
  elsif !release_qa_approved?
    raise FlashFlow::Release::QAError.new("The release build '#{get_release_sha(short: true)}' has not been approved for release")
  end
end

#release_qa_approved?Boolean

Returns:

  • (Boolean)


105
106
107
108
# File 'lib/flash_flow/merge/master.rb', line 105

def release_qa_approved?
  release = FlashFlow::Release::Base.new(FlashFlow::Config.configuration.release)
  release.qa_approved?(get_release_sha)
end

#runObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/flash_flow/merge/master.rb', line 36

def run
  begin
    check_version
    puts "Merging #{@git.release_branch} into #{@git.master_branch}"
    logger.info "\n\n### Beginning merge of #{@git.release_branch} into #{@git.master_branch} ###\n\n"

    errors = []

    @lock.with_lock do
      release = pending_release || ready_to_merge_release
      ready!(release)

      errors = merge_master(release)
    end

    if errors.empty?
      puts 'Success!'
    else
      raise UnmergeableBranch.new("#{@git.release_branch} didn't merge successfully to #{@git.master_branch}:\n  #{errors.map { |e| e.first.ref }.join("\n  ")}")
    end

    logger.info "### Finished merge of #{@git.release_branch} into #{@git.master_branch} ###"
  rescue Lock::Error, OutOfSyncWithRemote, UnmergeableBranch, GitPushFailure, NothingToMergeError, FlashFlow::Release::QAError, VersionError => e
    puts 'Failure!'
    puts e.message
  ensure
    @local_git.run("checkout #{@local_git.working_branch}")
  end
end

#send_mailObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/flash_flow/merge/master.rb', line 16

def send_mail
  check_version
  puts "Checking #{@git.release_branch} QA approval"
  logger.info "\n\n### Beginning check of #{@git.release_branch} QA ###\n\n"

  @lock.with_lock do
    release = pending_release
    ready!(release)

    send_release_ready_email(release)
  end

  logger.info "### Sent release email ###"
rescue Lock::Error, NothingToMergeError, FlashFlow::Release::QAError, VersionError => e
  puts 'Failure!'
  puts e.message
ensure
  @local_git.run("checkout #{@local_git.working_branch}")
end

#send_release_ready_email(release) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/flash_flow/merge/master.rb', line 110

def send_release_ready_email(release)
  begin
    mailer = FlashFlow::Mailer::Base.new(Config.configuration.smtp)
    mailer.deliver!(:release_ready, { approved_sha: get_release_sha(short: true) })

    release['status'] = 'Ready to merge'
    write_data('Release info updated [ci skip]')
  rescue ArgumentError => e
    raise FlashFlow::Release::QAError.new("Cannot send the email: #{e}")
  end
end