Welcome to mirror list, hosted at ThFree Co, Russian Federation.

runner.rb « housekeeper « gitlab « lib « gitlab-housekeeper « gems - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1be94e15f3783a2d82da7af353f48591c6d79f8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

require 'active_support/core_ext/string'
require 'gitlab/housekeeper/keep'
require 'gitlab/housekeeper/gitlab_client'
require 'gitlab/housekeeper/git'
require 'digest'

module Gitlab
  module Housekeeper
    Change = Struct.new(:identifiers, :title, :description, :changed_files, :labels)

    class Runner
      def initialize(max_mrs: 1, dry_run: false, require: [], keeps: nil)
        @max_mrs = max_mrs
        @dry_run = dry_run
        @logger = Logger.new($stdout)
        require_keeps(require)

        @keeps = if keeps
                   keeps.map { |k| k.is_a?(String) ? k.constantize : k }
                 else
                   all_keeps
                 end
      end

      def run
        created = 0

        git.with_branch_from_branch do
          @keeps.each do |keep_class|
            keep = keep_class.new
            keep.each_change do |change|
              branch_name = git.commit_in_branch(change)

              if @dry_run
                dry_run(change, branch_name)
              else
                create(change, branch_name)
              end

              created += 1
              break if created >= @max_mrs
            end
            break if created >= @max_mrs
          end
        end

        puts "Housekeeper created #{created} MRs"
      end

      def git
        @git ||= ::Gitlab::Housekeeper::Git.new(logger: @logger)
      end

      def require_keeps(files)
        files.each do |r|
          require(Pathname(r).expand_path.to_s)
        end
      end

      def dry_run(change, branch_name)
        puts "=> #{change.identifiers.join(': ')}"

        if change.labels.present?
          puts '=> Attributes:'
          puts "Labels: #{change.labels.join(', ')}"
          puts
        end

        puts '=> Title:'
        puts change.title
        puts

        puts '=> Description:'
        puts change.description
        puts

        puts '=> Diff:'
        puts Shell.execute('git', '--no-pager', 'diff', '--color=always', 'master', branch_name, '--',
          *change.changed_files)
        puts
      end

      def create(change, branch_name)
        dry_run(change, branch_name)

        non_housekeeper_changes = gitlab_client.non_housekeeper_changes(
          source_project_id: housekeeper_fork_project_id,
          source_branch: branch_name,
          target_branch: 'master',
          target_project_id: housekeeper_target_project_id
        )

        unless non_housekeeper_changes.include?(:code)
          Shell.execute('git', 'push', '-f', 'housekeeper', "#{branch_name}:#{branch_name}")
        end

        gitlab_client.create_or_update_merge_request(
          source_project_id: housekeeper_fork_project_id,
          title: change.title,
          description: change.description,
          labels: change.labels,
          source_branch: branch_name,
          target_branch: 'master',
          target_project_id: housekeeper_target_project_id,
          update_title: !non_housekeeper_changes.include?(:title),
          update_description: !non_housekeeper_changes.include?(:description),
          update_labels: !non_housekeeper_changes.include?(:labels)
        )
      end

      def housekeeper_fork_project_id
        ENV.fetch('HOUSEKEEPER_FORK_PROJECT_ID')
      end

      def housekeeper_target_project_id
        ENV.fetch('HOUSEKEEPER_TARGET_PROJECT_ID')
      end

      def gitlab_client
        @gitlab_client ||= GitlabClient.new
      end

      def all_keeps
        @all_keeps ||= ObjectSpace.each_object(Class).select { |klass| klass < Keep }
      end
    end
  end
end