Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5ced7473bb
commit
9d20ce8c99
25 changed files with 101 additions and 161 deletions
|
@ -12,3 +12,5 @@ class Projects::DeployTokensController < Projects::ApplicationController
|
|||
redirect_to project_settings_repository_path(project, anchor: 'js-deploy-tokens')
|
||||
end
|
||||
end
|
||||
|
||||
Projects::DeployTokensController.prepend_mod
|
||||
|
|
|
@ -89,11 +89,7 @@ module Projects
|
|||
# OWNER access level
|
||||
def project_owner
|
||||
user_id = project.namespace.owner.id
|
||||
access_level = if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
|
||||
Gitlab::Access::OWNER
|
||||
else
|
||||
Gitlab::Access::MAINTAINER
|
||||
end
|
||||
access_level = Gitlab::Access::OWNER
|
||||
|
||||
Member
|
||||
.from(generate_from_statement([[user_id, access_level]])) # rubocop: disable CodeReuse/ActiveRecord
|
||||
|
|
|
@ -11,11 +11,7 @@ module SelectForProjectAuthorization
|
|||
# workaround until we migrate Project#owners to have membership with
|
||||
# OWNER access level
|
||||
def select_project_owner_for_project_authorization
|
||||
if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
|
||||
select(["projects.id AS project_id", "#{Gitlab::Access::OWNER} AS access_level"])
|
||||
else
|
||||
select(["projects.id AS project_id", "#{Gitlab::Access::MAINTAINER} AS access_level"])
|
||||
end
|
||||
select(["projects.id AS project_id", "#{Gitlab::Access::OWNER} AS access_level"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -94,14 +94,7 @@ class ProjectMember < Member
|
|||
|
||||
override :access_level_inclusion
|
||||
def access_level_inclusion
|
||||
allowed_values = if ::Feature.enabled?(:personal_project_owner_with_owner_access,
|
||||
default_enabled: :yaml)
|
||||
Gitlab::Access.all_values
|
||||
else
|
||||
Gitlab::Access.values
|
||||
end
|
||||
|
||||
unless access_level.in?(allowed_values)
|
||||
unless access_level.in?(Gitlab::Access.all_values)
|
||||
errors.add(:access_level, "is not included in the list")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -147,11 +147,7 @@ module Projects
|
|||
priority: UserProjectAccessChangedService::LOW_PRIORITY
|
||||
)
|
||||
else
|
||||
if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
|
||||
@project.add_owner(@project.namespace.owner, current_user: current_user)
|
||||
else
|
||||
@project.add_maintainer(@project.namespace.owner, current_user: current_user)
|
||||
end
|
||||
@project.add_owner(@project.namespace.owner, current_user: current_user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,3 +13,5 @@ module Projects
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Projects::DeployTokens::CreateService.prepend_mod
|
||||
|
|
|
@ -11,3 +11,5 @@ module Projects
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Projects::DeployTokens::DestroyService.prepend_mod
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: personal_project_owner_with_owner_access
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78193
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351919
|
||||
milestone: '14.8'
|
||||
type: development
|
||||
group: group::workspace
|
||||
default_enabled: false
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveNotNullConstraintForSecurityScanSucceeded < Gitlab::Database::Migration[1.0]
|
||||
def up
|
||||
change_column_null :analytics_devops_adoption_snapshots, :security_scan_succeeded, true
|
||||
end
|
||||
|
||||
def down
|
||||
# There may now be nulls in the table, so we cannot re-add the constraint here.
|
||||
end
|
||||
end
|
1
db/schema_migrations/20220222191845
Normal file
1
db/schema_migrations/20220222191845
Normal file
|
@ -0,0 +1 @@
|
|||
c528d64cafc072554cd1ef1006a1c359a3135896abae2d5ca20fbbc99ff14f8c
|
|
@ -10776,7 +10776,7 @@ CREATE TABLE analytics_devops_adoption_snapshots (
|
|||
runner_configured boolean NOT NULL,
|
||||
pipeline_succeeded boolean NOT NULL,
|
||||
deploy_succeeded boolean NOT NULL,
|
||||
security_scan_succeeded boolean NOT NULL,
|
||||
security_scan_succeeded boolean,
|
||||
end_time timestamp with time zone NOT NULL,
|
||||
total_projects_count integer,
|
||||
code_owners_used_count integer,
|
||||
|
|
|
@ -160,6 +160,8 @@ From there, you can see the following actions:
|
|||
- Allowing force push to protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
|
||||
- Code owner approval requirement on merge requests targeting protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
|
||||
- Users and groups allowed to merge and push to protected branch added or removed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
|
||||
- Project deploy token was successfully created, revoked or deleted ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353451) in GitLab 14.9)
|
||||
- Failed attempt to create a project deploy token ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353451) in GitLab 14.9)
|
||||
|
||||
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
|
||||
|
||||
|
|
|
@ -40,7 +40,9 @@ If you are using GDK, you can follow the following steps:
|
|||
```yaml
|
||||
gitlab:
|
||||
rails:
|
||||
multiple_databases: true
|
||||
databases:
|
||||
ci:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
1. Reconfigure GDK:
|
||||
|
|
|
@ -33,14 +33,8 @@ usernames. A GitLab administrator can configure the GitLab instance to
|
|||
|
||||
## Project members permissions
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/219299) in GitLab 14.8, personal namespace owners appear with Owner role in new projects in their namespace. Introduced [with a flag](../administration/feature_flags.md) named `personal_project_owner_with_owner_access`. Disabled by default.
|
||||
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/351919) in GitLab 14.9.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, personal namespace owners appearing with the Owner role in new projects in their namespace is disabled. To make it available,
|
||||
ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `personal_project_owner_with_owner_access`.
|
||||
The feature is not ready for production use.
|
||||
On GitLab.com, this feature is available.
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/219299) in GitLab 14.8, personal namespace owners appear with Owner role in new projects in their namespace. Introduced [with a flag](../administration/feature_flags.md) named `personal_project_owner_with_owner_access`. Disabled by default.
|
||||
- [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/351919) in GitLab 14.9. Feature flag `personal_project_owner_with_owner_access` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/219299).
|
||||
|
||||
A user's role determines what permissions they have on a project. The Owner role provides all permissions but is
|
||||
available only:
|
||||
|
@ -51,7 +45,7 @@ available only:
|
|||
Personal [namespace](group/index.md#namespaces) owners:
|
||||
|
||||
- Are displayed as having the Maintainer role on projects in the namespace, but have the same permissions as a user with the Owner role.
|
||||
- (Disabled by default) In GitLab 14.8 and later, for new projects in the namespace, are displayed as having the Owner role.
|
||||
- In GitLab 14.9 and later, for new projects in the namespace, are displayed as having the Owner role.
|
||||
|
||||
For more information about how to manage project members, see
|
||||
[members of a project](project/members/index.md).
|
||||
|
|
|
@ -127,16 +127,21 @@ module Atlassian
|
|||
def handle_response(response, name, &block)
|
||||
data = response.parsed_response
|
||||
|
||||
case response.code
|
||||
when 200 then yield data
|
||||
when 400 then { 'errorMessages' => data.map { |e| e['message'] } }
|
||||
when 401 then { 'errorMessages' => ['Invalid JWT'] }
|
||||
when 403 then { 'errorMessages' => ["App does not support #{name}"] }
|
||||
when 413 then { 'errorMessages' => ['Data too large'] + data.map { |e| e['message'] } }
|
||||
when 429 then { 'errorMessages' => ['Rate limit exceeded'] }
|
||||
when 503 then { 'errorMessages' => ['Service unavailable'] }
|
||||
if [200, 202].include?(response.code)
|
||||
yield data
|
||||
else
|
||||
{ 'errorMessages' => ['Unknown error'], 'response' => data }
|
||||
message = case response.code
|
||||
when 400 then { 'errorMessages' => data.map { |e| e['message'] } }
|
||||
when 401 then { 'errorMessages' => ['Invalid JWT'] }
|
||||
when 403 then { 'errorMessages' => ["App does not support #{name}"] }
|
||||
when 413 then { 'errorMessages' => ['Data too large'] + data.map { |e| e['message'] } }
|
||||
when 429 then { 'errorMessages' => ['Rate limit exceeded'] }
|
||||
when 503 then { 'errorMessages' => ['Service unavailable'] }
|
||||
else
|
||||
{ 'errorMessages' => ['Unknown error'], 'response' => data }
|
||||
end
|
||||
|
||||
message.merge('responseCode' => response.code)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -40735,9 +40735,6 @@ msgstr ""
|
|||
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
|
||||
msgstr ""
|
||||
|
||||
msgid "VulnerabilityManagement|At least one identifier is required"
|
||||
msgstr ""
|
||||
|
||||
msgid "VulnerabilityManagement|Change status"
|
||||
msgstr ""
|
||||
|
||||
|
@ -40759,6 +40756,9 @@ msgstr ""
|
|||
msgid "VulnerabilityManagement|Fetching linked Jira issues"
|
||||
msgstr ""
|
||||
|
||||
msgid "VulnerabilityManagement|Identifier code and URL are required fields"
|
||||
msgstr ""
|
||||
|
||||
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ module QA
|
|||
def initialize
|
||||
super
|
||||
|
||||
@name = @path = 'reusable_group'
|
||||
@name = @path = QA::Runtime::Env.reusable_group_path
|
||||
@description = "QA reusable group"
|
||||
@reuse_as = :default_group
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ module QA
|
|||
super
|
||||
|
||||
@add_name_uuid = false
|
||||
@name = @path = 'reusable_project'
|
||||
@name = @path = QA::Runtime::Env.reusable_project_path
|
||||
@reuse_as = :default_project
|
||||
@initialize_with_readme = true
|
||||
end
|
||||
|
|
|
@ -404,6 +404,14 @@ module QA
|
|||
ENV.fetch('GITLAB_QA_LOOP_RUNNER_MINUTES', 1).to_i
|
||||
end
|
||||
|
||||
def reusable_project_path
|
||||
ENV.fetch('QA_REUSABLE_PROJECT_PATH', 'reusable_project')
|
||||
end
|
||||
|
||||
def reusable_group_path
|
||||
ENV.fetch('QA_REUSABLE_GROUP_PATH', 'reusable_group')
|
||||
end
|
||||
|
||||
def mailhog_hostname
|
||||
ENV['MAILHOG_HOSTNAME']
|
||||
end
|
||||
|
|
|
@ -76,7 +76,8 @@ RSpec.configure do |config|
|
|||
QA::Resource::ReusableCollection.validate_resource_reuse if QA::Runtime::Env.validate_resource_reuse?
|
||||
|
||||
# If any tests failed, leave the resources behind to help troubleshoot, otherwise remove them.
|
||||
QA::Resource::ReusableCollection.remove_all_via_api! unless suite.reporter.failed_examples.present?
|
||||
# Do not remove the shared resource on live environments
|
||||
QA::Resource::ReusableCollection.remove_all_via_api! if !suite.reporter.failed_examples.present? && !QA::Runtime::Env.running_on_dot_com?
|
||||
end
|
||||
|
||||
config.append_after(:suite) do
|
||||
|
|
|
@ -12,34 +12,15 @@ RSpec.describe Projects::Members::EffectiveAccessLevelFinder, '#execute' do
|
|||
let_it_be(:project) { create(:project) }
|
||||
|
||||
shared_examples_for 'includes access level of the owner of the project' do
|
||||
context 'when personal_project_owner_with_owner_access feature flag is enabled' do
|
||||
it 'includes access level of the owner of the project as Owner' do
|
||||
expect(subject).to(
|
||||
contain_exactly(
|
||||
hash_including(
|
||||
'user_id' => project.namespace.owner.id,
|
||||
'access_level' => Gitlab::Access::OWNER
|
||||
)
|
||||
it 'includes access level of the owner of the project as Owner' do
|
||||
expect(subject).to(
|
||||
contain_exactly(
|
||||
hash_including(
|
||||
'user_id' => project.namespace.owner.id,
|
||||
'access_level' => Gitlab::Access::OWNER
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when personal_project_owner_with_owner_access feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(personal_project_owner_with_owner_access: false)
|
||||
end
|
||||
|
||||
it 'includes access level of the owner of the project as Maintainer' do
|
||||
expect(subject).to(
|
||||
contain_exactly(
|
||||
hash_including(
|
||||
'user_id' => project.namespace.owner.id,
|
||||
'access_level' => Gitlab::Access::MAINTAINER
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -127,11 +127,19 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
end
|
||||
end
|
||||
|
||||
context 'the response is 202 accepted' do
|
||||
let(:response) { double(code: 202, parsed_response: :foo) }
|
||||
|
||||
it 'yields to the block' do
|
||||
expect(processed).to eq [:data, :foo]
|
||||
end
|
||||
end
|
||||
|
||||
context 'the response is 400 bad request' do
|
||||
let(:response) { double(code: 400, parsed_response: errors) }
|
||||
|
||||
it 'extracts the errors messages' do
|
||||
expect(processed).to eq('errorMessages' => %w(X Y))
|
||||
expect(processed).to eq('errorMessages' => %w(X Y), 'responseCode' => 400)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -139,7 +147,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
let(:response) { double(code: 401, parsed_response: nil) }
|
||||
|
||||
it 'reports that our JWT is wrong' do
|
||||
expect(processed).to eq('errorMessages' => ['Invalid JWT'])
|
||||
expect(processed).to eq('errorMessages' => ['Invalid JWT'], 'responseCode' => 401)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -147,7 +155,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
let(:response) { double(code: 403, parsed_response: nil) }
|
||||
|
||||
it 'reports that the App is misconfigured' do
|
||||
expect(processed).to eq('errorMessages' => ['App does not support foo'])
|
||||
expect(processed).to eq('errorMessages' => ['App does not support foo'], 'responseCode' => 403)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -155,7 +163,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
let(:response) { double(code: 413, parsed_response: errors) }
|
||||
|
||||
it 'extracts the errors messages' do
|
||||
expect(processed).to eq('errorMessages' => ['Data too large', 'X', 'Y'])
|
||||
expect(processed).to eq('errorMessages' => ['Data too large', 'X', 'Y'], 'responseCode' => 413)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -163,7 +171,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
let(:response) { double(code: 429, parsed_response: nil) }
|
||||
|
||||
it 'reports that we exceeded the rate limit' do
|
||||
expect(processed).to eq('errorMessages' => ['Rate limit exceeded'])
|
||||
expect(processed).to eq('errorMessages' => ['Rate limit exceeded'], 'responseCode' => 429)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -171,7 +179,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
let(:response) { double(code: 503, parsed_response: nil) }
|
||||
|
||||
it 'reports that the service is unavailable' do
|
||||
expect(processed).to eq('errorMessages' => ['Service unavailable'])
|
||||
expect(processed).to eq('errorMessages' => ['Service unavailable'], 'responseCode' => 503)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -179,7 +187,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
|
|||
let(:response) { double(code: 1000, parsed_response: :something) }
|
||||
|
||||
it 'reports that this was unanticipated' do
|
||||
expect(processed).to eq('errorMessages' => ['Unknown error'], 'response' => :something)
|
||||
expect(processed).to eq('errorMessages' => ['Unknown error'], 'responseCode' => 1000, 'response' => :something)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,28 +34,12 @@ RSpec.describe Gitlab::ProjectAuthorizations do
|
|||
.to include(owned_project.id, other_project.id, group_project.id)
|
||||
end
|
||||
|
||||
context 'when personal_project_owner_with_owner_access feature flag is enabled' do
|
||||
it 'includes the correct access levels' do
|
||||
mapping = map_access_levels(authorizations)
|
||||
it 'includes the correct access levels' do
|
||||
mapping = map_access_levels(authorizations)
|
||||
|
||||
expect(mapping[owned_project.id]).to eq(Gitlab::Access::OWNER)
|
||||
expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
|
||||
expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when personal_project_owner_with_owner_access feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(personal_project_owner_with_owner_access: false)
|
||||
end
|
||||
|
||||
it 'includes the correct access levels' do
|
||||
mapping = map_access_levels(authorizations)
|
||||
|
||||
expect(mapping[owned_project.id]).to eq(Gitlab::Access::MAINTAINER)
|
||||
expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
|
||||
expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
|
||||
end
|
||||
expect(mapping[owned_project.id]).to eq(Gitlab::Access::OWNER)
|
||||
expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
|
||||
expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -675,30 +675,13 @@ RSpec.describe API::Members do
|
|||
end
|
||||
|
||||
context 'adding owner to project' do
|
||||
context 'when personal_project_owner_with_owner_access feature flag is enabled' do
|
||||
it 'returns created status' do
|
||||
expect do
|
||||
post api("/projects/#{project.id}/members", maintainer),
|
||||
params: { user_id: stranger.id, access_level: Member::OWNER }
|
||||
it 'returns created status' do
|
||||
expect do
|
||||
post api("/projects/#{project.id}/members", maintainer),
|
||||
params: { user_id: stranger.id, access_level: Member::OWNER }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
end.to change { project.members.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when personal_project_owner_with_owner_access feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(personal_project_owner_with_owner_access: false)
|
||||
end
|
||||
|
||||
it 'returns created status' do
|
||||
expect do
|
||||
post api("/projects/#{project.id}/members", maintainer),
|
||||
params: { user_id: stranger.id, access_level: Member::OWNER }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end.not_to change { project.members.count }
|
||||
end
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
end.to change { project.members.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -116,34 +116,15 @@ RSpec.describe Projects::CreateService, '#execute' do
|
|||
end
|
||||
|
||||
context 'user namespace' do
|
||||
context 'when personal_project_owner_with_owner_access feature flag is enabled' do
|
||||
it 'creates a project in user namespace' do
|
||||
project = create_project(user, opts)
|
||||
it 'creates a project in user namespace' do
|
||||
project = create_project(user, opts)
|
||||
|
||||
expect(project).to be_valid
|
||||
expect(project.first_owner).to eq(user)
|
||||
expect(project.team.maintainers).not_to include(user)
|
||||
expect(project.team.owners).to contain_exactly(user)
|
||||
expect(project.namespace).to eq(user.namespace)
|
||||
expect(project.project_namespace).to be_in_sync_with_project(project)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when personal_project_owner_with_owner_access feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(personal_project_owner_with_owner_access: false)
|
||||
end
|
||||
|
||||
it 'creates a project in user namespace' do
|
||||
project = create_project(user, opts)
|
||||
|
||||
expect(project).to be_valid
|
||||
expect(project.first_owner).to eq(user)
|
||||
expect(project.team.maintainers).to contain_exactly(user)
|
||||
expect(project.team.owners).to contain_exactly(user)
|
||||
expect(project.namespace).to eq(user.namespace)
|
||||
expect(project.project_namespace).to be_in_sync_with_project(project)
|
||||
end
|
||||
expect(project).to be_valid
|
||||
expect(project.first_owner).to eq(user)
|
||||
expect(project.team.maintainers).not_to include(user)
|
||||
expect(project.team.owners).to contain_exactly(user)
|
||||
expect(project.namespace).to eq(user.namespace)
|
||||
expect(project.project_namespace).to be_in_sync_with_project(project)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue