Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c3d4086211
commit
f230568ed1
|
@ -135,7 +135,7 @@ class Issue < ApplicationRecord
|
|||
scope :with_prometheus_alert_events, -> { joins(:issues_prometheus_alert_events) }
|
||||
scope :with_self_managed_prometheus_alert_events, -> { joins(:issues_self_managed_prometheus_alert_events) }
|
||||
scope :with_api_entity_associations, -> {
|
||||
preload(:timelogs, :closed_by, :assignees, :author, :labels,
|
||||
preload(:timelogs, :closed_by, :assignees, :author, :labels, :issuable_severity,
|
||||
milestone: { project: [:route, { namespace: :route }] },
|
||||
project: [:route, { namespace: :route }])
|
||||
}
|
||||
|
|
|
@ -165,6 +165,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links":{
|
||||
"self":"http://gitlab.example.com/api/v4/projects/1/issues/76",
|
||||
"notes":"http://gitlab.example.com/api/v4/projects/1/issues/76/notes",
|
||||
|
@ -390,6 +391,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links":{
|
||||
"self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
|
||||
"notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
|
||||
|
@ -598,6 +600,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links":{
|
||||
"self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
|
||||
"notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
|
||||
|
@ -755,6 +758,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"task_completion_status": {
|
||||
"count": 0,
|
||||
"completed_count": 0
|
||||
|
@ -917,6 +921,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links": {
|
||||
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
|
||||
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
|
||||
|
@ -1064,6 +1069,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links": {
|
||||
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
|
||||
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
|
||||
|
@ -1238,6 +1244,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links": {
|
||||
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
|
||||
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
|
||||
|
@ -1421,6 +1428,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links": {
|
||||
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
|
||||
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
|
||||
|
@ -1560,6 +1568,7 @@ Example response:
|
|||
"confidential":false,
|
||||
"discussion_locked":null,
|
||||
"issue_type":"issue",
|
||||
"severity": "UNKNOWN",
|
||||
"web_url":"https://gitlab.example.com/namespace1/project2/-/issues/1",
|
||||
"time_stats":{
|
||||
"time_estimate":0,
|
||||
|
@ -1669,6 +1678,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"_links": {
|
||||
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
|
||||
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
|
||||
|
@ -1797,6 +1807,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"task_completion_status":{
|
||||
"count":0,
|
||||
"completed_count":0
|
||||
|
@ -1906,6 +1917,7 @@ Example response:
|
|||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"severity": "UNKNOWN",
|
||||
"task_completion_status":{
|
||||
"count":0,
|
||||
"completed_count":0
|
||||
|
|
|
@ -35,6 +35,10 @@ module API
|
|||
issue
|
||||
end
|
||||
|
||||
expose :severity,
|
||||
format_with: :upcase,
|
||||
documentation: { type: "String", desc: "One of #{::IssuableSeverity.severities.keys.map(&:upcase)}" }
|
||||
|
||||
# Calculating the value of subscribed field triggers Markdown
|
||||
# processing. We can't do that for multiple issues / merge
|
||||
# requests in a single API request.
|
||||
|
|
|
@ -66,7 +66,7 @@ module Gitlab
|
|||
current_size = 0
|
||||
|
||||
Gitlab::HTTP.get(url, stream_body: true, allow_object_storage: true) do |fragment|
|
||||
if [301, 302, 307].include?(fragment.code)
|
||||
if [301, 302, 303, 307].include?(fragment.code)
|
||||
Gitlab::Import::Logger.warn(message: "received redirect fragment", fragment_code: fragment.code)
|
||||
elsif fragment.code == 200
|
||||
current_size += fragment.bytesize
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'httparty'
|
||||
require 'csv'
|
||||
|
||||
namespace :ci do
|
||||
namespace :build_artifacts do
|
||||
desc "GitLab | CI | Fetch projects with incorrect artifact size on GitLab.com"
|
||||
task :project_with_incorrect_artifact_size do
|
||||
csv_url = ENV['SISENSE_PROJECT_IDS_WITH_INCORRECT_ARTIFACTS_URL']
|
||||
|
||||
# rubocop: disable Gitlab/HTTParty
|
||||
body = HTTParty.get(csv_url)
|
||||
# rubocop: enable Gitlab/HTTParty
|
||||
|
||||
table = CSV.parse(body.parsed_response, headers: true)
|
||||
puts table['PROJECT_ID'].join(' ')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'httparty'
|
||||
require 'csv'
|
||||
|
||||
namespace :gitlab do
|
||||
desc "GitLab | Refresh build artifacts size project statistics for given project IDs"
|
||||
desc "GitLab | Refresh build artifacts size project statistics for given list of Project IDs from remote CSV"
|
||||
|
||||
BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE = 500
|
||||
|
||||
task :refresh_project_statistics_build_artifacts_size, [:project_ids] => :environment do |_t, args|
|
||||
project_ids = []
|
||||
project_ids = $stdin.read.split unless $stdin.tty?
|
||||
project_ids = args.project_ids.to_s.split unless project_ids.any?
|
||||
task :refresh_project_statistics_build_artifacts_size, [:csv_url] => :environment do |_t, args|
|
||||
csv_url = args.csv_url
|
||||
|
||||
# rubocop: disable Gitlab/HTTParty
|
||||
body = HTTParty.get(csv_url)
|
||||
# rubocop: enable Gitlab/HTTParty
|
||||
|
||||
table = CSV.parse(body.to_s, headers: true)
|
||||
project_ids = table['PROJECT_ID']
|
||||
|
||||
puts "Loaded #{project_ids.size} project ids to import"
|
||||
|
||||
imported = 0
|
||||
missing = 0
|
||||
|
||||
if project_ids.any?
|
||||
project_ids.in_groups_of(BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE) do |ids|
|
||||
project_ids.in_groups_of(BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE, false) do |ids|
|
||||
projects = Project.where(id: ids)
|
||||
Projects::BuildArtifactsSizeRefresh.enqueue_refresh(projects)
|
||||
|
||||
imported += projects.size
|
||||
missing += ids.size - projects.size
|
||||
puts "#{imported}/#{project_ids.size} (missing projects: #{missing})"
|
||||
end
|
||||
puts 'Done.'.green
|
||||
else
|
||||
puts 'Please provide a string of space-separated project IDs as the argument or through the STDIN'.red
|
||||
puts 'Project IDs must be listed in the CSV under the header PROJECT_ID'.red
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -105,6 +105,9 @@ RSpec.configure do |config|
|
|||
# show exception that triggers a retry if verbose_retry is set to true
|
||||
config.display_try_failure_messages = true
|
||||
|
||||
# This option allows to use shorthand aliases for adding :focus metadata - fit, fdescribe and fcontext
|
||||
config.filter_run_when_matching :focus
|
||||
|
||||
if ENV['CI'] && !QA::Runtime::Env.disable_rspec_retry?
|
||||
non_quarantine_retries = QA::Runtime::Env.ci_project_name =~ /staging|canary|production/ ? 3 : 2
|
||||
config.around do |example|
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
"due_date": { "type": ["string", "null"] },
|
||||
"confidential": { "type": "boolean" },
|
||||
"web_url": { "type": "uri" },
|
||||
"severity": { "type": "string", "enum": ["UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"] },
|
||||
"time_stats": {
|
||||
"time_estimate": { "type": "integer" },
|
||||
"total_time_spent": { "type": "integer" },
|
||||
|
|
|
@ -114,7 +114,7 @@ RSpec.describe Gitlab::ImportExport::CommandLineUtil do
|
|||
end
|
||||
end
|
||||
|
||||
%w[MOVED_PERMANENTLY FOUND TEMPORARY_REDIRECT].each do |code|
|
||||
%w[MOVED_PERMANENTLY FOUND SEE_OTHER TEMPORARY_REDIRECT].each do |code|
|
||||
context "with a redirect status code #{code}" do
|
||||
let(:status) { HTTP::Status.const_get(code, false) }
|
||||
|
||||
|
|
|
@ -554,6 +554,27 @@ RSpec.describe API::Issues do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with incident issues' do
|
||||
let_it_be(:incident) { create(:incident, project: project) }
|
||||
|
||||
it 'avoids N+1 queries' do
|
||||
get api('/issues', user) # warm up
|
||||
|
||||
control = ActiveRecord::QueryRecorder.new do
|
||||
get api('/issues', user)
|
||||
end
|
||||
|
||||
create(:incident, project: project)
|
||||
create(:incident, project: project)
|
||||
|
||||
expect do
|
||||
get api('/issues', user)
|
||||
end.not_to exceed_query_limit(control)
|
||||
# 2 pre-existed issues + 3 incidents
|
||||
expect(json_response.count).to eq(5)
|
||||
end
|
||||
end
|
||||
|
||||
context 'filter by labels or label_name param' do
|
||||
context 'N+1' do
|
||||
let(:label_b) { create(:label, title: 'foo', project: project) }
|
||||
|
|
|
@ -11,37 +11,44 @@ RSpec.describe 'gitlab:refresh_project_statistics_build_artifacts_size rake task
|
|||
let_it_be(:project_3) { create(:project) }
|
||||
|
||||
let(:string_of_ids) { "#{project_1.id} #{project_2.id} #{project_3.id} 999999" }
|
||||
let(:csv_url) { 'https://www.example.com/foo.csv' }
|
||||
let(:csv_body) do
|
||||
<<~BODY
|
||||
PROJECT_ID
|
||||
#{project_1.id}
|
||||
#{project_2.id}
|
||||
#{project_3.id}
|
||||
BODY
|
||||
end
|
||||
|
||||
before do
|
||||
Rake.application.rake_require('tasks/gitlab/refresh_project_statistics_build_artifacts_size')
|
||||
|
||||
stub_const("BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE", 2)
|
||||
end
|
||||
|
||||
context 'when given a list of space-separated IDs through STDIN' do
|
||||
before do
|
||||
allow($stdin).to receive(:tty?).and_return(false)
|
||||
allow($stdin).to receive(:read).and_return(string_of_ids)
|
||||
end
|
||||
|
||||
it 'enqueues the projects for refresh' do
|
||||
expect { run_rake_task(rake_task) }.to output(/Done/).to_stdout
|
||||
|
||||
expect(Projects::BuildArtifactsSizeRefresh.all.map(&:project)).to match_array([project_1, project_2, project_3])
|
||||
end
|
||||
stub_request(:get, csv_url).to_return(status: 200, body: csv_body)
|
||||
end
|
||||
|
||||
context 'when given a list of space-separated IDs through rake argument' do
|
||||
it 'enqueues the projects for refresh' do
|
||||
expect { run_rake_task(rake_task, string_of_ids) }.to output(/Done/).to_stdout
|
||||
expect { run_rake_task(rake_task, csv_url) }.to output(/Done/).to_stdout
|
||||
|
||||
expect(Projects::BuildArtifactsSizeRefresh.all.map(&:project)).to match_array([project_1, project_2, project_3])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not given any IDs' do
|
||||
context 'when CSV has invalid header' do
|
||||
let(:csv_body) do
|
||||
<<~BODY
|
||||
projectid
|
||||
#{project_1.id}
|
||||
#{project_2.id}
|
||||
#{project_3.id}
|
||||
BODY
|
||||
end
|
||||
|
||||
it 'returns an error message' do
|
||||
expect { run_rake_task(rake_task) }.to output(/Please provide a string of space-separated project IDs/).to_stdout
|
||||
expect { run_rake_task(rake_task, csv_url) }.to output(/Project IDs must be listed in the CSV under the header PROJECT_ID/).to_stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue