Commit c1bacbd3 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 6aedae30 510ee2a4
...@@ -47,7 +47,7 @@ When GitLab detects a **Denied** license, you can view it in the [license list]( ...@@ -47,7 +47,7 @@ When GitLab detects a **Denied** license, you can view it in the [license list](
![License List](img/license_list_v13_0.png) ![License List](img/license_list_v13_0.png)
You can view and modify existing policies from the [policies](#policies) tab. You can view and modify existing policies from the [policies](#policies) tab.
![Edit Policy](img/policies_maintainer_edit_v14_2.png) ![Edit Policy](img/policies_maintainer_edit_v14_3.png)
## License expressions ## License expressions
...@@ -742,8 +742,9 @@ which enables a designated approver that can approve and then merge a merge requ ...@@ -742,8 +742,9 @@ which enables a designated approver that can approve and then merge a merge requ
The **Policies** tab in the project's license compliance section displays your project's license The **Policies** tab in the project's license compliance section displays your project's license
policies. Project maintainers can specify policies in this section. policies. Project maintainers can specify policies in this section.
![Edit Policy](img/policies_maintainer_edit_v14_2.png) ![Edit Policy](img/policies_maintainer_edit_v14_3.png)
![Add Policy](img/policies_maintainer_add_v13_2.png)
![Add Policy](img/policies_maintainer_add_v14_3.png)
Developers of the project can view the policies configured in a project. Developers of the project can view the policies configured in a project.
......
...@@ -12,13 +12,13 @@ module QA ...@@ -12,13 +12,13 @@ module QA
:auto_devops_enabled, :auto_devops_enabled,
:github_personal_access_token, :github_personal_access_token,
:github_repository_path, :github_repository_path,
:gitlab_repository_path :gitlab_repository_path,
:personal_namespace
attributes :id, attributes :id,
:name, :name,
:add_name_uuid, :add_name_uuid,
:description, :description,
:personal_namespace,
:runners_token, :runners_token,
:visibility, :visibility,
:template_name, :template_name,
...@@ -31,13 +31,15 @@ module QA ...@@ -31,13 +31,15 @@ module QA
end end
attribute :path_with_namespace do attribute :path_with_namespace do
"#{group.full_path}/#{name}" "#{personal_namespace || group.full_path}/#{name}"
end end
alias_method :full_path, :path_with_namespace alias_method :full_path, :path_with_namespace
def sandbox_path def sandbox_path
group.respond_to?('sandbox') ? "#{group.sandbox.path}/" : '' return '' if personal_namespace || !group.respond_to?('sandbox')
"#{group.sandbox.path}/"
end end
attribute :repository_ssh_location do attribute :repository_ssh_location do
...@@ -50,12 +52,12 @@ module QA ...@@ -50,12 +52,12 @@ module QA
def initialize def initialize
@add_name_uuid = true @add_name_uuid = true
@personal_namespace = false
@description = 'My awesome project' @description = 'My awesome project'
@initialize_with_readme = false @initialize_with_readme = false
@auto_devops_enabled = false @auto_devops_enabled = false
@visibility = :public @visibility = :public
@template_name = nil @template_name = nil
@personal_namespace = nil
@import = false @import = false
self.name = "the_awesome_project" self.name = "the_awesome_project"
...@@ -68,7 +70,7 @@ module QA ...@@ -68,7 +70,7 @@ module QA
def fabricate! def fabricate!
return if @import return if @import
if @personal_namespace if personal_namespace
Page::Dashboard::Projects.perform(&:click_new_project_button) Page::Dashboard::Projects.perform(&:click_new_project_button)
else else
group.visit! group.visit!
......
...@@ -34,7 +34,7 @@ module QA ...@@ -34,7 +34,7 @@ module QA
def fabricate_via_api! def fabricate_via_api!
super super
rescue ResourceURLMissingError rescue ResourceURLMissingError
"#{Runtime::Scenario.gitlab_address}/#{group.full_path}/#{name}" "#{Runtime::Scenario.gitlab_address}/#{full_path}"
end end
def api_post_path def api_post_path
...@@ -49,7 +49,7 @@ module QA ...@@ -49,7 +49,7 @@ module QA
{ {
repo_id: github_repo_id, repo_id: github_repo_id,
new_name: name, new_name: name,
target_namespace: group.full_path, target_namespace: @personal_namespace || group.full_path,
personal_access_token: github_personal_access_token, personal_access_token: github_personal_access_token,
ci_cd_only: false ci_cd_only: false
} }
......
...@@ -9,11 +9,6 @@ module QA ...@@ -9,11 +9,6 @@ module QA
let(:differ) { RSpec::Support::Differ.new(color: true) } let(:differ) { RSpec::Support::Differ.new(color: true) }
let(:api_client) { Runtime::API::Client.as_admin } let(:api_client) { Runtime::API::Client.as_admin }
let(:group) do
Resource::Group.fabricate_via_api! do |resource|
resource.api_client = api_client
end
end
let(:user) do let(:user) do
Resource::User.fabricate_via_api! do |resource| Resource::User.fabricate_via_api! do |resource|
...@@ -86,19 +81,15 @@ module QA ...@@ -86,19 +81,15 @@ module QA
Resource::ProjectImportedFromGithub.fabricate_via_api! do |project| Resource::ProjectImportedFromGithub.fabricate_via_api! do |project|
project.add_name_uuid = false project.add_name_uuid = false
project.name = 'imported-project' project.name = 'imported-project'
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = github_repo project.github_repository_path = github_repo
project.personal_namespace = user.username
project.api_client = api_client project.api_client = api_client
end end
end end
before do
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
end
after do |example| after do |example|
user.remove_via_api! user.remove_via_api! unless example.exception
next unless defined?(@import_time) next unless defined?(@import_time)
# save data for comparison after run finished # save data for comparison after run finished
...@@ -128,7 +119,10 @@ module QA ...@@ -128,7 +119,10 @@ module QA
) )
end end
it 'imports large Github repo via api', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1880' do it(
'imports large Github repo via api',
testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1880'
) do
start = Time.now start = Time.now
Runtime::Logger.info("Importing project '#{imported_project.full_path}'") # import the project and log path Runtime::Logger.info("Importing project '#{imported_project.full_path}'") # import the project and log path
......
...@@ -46,10 +46,9 @@ module QA ...@@ -46,10 +46,9 @@ module QA
def create_project(user, api_client, project_name) def create_project(user, api_client, project_name)
project = Resource::Project.fabricate_via_api! do |project| project = Resource::Project.fabricate_via_api! do |project|
project.personal_namespace = true project.personal_namespace = user.username
project.add_name_uuid = false project.add_name_uuid = false
project.name = project_name project.name = project_name
project.path_with_namespace = "#{user.username}/#{project_name}"
project.api_client = api_client project.api_client = api_client
end end
......
...@@ -39,7 +39,7 @@ module QA ...@@ -39,7 +39,7 @@ module QA
Resource::Project.fabricate_via_browser_ui! do |project| Resource::Project.fabricate_via_browser_ui! do |project|
project.name = project_name project.name = project_name
project.description = 'create awesome project test' project.description = 'create awesome project test'
project.personal_namespace = true project.personal_namespace = Runtime::User.username
end end
end end
......
...@@ -8,9 +8,11 @@ module QA ...@@ -8,9 +8,11 @@ module QA
HTTP_STATUS_NO_CONTENT = 204 HTTP_STATUS_NO_CONTENT = 204
HTTP_STATUS_ACCEPTED = 202 HTTP_STATUS_ACCEPTED = 202
HTTP_STATUS_NOT_FOUND = 404 HTTP_STATUS_NOT_FOUND = 404
HTTP_STATUS_TOO_MANY_REQUESTS = 429
HTTP_STATUS_SERVER_ERROR = 500 HTTP_STATUS_SERVER_ERROR = 500
def post(url, payload, args = {}) def post(url, payload, args = {})
with_retry_on_too_many_requests do
default_args = { default_args = {
method: :post, method: :post,
url: url, url: url,
...@@ -24,8 +26,10 @@ module QA ...@@ -24,8 +26,10 @@ module QA
rescue RestClient::ExceptionWithResponse => e rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e) return_response_or_raise(e)
end end
end
def get(url, args = {}) def get(url, args = {})
with_retry_on_too_many_requests do
default_args = { default_args = {
method: :get, method: :get,
url: url, url: url,
...@@ -38,8 +42,10 @@ module QA ...@@ -38,8 +42,10 @@ module QA
rescue RestClient::ExceptionWithResponse => e rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e) return_response_or_raise(e)
end end
end
def put(url, payload = nil) def put(url, payload = nil)
with_retry_on_too_many_requests do
RestClient::Request.execute( RestClient::Request.execute(
method: :put, method: :put,
url: url, url: url,
...@@ -48,8 +54,10 @@ module QA ...@@ -48,8 +54,10 @@ module QA
rescue RestClient::ExceptionWithResponse => e rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e) return_response_or_raise(e)
end end
end
def delete(url) def delete(url)
with_retry_on_too_many_requests do
RestClient::Request.execute( RestClient::Request.execute(
method: :delete, method: :delete,
url: url, url: url,
...@@ -57,8 +65,10 @@ module QA ...@@ -57,8 +65,10 @@ module QA
rescue RestClient::ExceptionWithResponse => e rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e) return_response_or_raise(e)
end end
end
def head(url) def head(url)
with_retry_on_too_many_requests do
RestClient::Request.execute( RestClient::Request.execute(
method: :head, method: :head,
url: url, url: url,
...@@ -66,6 +76,26 @@ module QA ...@@ -66,6 +76,26 @@ module QA
rescue RestClient::ExceptionWithResponse => e rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e) return_response_or_raise(e)
end end
end
def with_retry_on_too_many_requests
response = nil
Support::Retrier.retry_until do
response = yield
if response.code == HTTP_STATUS_TOO_MANY_REQUESTS
wait_seconds = response.headers[:retry_after].to_i
QA::Runtime::Logger.debug("Received 429 - Too many requests. Waiting for #{wait_seconds} seconds.")
sleep wait_seconds
end
response.code != HTTP_STATUS_TOO_MANY_REQUESTS
end
response
end
def parse_body(response) def parse_body(response)
JSON.parse(response.body, symbolize_names: true) JSON.parse(response.body, symbolize_names: true)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment