Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-17 06:08:15 +00:00
parent 80816914ff
commit e4476c4a18
20 changed files with 288 additions and 63 deletions

View File

@ -80,10 +80,10 @@ export default {
<template>
<div class="ide-commit-list-container">
<header class="multi-file-commit-panel-header d-flex mb-0">
<div class="d-flex align-items-center flex-fill">
<header class="multi-file-commit-panel-header gl-display-flex gl-mb-0">
<div class="gl-display-flex gl-align-items-center flex-fill">
<strong> {{ titleText }} </strong>
<div class="d-flex ml-auto">
<div class="gl-display-flex gl-ml-auto">
<gl-button
v-if="!stagedList"
v-gl-tooltip
@ -114,7 +114,7 @@ export default {
/>
</li>
</ul>
<p v-else class="multi-file-commit-list form-text text-muted text-center">
<p v-else class="multi-file-commit-list form-text gl-text-gray-600 gl-text-center">
{{ emptyStateText }}
</p>
<gl-modal

View File

@ -75,25 +75,25 @@ export default {
<span class="gl-font-weight-bold gl-w-15 gl-pt-2" data-testid="assignees-title">{{
__('Assignee(s)')
}}</span>
<!-- TODO: Remove this div when https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2872 is merged -->
<div
v-if="assigneeListEmpty && !isEditing"
class="add-assignees gl-min-w-fit-content gl-absolute gl-display-flex gl-align-items-center gl-text-gray-300 gl-pr-4 gl-top-2 gl-z-index-0"
data-testid="empty-state"
>
<gl-icon name="profile" />
<span class="gl-ml-2">{{ __('Add assignees') }}</span>
</div>
<gl-token-selector
ref="tokenSelector"
v-model="localAssignees"
hide-dropdown-with-no-items
:container-class="containerClass"
class="gl-w-full gl-border gl-border-white gl-hover-border-gray-200 gl-rounded-base gl-z-index-1 gl-bg-transparent!"
class="gl-w-full gl-border gl-border-white gl-hover-border-gray-200 gl-rounded-base"
@token-remove="focusTokenSelector"
@focus="isEditing = true"
@blur="setAssignees"
>
<template #empty-placeholder>
<div
class="add-assignees gl-min-w-fit-content gl-display-flex gl-align-items-center gl-text-gray-300 gl-pr-4 gl-top-2"
data-testid="empty-state"
>
<gl-icon name="profile" />
<span class="gl-ml-2">{{ __('Add assignees') }}</span>
</div>
</template>
<template #token-content="{ token }">
<gl-link
:href="token.webUrl"
@ -109,10 +109,3 @@ export default {
</gl-token-selector>
</div>
</template>
<style lang="scss">
/* TODO: Remove style block when https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2872 is merged */
.work-item-assignees .add-assignees {
left: 7.5rem;
}
</style>

View File

@ -17,12 +17,7 @@ module Projects
private
def packages_and_registries_settings_enabled!
render_404 unless can_destroy_container_registry_image?(project)
end
def can_destroy_container_registry_image?(project)
Gitlab.config.registry.enabled &&
can?(current_user, :destroy_container_image, project)
render_404 unless can?(current_user, :view_package_registry_project_settings, project)
end
end
end

View File

@ -7,7 +7,7 @@ module Types
class JobType < BaseObject
graphql_name 'CiJob'
connection_type_class(Types::CountableConnectionType)
connection_type_class(Types::LimitedCountableConnectionType)
expose_permissions Types::PermissionTypes::Ci::Job

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class LimitedCountableConnectionType < GraphQL::Types::Relay::BaseConnection
COUNT_LIMIT = 1000
COUNT_DESCRIPTION = "Limited count of collection. Returns limit + 1 for counts greater than the limit."
field :count, GraphQL::Types::Int, null: false, description: COUNT_DESCRIPTION do
argument :limit, GraphQL::Types::Int,
required: false, default_value: COUNT_LIMIT,
validates: { numericality: { greater_than: 0, less_than_or_equal_to: COUNT_LIMIT } },
description: "Limit value to be applied to the count query. Default is 1000."
end
def count(limit:)
relation = object.items
if relation.respond_to?(:page)
relation.page.total_count_with_limit(:all, limit: limit)
else
[relation.size, limit.next].min
end
end
end
end

View File

@ -203,6 +203,10 @@ class ProjectPolicy < BasePolicy
Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?('project')
end
condition :registry_enabled do
Gitlab.config.registry.enabled
end
# `:read_project` may be prevented in EE, but `:read_project_for_iids` should
# not.
rule { guest | admin }.enable :read_project_for_iids
@ -760,6 +764,10 @@ class ProjectPolicy < BasePolicy
enable :import_project_members_from_another_project
end
rule { registry_enabled & can?(:admin_container_image) }.policy do
enable :view_package_registry_project_settings
end
private
def user_is_user?

View File

@ -8,7 +8,7 @@ module TwoFactor
result = disable_two_factor
notification_service.disabled_two_factor(user) if result[:status] == :success
notify_on_success(user) if result[:status] == :success
result
end
@ -20,5 +20,11 @@ module TwoFactor
user.disable_two_factor!
end
end
def notify_on_success(user)
notification_service.disabled_two_factor(user)
end
end
end
TwoFactor::DestroyService.prepend_mod_with('TwoFactor::DestroyService')

View File

@ -43,7 +43,7 @@
= message.target_path
%td
= message.broadcast_type.capitalize
%td.gl-white-space-nowrap
%td.gl-white-space-nowrap<
= link_to sprite_icon('pencil', css_class: 'gl-icon'), edit_admin_broadcast_message_path(message), title: _('Edit'), class: 'btn btn-icon gl-button'
= link_to sprite_icon('remove', css_class: 'gl-icon'), admin_broadcast_message_path(message), method: :delete, remote: true, title: _('Remove'), class: 'js-remove-tr btn btn-icon gl-button btn-danger ml-2'
= link_to sprite_icon('remove', css_class: 'gl-icon'), admin_broadcast_message_path(message), method: :delete, remote: true, title: _('Remove'), class: 'js-remove-tr btn btn-icon gl-button btn-danger gl-ml-3'
= paginate @broadcast_messages, theme: 'gitlab'

View File

@ -1,8 +0,0 @@
---
name: omit_epic_subscribed
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86016
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/360663
milestone: '15.0'
type: development
group: group::product planning
default_enabled: true

View File

@ -166,6 +166,18 @@ mutation {
}
```
### Delete with the API
Group owners can remove a HTTP header using the GraphQL `auditEventsStreamingHeadersDestroy` mutation.
```graphql
mutation {
auditEventsStreamingHeadersDestroy(input: { headerId: "gid://gitlab/AuditEvents::ExternalAuditEventDestination/24601" }) {
errors
}
}
```
The header is created if the returned `errors` object is empty.
## Verify event authenticity

View File

@ -234,6 +234,7 @@ The following user actions are recorded:
- Administrator added or removed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/323905) in GitLab 14.1)
- Removed SSH key ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) in GitLab 14.1)
- Added or removed GPG key ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) in GitLab 14.1)
- A user's two-factor authentication was disabled ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238177) in GitLab 15.1)
Instance events can also be accessed via the [Instance Audit Events API](../api/audit_events.md#instance-audit-events).

View File

@ -738,6 +738,24 @@ Input type: `AuditEventsStreamingHeadersCreateInput`
| <a id="mutationauditeventsstreamingheaderscreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationauditeventsstreamingheaderscreateheader"></a>`header` | [`AuditEventStreamingHeader`](#auditeventstreamingheader) | Created header. |
### `Mutation.auditEventsStreamingHeadersDestroy`
Input type: `AuditEventsStreamingHeadersDestroyInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationauditeventsstreamingheadersdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationauditeventsstreamingheadersdestroyheaderid"></a>`headerId` | [`AuditEventsStreamingHeaderID!`](#auditeventsstreamingheaderid) | Header to delete. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationauditeventsstreamingheadersdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationauditeventsstreamingheadersdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.awardEmojiAdd`
Input type: `AwardEmojiAddInput`
@ -6033,11 +6051,24 @@ The connection type for [`CiJob`](#cijob).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="cijobconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
| <a id="cijobconnectionedges"></a>`edges` | [`[CiJobEdge]`](#cijobedge) | A list of edges. |
| <a id="cijobconnectionnodes"></a>`nodes` | [`[CiJob]`](#cijob) | A list of nodes. |
| <a id="cijobconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
##### Fields with arguments
###### `CiJobConnection.count`
Limited count of collection. Returns limit + 1 for counts greater than the limit.
Returns [`Int!`](#int).
####### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="cijobconnectioncountlimit"></a>`limit` | [`Int`](#int) | Limit value to be applied to the count query. Default is 1000. |
#### `CiJobEdge`
The edge type for [`CiJob`](#cijob).
@ -20079,6 +20110,12 @@ A `AuditEventsExternalAuditEventDestinationID` is a global ID. It is encoded as
An example `AuditEventsExternalAuditEventDestinationID` is: `"gid://gitlab/AuditEvents::ExternalAuditEventDestination/1"`.
### `AuditEventsStreamingHeaderID`
A `AuditEventsStreamingHeaderID` is a global ID. It is encoded as a string.
An example `AuditEventsStreamingHeaderID` is: `"gid://gitlab/AuditEvents::Streaming::Header/1"`.
### `AwardableID`
A `AwardableID` is a global ID. It is encoded as a string.

View File

@ -242,6 +242,10 @@ Change a file in the project and see if it's reflected in the demo application o
Congratulations! You successfully set up continuous deployment to ECS.
NOTE:
ECS deploy jobs wait for the rollout to complete before exiting. To disable this behavior,
set `CI_AWS_ECS_WAIT_FOR_ROLLOUT_COMPLETE_DISABLED` to a non-empty value.
## Further reading
- If you're interested in more of the continuous deployments to clouds, see [cloud deployments](../index.md).

View File

@ -124,6 +124,10 @@ Finally, your AWS ECS service is updated with the new revision of the
task definition, making the cluster pull the newest version of your
application.
NOTE:
ECS deploy jobs wait for the rollout to complete before exiting. To disable this behavior,
set `CI_AWS_ECS_WAIT_FOR_ROLLOUT_COMPLETE_DISABLED` to a non-empty value.
WARNING:
The [`AWS/Deploy-ECS.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml)
template includes two templates: [`Jobs/Build.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml)

View File

@ -118,6 +118,25 @@ create or update pipelines until their email address is confirmed.
You can [change](../../../security/password_length_limits.md#modify-minimum-password-length-using-gitlab-ui)
the minimum number of characters a user must have in their password using the GitLab UI.
### Password complexity requirements **(PREMIUM SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/354965) in GitLab 15.1.
By default, the only requirement for user passwords is [minimum password length](#minimum-password-length-limit).
You can add additional complexity requirements. Changes to password complexity requirements apply to new passwords:
- For new users that sign up.
- For existing users that reset their password.
Existing passwords are unaffected. To change password complexity requirements:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Sign-up restrictions**.
1. Under **Minimum password length (number of characters)**, select additional password complexity requirements. You can require numbers, uppercase letters, lowercase letters,
and symbols.
1. Select **Save changes**.
## Allow or deny sign ups using specific email domains
You can specify an inclusive or exclusive list of email domains which can be used for user sign up.

View File

@ -104,8 +104,7 @@ module Sidebars
end
def packages_and_registries_menu_item
if !Gitlab.config.registry.enabled ||
!can?(context.current_user, :destroy_container_image, context.project)
unless can?(context.current_user, :view_package_registry_project_settings, context.project)
return ::Sidebars::NilMenuItem.new(item_id: :packages_and_registries)
end

View File

@ -60,32 +60,11 @@ describe('WorkItemAssignees component', () => {
expect(findAssigneeLinks().at(0).attributes('data-user-id')).toBe('1');
});
describe('when there are no assignees', () => {
beforeEach(() => {
createComponent({ assignees: [] });
});
it('should render empty state placeholder', () => {
expect(findEmptyState().exists()).toBe(true);
});
it('should hide empty state placeholder on focusing token selector', async () => {
findTokenSelector().vm.$emit('focus');
await nextTick();
expect(findEmptyState().exists()).toBe(false);
});
});
describe('when there are assignees', () => {
beforeEach(() => {
createComponent();
});
it('should not render empty state placeholder', () => {
expect(findEmptyState().exists()).toBe(false);
});
it('should focus token selector on token removal', async () => {
findTokenSelector().vm.$emit('token-remove', mockAssignees[0].id);
await nextTick();

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Types::LimitedCountableConnectionType do
it 'has the expected fields' do
expected_fields = %i[count page_info]
expect(described_class).to have_graphql_fields(*expected_fields)
end
end

View File

@ -1369,6 +1369,68 @@ RSpec.describe ProjectPolicy do
end
end
describe 'view_package_registry_project_settings' do
context 'with registry enabled' do
before do
stub_config(registry: { enabled: true })
end
context 'with an admin user' do
let(:current_user) { admin }
context 'when admin mode enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:view_package_registry_project_settings) }
end
context 'when admin mode disabled' do
it { is_expected.to be_disallowed(:view_package_registry_project_settings) }
end
end
%i[owner maintainer].each do |role|
context "with #{role}" do
let(:current_user) { public_send(role) }
it { is_expected.to be_allowed(:view_package_registry_project_settings) }
end
end
%i[developer reporter guest non_member anonymous].each do |role|
context "with #{role}" do
let(:current_user) { public_send(role) }
it { is_expected.to be_disallowed(:view_package_registry_project_settings) }
end
end
end
context 'with registry disabled' do
before do
stub_config(registry: { enabled: false })
end
context 'with admin user' do
let(:current_user) { admin }
context 'when admin mode enabled', :enable_admin_mode do
it { is_expected.to be_disallowed(:view_package_registry_project_settings) }
end
context 'when admin mode disabled' do
it { is_expected.to be_disallowed(:view_package_registry_project_settings) }
end
end
%i[owner maintainer developer reporter guest non_member anonymous].each do |role|
context "with #{role}" do
let(:current_user) { public_send(role) }
it { is_expected.to be_disallowed(:view_package_registry_project_settings) }
end
end
end
end
describe 'read_feature_flag' do
subject { described_class.new(current_user, project) }

View File

@ -258,4 +258,81 @@ RSpec.describe 'Query.project.pipeline' do
end
end
end
describe '.jobs.count' do
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
let_it_be(:successful_job) { create(:ci_build, :success, pipeline: pipeline) }
let_it_be(:pending_job) { create(:ci_build, :pending, pipeline: pipeline) }
let_it_be(:failed_job) { create(:ci_build, :failed, pipeline: pipeline) }
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
jobs {
count
}
}
}
}
)
end
before do
post_graphql(query, current_user: user)
end
it 'returns the number of jobs' do
expect(graphql_data_at(:project, :pipeline, :jobs, :count)).to eq(3)
end
context 'with limit value' do
let(:limit) { 1 }
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
jobs {
count(limit: #{limit})
}
}
}
}
)
end
it 'returns a limited number of jobs' do
expect(graphql_data_at(:project, :pipeline, :jobs, :count)).to eq(2)
end
context 'with invalid value' do
let(:limit) { 1500 }
it 'returns a validation error' do
expect(graphql_errors).to include(a_hash_including('message' => 'limit must be less than or equal to 1000'))
end
end
end
context 'with jobs filter' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
jobs(statuses: FAILED) {
count
}
}
}
)
end
it 'returns the number of failed jobs' do
expect(graphql_data_at(:project, :jobs, :count)).to eq(1)
end
end
end
end