8957293d9b
1. Change multiple updates to a single `update_all` 2. Use cascading deletes 3. Extract an average function for the database median. 4. Move database median to `lib/gitlab/database` 5. Use `delete_all` instead of `destroy_all` 6. Minor refactoring
246 lines
7.6 KiB
Ruby
246 lines
7.6 KiB
Ruby
require 'sidekiq/testing'
|
|
require './spec/support/test_env'
|
|
|
|
class Gitlab::Seeder::CycleAnalytics
|
|
def initialize(project, perf: false)
|
|
@project = project
|
|
@user = User.order(:id).last
|
|
@issue_count = perf ? 1000 : 5
|
|
stub_git_pre_receive!
|
|
end
|
|
|
|
# The GitLab API needn't be running for the fixtures to be
|
|
# created. Since we're performing a number of git actions
|
|
# here (like creating a branch or committing a file), we need
|
|
# to disable the `pre_receive` hook in order to remove this
|
|
# dependency on the GitLab API.
|
|
def stub_git_pre_receive!
|
|
GitHooksService.class_eval do
|
|
def run_hook(name)
|
|
[true, '']
|
|
end
|
|
end
|
|
end
|
|
|
|
def seed_metrics!
|
|
@issue_count.times do |index|
|
|
# Issue
|
|
Timecop.travel 5.days.from_now
|
|
title = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
|
|
issue = Issue.create(project: @project, title: title, author: @user)
|
|
issue_metrics = issue.metrics
|
|
|
|
# Milestones / Labels
|
|
Timecop.travel 5.days.from_now
|
|
if index.even?
|
|
issue_metrics.first_associated_with_milestone_at = rand(6..12).hours.from_now
|
|
else
|
|
issue_metrics.first_added_to_board_at = rand(6..12).hours.from_now
|
|
end
|
|
|
|
# Commit
|
|
Timecop.travel 5.days.from_now
|
|
issue_metrics.first_mentioned_in_commit_at = rand(6..12).hours.from_now
|
|
|
|
# MR
|
|
Timecop.travel 5.days.from_now
|
|
branch_name = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
|
|
@project.repository.add_branch(@user, branch_name, 'master')
|
|
merge_request = MergeRequest.create(target_project: @project, source_project: @project, source_branch: branch_name, target_branch: 'master', title: branch_name, author: @user)
|
|
merge_request_metrics = merge_request.metrics
|
|
|
|
# MR closing issues
|
|
Timecop.travel 5.days.from_now
|
|
MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request)
|
|
|
|
# Merge
|
|
Timecop.travel 5.days.from_now
|
|
merge_request_metrics.merged_at = rand(6..12).hours.from_now
|
|
|
|
# Start build
|
|
Timecop.travel 5.days.from_now
|
|
merge_request_metrics.latest_build_started_at = rand(6..12).hours.from_now
|
|
|
|
# Finish build
|
|
Timecop.travel 5.days.from_now
|
|
merge_request_metrics.latest_build_finished_at = rand(6..12).hours.from_now
|
|
|
|
# Deploy to production
|
|
Timecop.travel 5.days.from_now
|
|
merge_request_metrics.first_deployed_to_production_at = rand(6..12).hours.from_now
|
|
|
|
issue_metrics.save!
|
|
merge_request_metrics.save!
|
|
|
|
print '.'
|
|
end
|
|
end
|
|
|
|
def seed!
|
|
Sidekiq::Testing.inline! do
|
|
issues = create_issues
|
|
puts '.'
|
|
|
|
# Stage 1
|
|
Timecop.travel 5.days.from_now
|
|
add_milestones_and_list_labels(issues)
|
|
print '.'
|
|
|
|
# Stage 2
|
|
Timecop.travel 5.days.from_now
|
|
branches = mention_in_commits(issues)
|
|
print '.'
|
|
|
|
# Stage 3
|
|
Timecop.travel 5.days.from_now
|
|
merge_requests = create_merge_requests_closing_issues(issues, branches)
|
|
print '.'
|
|
|
|
# Stage 4
|
|
Timecop.travel 5.days.from_now
|
|
run_builds(merge_requests)
|
|
print '.'
|
|
|
|
# Stage 5
|
|
Timecop.travel 5.days.from_now
|
|
merge_merge_requests(merge_requests)
|
|
print '.'
|
|
|
|
# Stage 6 / 7
|
|
Timecop.travel 5.days.from_now
|
|
deploy_to_production(merge_requests)
|
|
print '.'
|
|
end
|
|
|
|
print '.'
|
|
end
|
|
|
|
private
|
|
|
|
def create_issues
|
|
Array.new(@issue_count) do
|
|
issue_params = {
|
|
title: "Cycle Analytics: #{FFaker::Lorem.sentence(6)}",
|
|
description: FFaker::Lorem.sentence,
|
|
state: 'opened',
|
|
assignee: @project.team.users.sample
|
|
}
|
|
|
|
Issues::CreateService.new(@project, @project.team.users.sample, issue_params).execute
|
|
end
|
|
end
|
|
|
|
def add_milestones_and_list_labels(issues)
|
|
issues.shuffle.map.with_index do |issue, index|
|
|
Timecop.travel 12.hours.from_now
|
|
|
|
if index.even?
|
|
issue.update(milestone: @project.milestones.sample)
|
|
else
|
|
label_name = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
|
|
list_label = FactoryGirl.create(:label, title: label_name, project: issue.project)
|
|
FactoryGirl.create(:list, board: FactoryGirl.create(:board, project: issue.project), label: list_label)
|
|
issue.update(labels: [list_label])
|
|
end
|
|
|
|
issue
|
|
end
|
|
end
|
|
|
|
def mention_in_commits(issues)
|
|
issues.map do |issue|
|
|
Timecop.travel 12.hours.from_now
|
|
|
|
branch_name = filename = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
|
|
|
|
issue.project.repository.add_branch(@user, branch_name, 'master')
|
|
|
|
options = {
|
|
committer: issue.project.repository.user_to_committer(@user),
|
|
author: issue.project.repository.user_to_committer(@user),
|
|
commit: { message: "Commit for ##{issue.iid}", branch: branch_name, update_ref: true },
|
|
file: { content: "content", path: filename, update: false }
|
|
}
|
|
|
|
commit_sha = Gitlab::Git::Blob.commit(issue.project.repository, options)
|
|
issue.project.repository.commit(commit_sha)
|
|
|
|
|
|
GitPushService.new(issue.project,
|
|
@user,
|
|
oldrev: issue.project.repository.commit("master").sha,
|
|
newrev: commit_sha,
|
|
ref: 'refs/heads/master').execute
|
|
|
|
branch_name
|
|
end
|
|
end
|
|
|
|
def create_merge_requests_closing_issues(issues, branches)
|
|
issues.zip(branches).map do |issue, branch|
|
|
Timecop.travel 12.hours.from_now
|
|
|
|
opts = {
|
|
title: 'Cycle Analytics merge_request',
|
|
description: "Fixes #{issue.to_reference}",
|
|
source_branch: branch,
|
|
target_branch: 'master'
|
|
}
|
|
|
|
MergeRequests::CreateService.new(issue.project, @user, opts).execute
|
|
end
|
|
end
|
|
|
|
def run_builds(merge_requests)
|
|
merge_requests.each do |merge_request|
|
|
Timecop.travel 12.hours.from_now
|
|
|
|
service = Ci::CreatePipelineService.new(merge_request.project,
|
|
@user,
|
|
ref: "refs/heads/#{merge_request.source_branch}")
|
|
pipeline = service.execute(ignore_skip_ci: true, save_on_errors: false)
|
|
|
|
pipeline.run!
|
|
Timecop.travel rand(1..6).hours.from_now
|
|
pipeline.succeed!
|
|
end
|
|
end
|
|
|
|
def merge_merge_requests(merge_requests)
|
|
merge_requests.each do |merge_request|
|
|
Timecop.travel 12.hours.from_now
|
|
|
|
MergeRequests::MergeService.new(merge_request.project, @user).execute(merge_request)
|
|
end
|
|
end
|
|
|
|
def deploy_to_production(merge_requests)
|
|
merge_requests.each do |merge_request|
|
|
Timecop.travel 12.hours.from_now
|
|
|
|
CreateDeploymentService.new(merge_request.project, @user, {
|
|
environment: 'production',
|
|
ref: 'master',
|
|
tag: false,
|
|
sha: @project.repository.commit('master').sha
|
|
}).execute
|
|
end
|
|
end
|
|
end
|
|
|
|
Gitlab::Seeder.quiet do
|
|
if ENV['SEED_CYCLE_ANALYTICS']
|
|
Project.all.each do |project|
|
|
seeder = Gitlab::Seeder::CycleAnalytics.new(project)
|
|
seeder.seed!
|
|
end
|
|
elsif ENV['CYCLE_ANALYTICS_PERF_TEST']
|
|
seeder = Gitlab::Seeder::CycleAnalytics.new(Project.order(:id).first, perf: true)
|
|
seeder.seed!
|
|
elsif ENV['CYCLE_ANALYTICS_POPULATE_METRICS_DIRECTLY']
|
|
seeder = Gitlab::Seeder::CycleAnalytics.new(Project.order(:id).first, perf: true)
|
|
seeder.seed_metrics!
|
|
else
|
|
puts "Not running the cycle analytics seed file. Use the `SEED_CYCLE_ANALYTICS` environment variable to enable it."
|
|
end
|
|
end
|