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

group_seed.rake « seed « gitlab « tasks « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: cc9180d56a36a229acc603f33bdb3ccf4422cd33 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# frozen_string_literal: true

# Seed test groups with:
#   1. 2 Subgroups per level
#   1. 2 Users & group members per group
#   1. 2 Epics, 2 Milestones & 2 Projects per group
#   1. Project issues
#
# It also assigns each project's issue with one of group's or ascendants
# groups milestone & epic.
#
# @param subgroups_depth - number of subgroup levels
# @param username - user creating subgroups (i.e. GitLab admin)
#
# @example
#   bundle exec rake "gitlab:seed:group_seed[5, root]"
#
namespace :gitlab do
  namespace :seed do
    desc 'Seed groups with sub-groups/projects/epics/milestones for Group Import testing'
    task :group_seed, [:subgroups_depth, :username] => :gitlab_environment do |_t, args|
      require 'sidekiq/testing'

      GroupSeeder.new(
        subgroups_depth: args.subgroups_depth,
        username: args.username
      ).seed
    end
  end
end

class GroupSeeder
  PROJECT_URL = 'https://gitlab.com/gitlab-org/gitlab-test.git'

  attr_reader :all_group_ids

  def initialize(subgroups_depth:, username:)
    @subgroups_depth = subgroups_depth.to_i
    @user = User.find_by_username(username)
    @group_names = Set.new
    @resource_count = 2
    @all_groups = {}
    @all_group_ids = []
  end

  def seed
    create_groups

    puts 'Done!'
  end

  def create_groups
    create_root_group
    create_sub_groups
    create_users_and_members
    create_epics if Gitlab.ee?
    create_labels
    create_milestones

    Sidekiq::Testing.inline! do
      create_projects
    end
  end

  def create_users_and_members
    all_group_ids.each do |group_id|
      @resource_count.times do |_|
        user = create_user
        create_member(user.id, group_id)
      end
    end
  end

  def create_root_group
    root_group = ::Groups::CreateService.new(@user, group_params).execute

    track_group_id(1, root_group.id)
  end

  def create_sub_groups
    (2..@subgroups_depth).each do |level|
      parent_level = level - 1
      current_level = level
      parent_groups = @all_groups[parent_level]

      parent_groups.each do |parent_id|
        @resource_count.times do |_|
          sub_group = ::Groups::CreateService.new(@user, group_params(parent_id: parent_id)).execute

          track_group_id(current_level, sub_group.id)
        end
      end
    end
  end

  def track_group_id(depth_level, group_id)
    @all_groups[depth_level] ||= []
    @all_groups[depth_level] << group_id
    @all_group_ids << group_id
  end

  def group_params(parent_id: nil)
    name = unique_name

    {
      name: name,
      path: name,
      parent_id: parent_id
    }
  end

  def unique_name
    name = ffaker_name
    name = ffaker_name until @group_names.add?(name)
    name
  end

  def ffaker_name
    FFaker::Lorem.characters(5)
  end

  def create_user
    # rubocop:disable Style/SymbolProc -- Incorrect rubocop advice.
    User.create!(
      username: FFaker::Internet.user_name,
      name: FFaker::Name.name,
      email: FFaker::Internet.email,
      confirmed_at: DateTime.now,
      password: Devise.friendly_token
    ) do |user|
      user.assign_personal_namespace
    end
    # rubocop:enable Style/SymbolProc
  end

  def create_member(user_id, group_id)
    roles = Gitlab::Access.values

    GroupMember.create(user_id: user_id, access_level: roles.sample, source_id: group_id)
  end

  def create_epics
    all_group_ids.each do |group_id|
      @resource_count.times do |_|
        group = Group.find(group_id)

        epic_params = {
          title: FFaker::Lorem.sentence(6),
          description: FFaker::Lorem.paragraphs(3).join("\n\n"),
          author: group.users.sample,
          group: group
        }

        Epic.create!(epic_params)
      end
    end
  end

  def create_labels
    all_group_ids.each do |group_id|
      @resource_count.times do |_|
        group = Group.find(group_id)
        label_title = FFaker::Product.brand

        Labels::CreateService.new(title: label_title, color: "#{::Gitlab::Color.color_for(label_title)}").execute(group: group)
      end
    end
  end

  def create_milestones
    all_group_ids.each do |group_id|
      @resource_count.times do |i|
        group = Group.find(group_id)

        milestone_params = {
          title: "v#{i}.0",
          description: FFaker::Lorem.sentence,
          state: [:active, :closed].sample
        }

        Milestones::CreateService.new(group, group.members.sample, milestone_params).execute
      end
    end
  end

  def create_projects
    all_group_ids.each do |group_id|
      group = Group.find(group_id)

      @resource_count.times do |i|
        _, project_path = PROJECT_URL.split('/')[-2..]

        project_path.gsub!('.git', '')

        params = {
          import_url: PROJECT_URL,
          namespace_id: group.id,
          name: project_path.titleize + FFaker::Lorem.characters(10),
          description: FFaker::Lorem.sentence,
          visibility_level: 0,
          skip_disk_validation: true
        }

        project = nil

        Sidekiq::Worker.skipping_transaction_check do
          project = ::Projects::CreateService.new(@user, params).execute
          project.send(:_run_after_commit_queue)
          project.import_state.send(:_run_after_commit_queue)
          project.repository.expire_all_method_caches
        end

        create_project_issues(project)
        assign_issues_to_epics_and_milestones(project)
      end
    end
  end

  def create_project_issues(project)
    seeder = Quality::Seeders::Issues.new(project: project)
    seeder.seed(backfill_weeks: 2, average_issues_per_week: 2)
  end

  def assign_issues_to_epics_and_milestones(project)
    group_ids = project.group.self_and_ancestors.map(&:id)

    project.issues.each do |issue|
      issue_params = {
        milestone: Milestone.where(group: group_ids).sample
      }

      issue_params[:epic] = Epic.where(group: group_ids).sample if Gitlab.ee?

      issue.update(issue_params)
    end
  end
end