Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c263b1fffc
commit
24b8d0f8cd
2
Gemfile
2
Gemfile
|
|
@ -575,7 +575,7 @@ gem 'mail-smtp_pool', '~> 0.1.0', path: 'vendor/gems/mail-smtp_pool', require: f
|
|||
gem 'microsoft_graph_mailer', '~> 0.1.0', path: 'vendor/gems/microsoft_graph_mailer'
|
||||
|
||||
# File encryption
|
||||
gem 'lockbox', '~> 1.1.1'
|
||||
gem 'lockbox', '~> 1.3.0'
|
||||
|
||||
# Email validation
|
||||
gem 'valid_email', '~> 0.1'
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@
|
|||
{"name":"listen","version":"3.7.1","platform":"ruby","checksum":"3b80caa7aa77fae836916c2f9e3fbcafbd15f5d695dd487c1f5b5e7e465efe29"},
|
||||
{"name":"llhttp-ffi","version":"0.4.0","platform":"ruby","checksum":"e5f7327db3cf8007e648342ef76347d6e0ae545a8402e519cca9c886eb37b001"},
|
||||
{"name":"locale","version":"2.1.3","platform":"ruby","checksum":"b6ddee011e157817cb98e521b3ce7cb626424d5882f1e844aafdee3e8b212725"},
|
||||
{"name":"lockbox","version":"1.1.1","platform":"ruby","checksum":"0af16b14c54f791c148615a0115387b51903d868c7fe622f49606c97071c2ac0"},
|
||||
{"name":"lockbox","version":"1.3.0","platform":"ruby","checksum":"ca8e5806e4e0c56d1d762ac5cf401940ff53fc37554ef623d3313c7a6331a3ea"},
|
||||
{"name":"lograge","version":"0.11.2","platform":"ruby","checksum":"4cbd1554b86f545d795eff15a0c24fd25057d2ac4e1caa5fc186168b3da932ef"},
|
||||
{"name":"loofah","version":"2.21.3","platform":"ruby","checksum":"43d21a8bb96c380199a8f66e0298649eaa7362fcd32f3a6114f39775e524e4dc"},
|
||||
{"name":"lookbook","version":"2.0.1","platform":"ruby","checksum":"0f14729c8c992810de0792a0be865a5792e5765fbaea5950cce74c6e5c73fc4a"},
|
||||
|
|
|
|||
|
|
@ -973,7 +973,7 @@ GEM
|
|||
ffi-compiler (~> 1.0)
|
||||
rake (~> 13.0)
|
||||
locale (2.1.3)
|
||||
lockbox (1.1.1)
|
||||
lockbox (1.3.0)
|
||||
lograge (0.11.2)
|
||||
actionpack (>= 4)
|
||||
activesupport (>= 4)
|
||||
|
|
@ -1892,7 +1892,7 @@ DEPENDENCIES
|
|||
license_finder (~> 7.0)
|
||||
licensee (~> 9.16)
|
||||
listen (~> 3.7)
|
||||
lockbox (~> 1.1.1)
|
||||
lockbox (~> 1.3.0)
|
||||
lograge (~> 0.5)
|
||||
loofah (~> 2.21.3)
|
||||
lookbook (~> 2.0, >= 2.0.1)
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
#import "~/graphql_shared/fragments/user.fragment.graphql"
|
||||
|
||||
query GroupBoardMembers($fullPath: ID!, $search: String) {
|
||||
workspace: group(fullPath: $fullPath) {
|
||||
id
|
||||
assignees: groupMembers(search: $search, relations: [DIRECT, DESCENDANTS, INHERITED]) {
|
||||
nodes {
|
||||
id
|
||||
user {
|
||||
...User
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#import "~/graphql_shared/fragments/user.fragment.graphql"
|
||||
|
||||
query ProjectBoardMembers($fullPath: ID!, $search: String) {
|
||||
workspace: project(fullPath: $fullPath) {
|
||||
id
|
||||
assignees: projectMembers(search: $search) {
|
||||
nodes {
|
||||
id
|
||||
user {
|
||||
...User
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
import { BoardType } from 'ee_else_ce/boards/constants';
|
||||
import groupBoardMembers from '~/boards/graphql/group_board_members.query.graphql';
|
||||
import projectBoardMembers from '~/boards/graphql/project_board_members.query.graphql';
|
||||
import usersAutocompleteQuery from '~/graphql_shared/queries/users_autocomplete.query.graphql';
|
||||
import groupBoardMilestonesQuery from './graphql/group_board_milestones.query.graphql';
|
||||
import projectBoardMilestonesQuery from './graphql/project_board_milestones.query.graphql';
|
||||
|
|
@ -11,31 +9,15 @@ export default function issueBoardFilters(apollo, fullPath, isGroupBoard) {
|
|||
return isGroupBoard ? data.group?.labels.nodes || [] : data.project?.labels.nodes || [];
|
||||
};
|
||||
|
||||
const boardAssigneesQuery = () => {
|
||||
return isGroupBoard ? groupBoardMembers : projectBoardMembers;
|
||||
};
|
||||
|
||||
const fetchUsers = (usersSearchTerm) => {
|
||||
if (gon.features?.newGraphqlUsersAutocomplete) {
|
||||
const namespace = isGroupBoard ? BoardType.group : BoardType.project;
|
||||
|
||||
return apollo
|
||||
.query({
|
||||
query: usersAutocompleteQuery,
|
||||
variables: { fullPath, search: usersSearchTerm, isProject: !isGroupBoard },
|
||||
})
|
||||
.then(({ data }) => data[namespace]?.autocompleteUsers);
|
||||
}
|
||||
const namespace = isGroupBoard ? BoardType.group : BoardType.project;
|
||||
|
||||
return apollo
|
||||
.query({
|
||||
query: boardAssigneesQuery(),
|
||||
variables: {
|
||||
fullPath,
|
||||
search: usersSearchTerm,
|
||||
},
|
||||
query: usersAutocompleteQuery,
|
||||
variables: { fullPath, search: usersSearchTerm, isProject: !isGroupBoard },
|
||||
})
|
||||
.then(({ data }) => data.workspace?.assignees.nodes.map(({ user }) => user));
|
||||
.then(({ data }) => data[namespace]?.autocompleteUsers);
|
||||
};
|
||||
|
||||
const fetchLabels = (labelSearchTerm) => {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ import eventHub from '../eventhub';
|
|||
import reorderIssuesMutation from '../queries/reorder_issues.mutation.graphql';
|
||||
import searchLabelsQuery from '../queries/search_labels.query.graphql';
|
||||
import searchMilestonesQuery from '../queries/search_milestones.query.graphql';
|
||||
import searchUsersQuery from '../queries/search_users.query.graphql';
|
||||
import setSortPreferenceMutation from '../queries/set_sort_preference.mutation.graphql';
|
||||
import {
|
||||
convertToApiParams,
|
||||
|
|
@ -649,23 +648,12 @@ export default {
|
|||
.then(({ data }) => data[this.namespace]?.milestones.nodes);
|
||||
},
|
||||
fetchUsers(search) {
|
||||
if (gon.features?.newGraphqlUsersAutocomplete) {
|
||||
return this.$apollo
|
||||
.query({
|
||||
query: usersAutocompleteQuery,
|
||||
variables: { fullPath: this.fullPath, search, isProject: this.isProject },
|
||||
})
|
||||
.then(({ data }) => data[this.namespace]?.autocompleteUsers);
|
||||
}
|
||||
|
||||
return this.$apollo
|
||||
.query({
|
||||
query: searchUsersQuery,
|
||||
query: usersAutocompleteQuery,
|
||||
variables: { fullPath: this.fullPath, search, isProject: this.isProject },
|
||||
})
|
||||
.then(({ data }) =>
|
||||
data[this.namespace]?.[`${this.namespace}Members`].nodes.map((member) => member.user),
|
||||
);
|
||||
.then(({ data }) => data[this.namespace]?.autocompleteUsers);
|
||||
},
|
||||
getExportCsvPathWithQuery() {
|
||||
return `${this.exportCsvPath}${window.location.search}`;
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
#import "./user.fragment.graphql"
|
||||
|
||||
query searchUsers($fullPath: ID!, $search: String, $isProject: Boolean = false) {
|
||||
group(fullPath: $fullPath) @skip(if: $isProject) {
|
||||
id
|
||||
groupMembers(search: $search, relations: [DIRECT, INHERITED, SHARED_FROM_GROUPS]) {
|
||||
nodes {
|
||||
id
|
||||
user {
|
||||
...User
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
project(fullPath: $fullPath) @include(if: $isProject) {
|
||||
id
|
||||
projectMembers(
|
||||
search: $search
|
||||
relations: [DIRECT, INHERITED, INVITED_GROUPS, SHARED_INTO_ANCESTORS]
|
||||
) {
|
||||
nodes {
|
||||
id
|
||||
user {
|
||||
...User
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
fragment User on User {
|
||||
id
|
||||
avatarUrl
|
||||
name
|
||||
username
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ class Groups::BoardsController < Groups::ApplicationController
|
|||
before_action do
|
||||
push_frontend_feature_flag(:board_multi_select, group)
|
||||
push_frontend_feature_flag(:apollo_boards, group)
|
||||
push_frontend_feature_flag(:new_graphql_users_autocomplete, group)
|
||||
experiment(:prominent_create_board_btn, subject: current_user) do |e|
|
||||
e.control {}
|
||||
e.candidate {}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ class GroupsController < Groups::ApplicationController
|
|||
push_frontend_feature_flag(:frontend_caching, group)
|
||||
push_force_frontend_feature_flag(:work_items, group.work_items_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:issues_grid_view)
|
||||
push_frontend_feature_flag(:new_graphql_users_autocomplete, group)
|
||||
end
|
||||
|
||||
before_action only: :merge_requests do
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ class Projects::BoardsController < Projects::ApplicationController
|
|||
before_action do
|
||||
push_frontend_feature_flag(:board_multi_select, project)
|
||||
push_frontend_feature_flag(:apollo_boards, project)
|
||||
push_frontend_feature_flag(:new_graphql_users_autocomplete, project)
|
||||
experiment(:prominent_create_board_btn, subject: current_user) do |e|
|
||||
e.control {}
|
||||
e.candidate {}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
before_action only: [:index, :service_desk] do
|
||||
push_frontend_feature_flag(:or_issuable_queries, project)
|
||||
push_frontend_feature_flag(:frontend_caching, project&.group)
|
||||
push_frontend_feature_flag(:new_graphql_users_autocomplete, project)
|
||||
end
|
||||
|
||||
before_action only: :show do
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class MergeRequest < ApplicationRecord
|
|||
belongs_to :latest_merge_request_diff, class_name: 'MergeRequestDiff'
|
||||
manual_inverse_association :latest_merge_request_diff, :merge_request
|
||||
|
||||
# method overriden in EE
|
||||
# method overridden in EE
|
||||
def suggested_reviewer_users
|
||||
User.none
|
||||
end
|
||||
|
|
@ -162,7 +162,7 @@ class MergeRequest < ApplicationRecord
|
|||
|
||||
# Keep states definition to be evaluated before the state_machine block to
|
||||
# avoid spec failures. If this gets evaluated after, the `merged` and `locked`
|
||||
# states (which are overriden) can be nil.
|
||||
# states (which are overridden) can be nil.
|
||||
#
|
||||
def self.available_state_names
|
||||
super + [:merged, :locked]
|
||||
|
|
|
|||
|
|
@ -5,8 +5,12 @@ module Ci
|
|||
include Ci::DeployablePolicy
|
||||
|
||||
condition(:can_update_downstream_branch) do
|
||||
::Gitlab::UserAccess.new(@user, container: @subject.downstream_project)
|
||||
.can_update_branch?(@subject.target_revision_ref)
|
||||
# `bridge.downstream_project` could be `nil` if the downstream project was removed after the pipeline creation,
|
||||
# which raises an error in `UserAccess` class because `container` arg must be present.
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/424145 for more information.
|
||||
@subject.downstream_project.present? &&
|
||||
::Gitlab::UserAccess.new(@user, container: @subject.downstream_project)
|
||||
.can_update_branch?(@subject.target_revision_ref)
|
||||
end
|
||||
|
||||
rule { can_update_downstream_branch }.enable :play_job
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: new_graphql_users_autocomplete
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129348
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/417757
|
||||
milestone: '16.3'
|
||||
name: use_merge_approval_rules_when_merged
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129165
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/422380
|
||||
milestone: '16.4'
|
||||
type: development
|
||||
group: group::project management
|
||||
group: group::code review
|
||||
default_enabled: false
|
||||
|
|
@ -65,19 +65,23 @@ This error occurs when you use an activation code to activate your instance, but
|
|||
|
||||
You may have connectivity issues due to the following reasons:
|
||||
|
||||
- **You have an offline environment**:
|
||||
- Configure your setup to allow connection to GitLab servers. If connection to GitLab servers is not possible, contact your Sales Representative to request a license key. You can also contact [GitLab support](https://about.gitlab.com/support/#contact-support) if you need help finding your Sales Representative.
|
||||
- **Customers Portal is not operational**:
|
||||
- To check for performance or service disruptions, check the Customers Portal [status](https://status.gitlab.com/).
|
||||
- **Firewall settings**:
|
||||
- Check if your GitLab instance has an encrypted connection to `customers.gitlab.com` (with IP addresses 172.64.146.11 and 104.18.41.245) on port 443:
|
||||
- Confirm that GitLab instance can establish an encrypted connection to `https://customers.gitlab.com` on port 443.
|
||||
Note: IP addresses for `https://customers.gitlab.com` are 172.64.146.11 and 104.18.41.245)
|
||||
|
||||
```shell
|
||||
curl --verbose "https://customers.gitlab.com/"
|
||||
```
|
||||
```
|
||||
|
||||
- If the curl command returns a failure, either:
|
||||
- If the curl command returns an error, either:
|
||||
- [Configure a proxy](https://docs.gitlab.com/omnibus/settings/environment-variables.html) in `gitlab.rb` to point to your server.
|
||||
- Contact your network administrator to make changes to the proxy.
|
||||
- If an SSL inspection appliance is used, you must add the appliance's root CA certificate to `/etc/gitlab/trusted-certs` on the server, then run `gitlab-ctl reconfigure`.
|
||||
|
||||
- Contact your network administrator to make changes to an existing proxy or firewall.
|
||||
- If an SSL inspection appliance is used, you must add the appliance's root CA certificate to `/etc/gitlab/trusted-certs` on your instance, then run `gitlab-ctl reconfigure`.
|
||||
|
||||
- **Customers Portal is not operational**:
|
||||
- Check for any active disruptions to the Customers Portal on [status](https://status.gitlab.com/).
|
||||
|
||||
- **You have an offline environment**:
|
||||
- If you are unable to configure your setup to allow connection to GitLab servers, contact your Sales Representative to request an [Offline license](https://about.gitlab.com/pricing/licensing-faq/cloud-licensing/#what-is-an-offline-cloud-license).
|
||||
|
||||
For assistance finding your sales representative you can contact [GitLab support](https://about.gitlab.com/support/#contact-support).
|
||||
|
|
|
|||
|
|
@ -210,21 +210,6 @@ RSpec.describe 'Issue board filters', :js, feature_category: :team_planning do
|
|||
|
||||
expect(page).to have_css('.gl-filtered-search-suggestion', text: child_project_member.name)
|
||||
end
|
||||
|
||||
context 'when new_graphql_users_autocomplete is disabled' do
|
||||
before do
|
||||
stub_feature_flags(new_graphql_users_autocomplete: false)
|
||||
end
|
||||
|
||||
it 'does not include descendant project members in autocomplete' do
|
||||
visit group_board_path(group, board)
|
||||
wait_for_requests
|
||||
|
||||
set_filter('assignee')
|
||||
|
||||
expect(page).not_to have_css('.gl-filtered-search-suggestion', text: child_project_member.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -113,33 +113,5 @@ RSpec.describe 'Dropdown assignee', :js, feature_category: :team_planning do
|
|||
expect(page).to have_text invited_to_group_group_user.name
|
||||
expect(page).not_to have_text subsubgroup_user.name
|
||||
end
|
||||
|
||||
context 'when new_graphql_users_autocomplete is disabled' do
|
||||
before do
|
||||
stub_feature_flags(new_graphql_users_autocomplete: false)
|
||||
end
|
||||
|
||||
it 'shows inherited, direct, and invited group members but not descendent members', :aggregate_failures do
|
||||
visit issues_group_path(subgroup)
|
||||
|
||||
select_tokens 'Assignee', '='
|
||||
|
||||
expect(page).to have_text group_user.name
|
||||
expect(page).to have_text subgroup_user.name
|
||||
expect(page).to have_text invited_to_group_group_user.name
|
||||
expect(page).not_to have_text subsubgroup_user.name
|
||||
expect(page).not_to have_text invited_to_project_group_user.name
|
||||
|
||||
visit project_issues_path(subgroup_project)
|
||||
|
||||
select_tokens 'Assignee', '='
|
||||
|
||||
expect(page).to have_text group_user.name
|
||||
expect(page).to have_text subgroup_user.name
|
||||
expect(page).to have_text invited_to_project_group_user.name
|
||||
expect(page).to have_text invited_to_group_group_user.name
|
||||
expect(page).not_to have_text subsubgroup_user.name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,22 +16,34 @@ RSpec.describe Ci::BridgePolicy do
|
|||
it_behaves_like 'a deployable job policy', :ci_bridge
|
||||
|
||||
describe '#play_job' do
|
||||
before do
|
||||
fake_access = double('Gitlab::UserAccess')
|
||||
expect(fake_access).to receive(:can_update_branch?).with('master').and_return(can_update_branch)
|
||||
expect(Gitlab::UserAccess).to receive(:new).with(user, container: downstream_project).and_return(fake_access)
|
||||
end
|
||||
context 'when downstream project exists' do
|
||||
before do
|
||||
fake_access = double('Gitlab::UserAccess')
|
||||
expect(fake_access).to receive(:can_update_branch?).with('master').and_return(can_update_branch)
|
||||
expect(Gitlab::UserAccess).to receive(:new).with(user, container: downstream_project).and_return(fake_access)
|
||||
end
|
||||
|
||||
context 'when user can update the downstream branch' do
|
||||
let(:can_update_branch) { true }
|
||||
context 'when user can update the downstream branch' do
|
||||
let(:can_update_branch) { true }
|
||||
|
||||
it 'allows' do
|
||||
expect(policy).to be_allowed :play_job
|
||||
it 'allows' do
|
||||
expect(policy).to be_allowed :play_job
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user can not update the downstream branch' do
|
||||
let(:can_update_branch) { false }
|
||||
|
||||
it 'does not allow' do
|
||||
expect(policy).not_to be_allowed :play_job
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user can not update the downstream branch' do
|
||||
let(:can_update_branch) { false }
|
||||
context 'when downstream project does not exist' do
|
||||
before do
|
||||
bridge.update!(options: { trigger: { project: 'deleted-project' } })
|
||||
end
|
||||
|
||||
it 'does not allow' do
|
||||
expect(policy).not_to be_allowed :play_job
|
||||
|
|
|
|||
Loading…
Reference in New Issue