Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d440531cf8
commit
d690a8d62b
|
@ -117,6 +117,7 @@ export default {
|
|||
v-if="displayFilters"
|
||||
id="discussion-filter-dropdown"
|
||||
class="gl-mr-3 full-width-mobile discussion-filter-container js-discussion-filter-container qa-discussion-filter"
|
||||
data-qa-selector="discussion_filter_dropdown"
|
||||
:text="currentFilter.title"
|
||||
>
|
||||
<div v-for="filter in filters" :key="filter.value" class="dropdown-item-wrapper">
|
||||
|
@ -125,7 +126,7 @@ export default {
|
|||
:is-checked="filter.value === currentValue"
|
||||
:class="{ 'is-active': filter.value === currentValue }"
|
||||
:data-filter-type="filterType(filter.value)"
|
||||
class="qa-filter-options"
|
||||
data-qa-selector="filter_menu_item"
|
||||
@click.prevent="selectFilter(filter.value)"
|
||||
>
|
||||
{{ filter.title }}
|
||||
|
|
|
@ -33,7 +33,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<li class="timeline-entry note note-wrapper discussion-filter-note js-discussion-filter-note">
|
||||
<li
|
||||
class="timeline-entry note note-wrapper discussion-filter-note js-discussion-filter-note"
|
||||
data-qa-selector="discussion_filter_container"
|
||||
>
|
||||
<div class="timeline-icon d-none d-lg-flex">
|
||||
<gl-icon name="comment" />
|
||||
</div>
|
||||
|
|
|
@ -170,7 +170,9 @@ export default {
|
|||
</template>
|
||||
<span v-else>{{ __('A deleted user') }}</span>
|
||||
<span class="note-headline-light note-headline-meta">
|
||||
<span class="system-note-message"> <slot></slot> </span>
|
||||
<span class="system-note-message" data-qa-selector="system_note_content">
|
||||
<slot></slot>
|
||||
</span>
|
||||
<template v-if="createdAt">
|
||||
<span ref="actionText" class="system-note-separator">
|
||||
<template v-if="actionText">{{ actionText }}</template>
|
||||
|
|
|
@ -353,7 +353,8 @@ export default {
|
|||
:class="classNameBindings"
|
||||
:data-award-url="note.toggle_award_path"
|
||||
:data-note-id="note.id"
|
||||
class="note note-wrapper qa-noteable-note-item"
|
||||
class="note note-wrapper"
|
||||
data-qa-selector="noteable_note_container"
|
||||
>
|
||||
<div
|
||||
v-if="showMultiLineComment"
|
||||
|
|
|
@ -117,8 +117,9 @@ export default {
|
|||
const errorMessage = data?.updateContainerExpirationPolicy?.errors[0];
|
||||
if (errorMessage) {
|
||||
this.$toast.show(errorMessage, { type: 'error' });
|
||||
} else {
|
||||
this.$toast.show(UPDATE_SETTINGS_SUCCESS_MESSAGE, { type: 'success' });
|
||||
}
|
||||
this.$toast.show(UPDATE_SETTINGS_SUCCESS_MESSAGE, { type: 'success' });
|
||||
})
|
||||
.catch(error => {
|
||||
this.setApiErrors(error);
|
||||
|
|
|
@ -32,7 +32,7 @@ export const KEEP_N_LABEL = s__('ContainerRegistry|Number of tags to retain:');
|
|||
export const NAME_REGEX_LABEL = s__(
|
||||
'ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}',
|
||||
);
|
||||
export const NAME_REGEX_PLACEHOLDER = '.*';
|
||||
export const NAME_REGEX_PLACEHOLDER = '';
|
||||
export const NAME_REGEX_DESCRIPTION = s__(
|
||||
'ContainerRegistry|Wildcards such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}',
|
||||
);
|
||||
|
|
|
@ -97,7 +97,11 @@ export default {
|
|||
class="related-issues-token-body bordered-box bg-white"
|
||||
:class="{ 'sortable-container': canReorder }"
|
||||
>
|
||||
<div v-if="isFetching" class="related-issues-loading-icon qa-related-issues-loading-icon">
|
||||
<div
|
||||
v-if="isFetching"
|
||||
class="related-issues-loading-icon"
|
||||
data-qa-selector="related_issues_loading_placeholder"
|
||||
>
|
||||
<gl-loading-icon ref="loadingIcon" label="Fetching linked issues" class="gl-mt-2" />
|
||||
</div>
|
||||
<ul ref="list" :class="{ 'content-list': !canReorder }" class="related-items-list">
|
||||
|
@ -132,7 +136,7 @@ export default {
|
|||
:is-locked="issue.lockIssueRemoval"
|
||||
:locked-message="issue.lockedMessage"
|
||||
event-namespace="relatedIssue"
|
||||
class="qa-related-issuable-item"
|
||||
data-qa-selector="related_issuable_content"
|
||||
@relatedIssueRemoveRequest="$emit('relatedIssueRemoveRequest', $event)"
|
||||
/>
|
||||
</li>
|
||||
|
|
|
@ -6,7 +6,6 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
before_action :user, except: [:index, :new, :create]
|
||||
before_action :check_impersonation_availability, only: :impersonate
|
||||
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
|
||||
before_action :check_admin_approval_feature_available!, only: [:approve]
|
||||
|
||||
feature_category :users
|
||||
|
||||
|
@ -298,10 +297,6 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
def log_impersonation_event
|
||||
Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username })
|
||||
end
|
||||
|
||||
def check_admin_approval_feature_available!
|
||||
access_denied! unless Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
|
||||
end
|
||||
end
|
||||
|
||||
Admin::UsersController.prepend_if_ee('EE::Admin::UsersController')
|
||||
|
|
|
@ -218,7 +218,6 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def set_user_state
|
||||
return unless Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
|
||||
return unless Gitlab::CurrentSettings.require_admin_approval_after_user_signup
|
||||
|
||||
resource.state = BLOCKED_PENDING_APPROVAL_STATE
|
||||
|
|
|
@ -21,6 +21,7 @@ class ContainerExpirationPolicy < ApplicationRecord
|
|||
validates :cadence, presence: true, inclusion: { in: ->(_) { self.cadence_options.stringify_keys } }
|
||||
validates :older_than, inclusion: { in: ->(_) { self.older_than_options.stringify_keys } }, allow_nil: true
|
||||
validates :keep_n, inclusion: { in: ->(_) { self.keep_n_options.keys } }, allow_nil: true
|
||||
validates :name_regex, presence: true, if: :enabled?
|
||||
validates :name_regex, untrusted_regexp: true, if: :enabled?
|
||||
validates :name_regex_keep, untrusted_regexp: true, if: :enabled?
|
||||
|
||||
|
|
|
@ -9,14 +9,13 @@
|
|||
Sign-up enabled
|
||||
.form-text.text-muted
|
||||
= _("When enabled, any user visiting %{host} will be able to create an account.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
|
||||
- if Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :require_admin_approval_after_user_signup, class: 'form-check-input'
|
||||
= f.label :require_admin_approval_after_user_signup, class: 'form-check-label' do
|
||||
= _('Require admin approval for new sign-ups')
|
||||
.form-text.text-muted
|
||||
= _("When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :require_admin_approval_after_user_signup, class: 'form-check-input'
|
||||
= f.label :require_admin_approval_after_user_signup, class: 'form-check-label' do
|
||||
= _('Require admin approval for new sign-ups')
|
||||
.form-text.text-muted
|
||||
= _("When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :send_user_confirmation_email, class: 'form-check-input'
|
||||
|
|
|
@ -30,11 +30,10 @@
|
|||
= link_to admin_users_path(filter: "blocked") do
|
||||
= s_('AdminUsers|Blocked')
|
||||
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked)
|
||||
- if Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
|
||||
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
|
||||
= link_to admin_users_path(filter: "blocked_pending_approval") do
|
||||
= s_('AdminUsers|Pending approval')
|
||||
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
|
||||
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
|
||||
= link_to admin_users_path(filter: "blocked_pending_approval") do
|
||||
= s_('AdminUsers|Pending approval')
|
||||
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
|
||||
= nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do
|
||||
= link_to admin_users_path(filter: "deactivated") do
|
||||
= s_('AdminUsers|Deactivated')
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove admin_approval_for_new_user_signups feature flag
|
||||
merge_request: 46051
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add default regexes and prevent blank regexes for container cleanup policies
|
||||
merge_request: 44757
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SetRegexDefaultsOnContainerExpirationPolicies < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
change_column_default :container_expiration_policies, :name_regex, '.*'
|
||||
change_column_default :container_expiration_policies, :enabled, false
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
change_column_default :container_expiration_policies, :name_regex, nil
|
||||
change_column_default :container_expiration_policies, :enabled, true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
250785e18682cc10afb4f04546e5ff6dff9ab6c6673df84692c8221d6fe820ac
|
|
@ -11235,11 +11235,11 @@ CREATE TABLE container_expiration_policies (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
next_run_at timestamp with time zone,
|
||||
name_regex character varying(255),
|
||||
name_regex character varying(255) DEFAULT '.*'::character varying,
|
||||
cadence character varying(12) DEFAULT '1d'::character varying NOT NULL,
|
||||
older_than character varying(12) DEFAULT '90d'::character varying,
|
||||
keep_n integer DEFAULT 10,
|
||||
enabled boolean DEFAULT true NOT NULL,
|
||||
enabled boolean DEFAULT false NOT NULL,
|
||||
name_regex_keep text,
|
||||
CONSTRAINT container_expiration_policies_name_regex_keep CHECK ((char_length(name_regex_keep) <= 255))
|
||||
);
|
||||
|
|
|
@ -582,6 +582,12 @@ This file lives in `/var/log/gitlab/gitaly/current` and is produced by [runit](h
|
|||
|
||||
This file lives in `/var/log/gitlab/gitlab-rails/grpc.log` for Omnibus GitLab packages. Native [gRPC](https://grpc.io/) logging used by Gitaly.
|
||||
|
||||
### `gitaly_ruby_json.log`
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/2678) in GitLab 13.6.
|
||||
|
||||
This file lives in `/var/log/gitlab/gitaly/gitaly_ruby_json.log` and is produced by [`gitaly-ruby`](gitaly/reference.md#gitaly-ruby). It contains an access log of gRPC calls made by Gitaly to `gitaly-ruby`.
|
||||
|
||||
## Puma Logs
|
||||
|
||||
### `puma_stdout.log`
|
||||
|
|
|
@ -16,7 +16,16 @@ POST /import/github
|
|||
| `target_namespace` | string | yes | Namespace to import repository into. Supports subgroups like `/namespace/subgroup`. |
|
||||
|
||||
```shell
|
||||
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "personal_access_token=abc123&repo_id=12345&target_namespace=group/subgroup" "https://gitlab.example.com/api/v4/import/github"
|
||||
curl --request POST \
|
||||
--url "https://gitlab.example.com/api/v4/import/github" \
|
||||
--header "content-type: application/json" \
|
||||
--header "PRIVATE-TOKEN: <your_access_token>" \
|
||||
--data '{
|
||||
"personal_access_token": "aBc123abC12aBc123abC12abC123+_A/c123",
|
||||
"repo_id": "12345",
|
||||
"target_namespace": "group/subgroup",
|
||||
"new_name": "NEW-NAME"
|
||||
}'
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
|
|
@ -24,6 +24,10 @@ of `state` are:
|
|||
- `replicated`
|
||||
- `cleanup_failed`
|
||||
|
||||
To ensure data integrity, projects are put in a temporary read-only state for the
|
||||
duration of the move. During this time, users receive a `The repository is temporarily
|
||||
read-only. Please try again later.` message if they try to push new commits.
|
||||
|
||||
This API requires you to [authenticate yourself](README.md#authentication) as an administrator.
|
||||
|
||||
## Retrieve all project repository storage moves
|
||||
|
|
|
@ -90,25 +90,6 @@ explain what falls under each type label.
|
|||
|
||||
The GitLab handbook documents [when something is a bug](https://about.gitlab.com/handbook/product/product-processes/#bug-issues) and [when it is a feature request](https://about.gitlab.com/handbook/product/product-processes/#feature-issues).
|
||||
|
||||
### Facet labels
|
||||
|
||||
Sometimes it's useful to refine the type of an issue. In those cases, you can
|
||||
add facet labels.
|
||||
|
||||
Following is a non-exhaustive list of facet labels:
|
||||
|
||||
- ~enhancement: This label can refine an issue that has the ~feature label.
|
||||
- ~"master:broken": This label can refine an issue that has the ~bug label.
|
||||
- ~"failure::flaky-test": This label can refine an issue that has the ~bug label.
|
||||
- ~"technical debt": This label can refine an issue that has the ~tooling label.
|
||||
- ~"static analysis": This label can refine an issue that has the ~tooling label.
|
||||
- ~"ci-build": This label can refine an issue that has the ~tooling label.
|
||||
- ~performance: A performance issue could describe a ~bug or a ~feature.
|
||||
- ~security: A security issue could describe a ~bug or a ~feature.
|
||||
- ~database: A database issue could describe a ~bug or a ~feature.
|
||||
- ~customer: This relates to an issue that was created by a customer, or that is of interest for a customer.
|
||||
- ~"UI text": Issues that add or modify any text within the UI such as user-assistance microcopy, button/menu labels, or error messages.
|
||||
|
||||
### Stage labels
|
||||
|
||||
Stage labels specify which [stage](https://about.gitlab.com/handbook/product/product-categories/#hierarchy) the issue belongs to.
|
||||
|
|
|
@ -13,12 +13,13 @@ See already supported package types in [Packages documentation](../administratio
|
|||
Since GitLab packages' UI is pretty generic, it is possible to add basic new
|
||||
package system support with solely backend changes. This guide is superficial and does
|
||||
not cover the way the code should be written. However, you can find a good example
|
||||
by looking at merge requests with Maven and NPM support:
|
||||
by looking at the following merge requests:
|
||||
|
||||
- [NPM registry support](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8673).
|
||||
- [Conan repository](https://gitlab.com/gitlab-org/gitlab/-/issues/8248).
|
||||
- [Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6607).
|
||||
- [Instance level endpoint for Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8757)
|
||||
- [Composer repository for PHP dependencies](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22415).
|
||||
- [Terraform modules registry](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18834).
|
||||
- [Instance-level endpoint for Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8757).
|
||||
|
||||
## General information
|
||||
|
||||
|
|
|
@ -522,7 +522,7 @@ To create a cleanup policy in the UI:
|
|||
| **Expiration interval** | How long tags are exempt from being deleted. |
|
||||
| **Expiration schedule** | How often the policy should run. |
|
||||
| **Number of tags to retain** | How many tags to _always_ keep for each image. |
|
||||
| **Tags with names matching this regex pattern expire:** | The regex pattern that determines which tags to remove. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
|
||||
| **Tags with names matching this regex pattern expire:** | The regex pattern that determines which tags to remove. This value cannot be blank. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
|
||||
| **Tags with names matching this regex pattern are preserved:** | The regex pattern that determines which tags to preserve. The `latest` tag is always preserved. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
|
||||
|
||||
1. Click **Set cleanup policy**.
|
||||
|
@ -544,6 +544,8 @@ Here are examples of regex patterns you may want to use:
|
|||
.*
|
||||
```
|
||||
|
||||
This is the default value for the expiration regex.
|
||||
|
||||
- Match tags that start with `v`:
|
||||
|
||||
```plaintext
|
||||
|
|
|
@ -33,8 +33,7 @@ You can also use the [API](../../api/packages.md) to administer the Package Regi
|
|||
## Accepting contributions
|
||||
|
||||
The below table lists formats that are not supported, but are accepting Community contributions for. Consider contributing to GitLab. This [development documentation](../../development/packages.md) will
|
||||
guide you through the process. Or check out how other members of the community
|
||||
are adding support for [PHP](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17417) or [Terraform](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18834).
|
||||
guide you through the process.
|
||||
|
||||
| Format | Status |
|
||||
| ------ | ------ |
|
||||
|
|
|
@ -41,7 +41,7 @@ Note the following:
|
|||
- Group members are exported as project members, as long as the user has
|
||||
maintainer or admin access to the group where the exported project lives.
|
||||
- Project members with owner access will be imported as maintainers.
|
||||
- Using an admin account to import will map users by primary email address (self-managed only).
|
||||
- Imported users can be mapped by their primary email on self-managed instances, if an administrative user (not an owner) does the import.
|
||||
Otherwise, a supplementary comment is left to mention that the original author and
|
||||
the MRs, notes, or issues will be owned by the importer.
|
||||
- If an imported project contains merge requests originating from forks,
|
||||
|
|
|
@ -16,12 +16,20 @@ module QA
|
|||
end
|
||||
|
||||
view 'app/assets/javascripts/notes/components/discussion_filter.vue' do
|
||||
element :discussion_filter, required: true
|
||||
element :filter_options
|
||||
element :discussion_filter_dropdown, required: true
|
||||
element :filter_menu_item
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/notes/components/discussion_filter_note.vue' do
|
||||
element :discussion_filter_container
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/notes/components/noteable_note.vue' do
|
||||
element :noteable_note_item
|
||||
element :noteable_note_container
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/notes/components/note_header.vue' do
|
||||
element :system_note_content
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue' do
|
||||
|
@ -51,8 +59,8 @@ module QA
|
|||
end
|
||||
|
||||
view 'app/assets/javascripts/related_issues/components/related_issues_list.vue' do
|
||||
element :related_issuable_item
|
||||
element :related_issues_loading_icon
|
||||
element :related_issuable_content
|
||||
element :related_issues_loading_placeholder
|
||||
end
|
||||
|
||||
def relate_issue(issue)
|
||||
|
@ -62,11 +70,11 @@ module QA
|
|||
end
|
||||
|
||||
def related_issuable_item
|
||||
find_element(:related_issuable_item)
|
||||
find_element(:related_issuable_content)
|
||||
end
|
||||
|
||||
def wait_for_related_issues_to_load
|
||||
has_no_element?(:related_issues_loading_icon, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
has_no_element?(:related_issues_loading_placeholder, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
end
|
||||
|
||||
def click_remove_related_issue_button
|
||||
|
@ -95,11 +103,15 @@ module QA
|
|||
end
|
||||
|
||||
def has_comment?(comment_text)
|
||||
has_element?(:noteable_note_item, text: comment_text, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
has_element?(:noteable_note_container, text: comment_text, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
end
|
||||
|
||||
def has_system_note?(note_text)
|
||||
has_element?(:system_note_content, text: note_text, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
end
|
||||
|
||||
def noteable_note_item
|
||||
find_element(:noteable_note_item)
|
||||
find_element(:noteable_note_container)
|
||||
end
|
||||
|
||||
def select_all_activities_filter
|
||||
|
@ -108,10 +120,18 @@ module QA
|
|||
|
||||
def select_comments_only_filter
|
||||
select_filter_with_text('Show comments only')
|
||||
|
||||
wait_until do
|
||||
has_no_element?(:system_note_content)
|
||||
end
|
||||
end
|
||||
|
||||
def select_history_only_filter
|
||||
select_filter_with_text('Show history only')
|
||||
|
||||
wait_until do
|
||||
has_element?(:discussion_filter_container) && has_no_element?(:noteable_note_container)
|
||||
end
|
||||
end
|
||||
|
||||
def has_metrics_unfurled?
|
||||
|
@ -123,8 +143,8 @@ module QA
|
|||
def select_filter_with_text(text)
|
||||
retry_on_exception do
|
||||
click_element(:title)
|
||||
click_element :discussion_filter
|
||||
find_element(:filter_options, text: text).click
|
||||
click_element :discussion_filter_dropdown
|
||||
find_element(:filter_menu_item, text: text).click
|
||||
|
||||
wait_for_loading
|
||||
end
|
||||
|
|
|
@ -18,16 +18,16 @@ module QA
|
|||
show.comment(my_own_comment, filter: :comments_only)
|
||||
|
||||
expect(show).not_to have_content(made_the_issue_confidential)
|
||||
expect(show).to have_content(my_own_comment)
|
||||
expect(show).to have_comment(my_own_comment)
|
||||
|
||||
show.select_all_activities_filter
|
||||
|
||||
expect(show).to have_content(made_the_issue_confidential)
|
||||
expect(show).to have_content(my_own_comment)
|
||||
expect(show).to have_system_note(made_the_issue_confidential)
|
||||
expect(show).to have_comment(my_own_comment)
|
||||
|
||||
show.select_history_only_filter
|
||||
|
||||
expect(show).to have_content(made_the_issue_confidential)
|
||||
expect(show).to have_system_note(made_the_issue_confidential)
|
||||
expect(show).not_to have_content(my_own_comment)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -107,49 +107,31 @@ RSpec.describe Admin::UsersController do
|
|||
|
||||
subject { put :approve, params: { id: user.username } }
|
||||
|
||||
context 'when feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: false)
|
||||
end
|
||||
|
||||
it 'responds with access denied' do
|
||||
context 'when successful' do
|
||||
it 'activates the user' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
user.reload
|
||||
|
||||
expect(user).to be_active
|
||||
expect(flash[:notice]).to eq('Successfully approved')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature is enabled' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: true)
|
||||
context 'when unsuccessful' do
|
||||
let(:user) { create(:user, :blocked) }
|
||||
|
||||
it 'displays the error' do
|
||||
subject
|
||||
|
||||
expect(flash[:alert]).to eq('The user you are trying to approve is not pending an approval')
|
||||
end
|
||||
|
||||
context 'when successful' do
|
||||
it 'activates the user' do
|
||||
subject
|
||||
it 'does not activate the user' do
|
||||
subject
|
||||
|
||||
user.reload
|
||||
|
||||
expect(user).to be_active
|
||||
expect(flash[:notice]).to eq('Successfully approved')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unsuccessful' do
|
||||
let(:user) { create(:user, :blocked) }
|
||||
|
||||
it 'displays the error' do
|
||||
subject
|
||||
|
||||
expect(flash[:alert]).to eq('The user you are trying to approve is not pending an approval')
|
||||
end
|
||||
|
||||
it 'does not activate the user' do
|
||||
subject
|
||||
|
||||
user.reload
|
||||
expect(user).not_to be_active
|
||||
end
|
||||
user.reload
|
||||
expect(user).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,102 +46,76 @@ RSpec.describe RegistrationsController do
|
|||
subject { post(:create, params: user_params) }
|
||||
|
||||
context '`blocked_pending_approval` state' do
|
||||
context 'when the feature is enabled' do
|
||||
context 'when the `require_admin_approval_after_user_signup` setting is turned on' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: true)
|
||||
stub_application_setting(require_admin_approval_after_user_signup: true)
|
||||
end
|
||||
|
||||
context 'when the `require_admin_approval_after_user_signup` setting is turned on' do
|
||||
before do
|
||||
stub_application_setting(require_admin_approval_after_user_signup: true)
|
||||
end
|
||||
it 'signs up the user in `blocked_pending_approval` state' do
|
||||
subject
|
||||
created_user = User.find_by(email: 'new@user.com')
|
||||
|
||||
it 'signs up the user in `blocked_pending_approval` state' do
|
||||
subject
|
||||
created_user = User.find_by(email: 'new@user.com')
|
||||
expect(created_user).to be_present
|
||||
expect(created_user.blocked_pending_approval?).to eq(true)
|
||||
end
|
||||
|
||||
expect(created_user).to be_present
|
||||
expect(created_user.blocked_pending_approval?).to eq(true)
|
||||
end
|
||||
it 'does not log in the user after sign up' do
|
||||
subject
|
||||
|
||||
it 'does not log in the user after sign up' do
|
||||
subject
|
||||
expect(controller.current_user).to be_nil
|
||||
end
|
||||
|
||||
expect(controller.current_user).to be_nil
|
||||
end
|
||||
it 'shows flash message after signing up' do
|
||||
subject
|
||||
|
||||
it 'shows flash message after signing up' do
|
||||
subject
|
||||
expect(response).to redirect_to(new_user_session_path(anchor: 'login-pane'))
|
||||
expect(flash[:notice])
|
||||
.to eq('You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator.')
|
||||
end
|
||||
|
||||
expect(response).to redirect_to(new_user_session_path(anchor: 'login-pane'))
|
||||
expect(flash[:notice])
|
||||
.to eq('You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator.')
|
||||
end
|
||||
|
||||
context 'email confirmation' do
|
||||
context 'when `send_user_confirmation_email` is true' do
|
||||
before do
|
||||
stub_application_setting(send_user_confirmation_email: true)
|
||||
end
|
||||
|
||||
it 'does not send a confirmation email' do
|
||||
expect { subject }
|
||||
.not_to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
|
||||
end
|
||||
context 'email confirmation' do
|
||||
context 'when `send_user_confirmation_email` is true' do
|
||||
before do
|
||||
stub_application_setting(send_user_confirmation_email: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the `require_admin_approval_after_user_signup` setting is turned off' do
|
||||
before do
|
||||
stub_application_setting(require_admin_approval_after_user_signup: false)
|
||||
end
|
||||
|
||||
it 'signs up the user in `active` state' do
|
||||
subject
|
||||
created_user = User.find_by(email: 'new@user.com')
|
||||
|
||||
expect(created_user).to be_present
|
||||
expect(created_user.active?).to eq(true)
|
||||
end
|
||||
|
||||
it 'does not show any flash message after signing up' do
|
||||
subject
|
||||
|
||||
expect(flash[:notice]).to be_nil
|
||||
end
|
||||
|
||||
context 'email confirmation' do
|
||||
context 'when `send_user_confirmation_email` is true' do
|
||||
before do
|
||||
stub_application_setting(send_user_confirmation_email: true)
|
||||
end
|
||||
|
||||
it 'sends a confirmation email' do
|
||||
expect { subject }
|
||||
.to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
|
||||
end
|
||||
it 'does not send a confirmation email' do
|
||||
expect { subject }
|
||||
.not_to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the feature is disabled' do
|
||||
context 'when the `require_admin_approval_after_user_signup` setting is turned off' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: false)
|
||||
stub_application_setting(require_admin_approval_after_user_signup: false)
|
||||
end
|
||||
|
||||
context 'when the `require_admin_approval_after_user_signup` setting is turned on' do
|
||||
before do
|
||||
stub_application_setting(require_admin_approval_after_user_signup: true)
|
||||
end
|
||||
it 'signs up the user in `active` state' do
|
||||
subject
|
||||
created_user = User.find_by(email: 'new@user.com')
|
||||
|
||||
it 'signs up the user in `active` state' do
|
||||
subject
|
||||
expect(created_user).to be_present
|
||||
expect(created_user.active?).to eq(true)
|
||||
end
|
||||
|
||||
created_user = User.find_by(email: 'new@user.com')
|
||||
expect(created_user).to be_present
|
||||
expect(created_user.active?).to eq(true)
|
||||
it 'does not show any flash message after signing up' do
|
||||
subject
|
||||
|
||||
expect(flash[:notice]).to be_nil
|
||||
end
|
||||
|
||||
context 'email confirmation' do
|
||||
context 'when `send_user_confirmation_email` is true' do
|
||||
before do
|
||||
stub_application_setting(send_user_confirmation_email: true)
|
||||
end
|
||||
|
||||
it 'sends a confirmation email' do
|
||||
expect { subject }
|
||||
.to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -132,32 +132,14 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
|
|||
|
||||
context 'Change Sign-up restrictions' do
|
||||
context 'Require Admin approval for new signup setting' do
|
||||
context 'when feature is enabled' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: true)
|
||||
it 'changes the setting' do
|
||||
page.within('.as-signup') do
|
||||
check 'Require admin approval for new sign-ups'
|
||||
click_button 'Save changes'
|
||||
end
|
||||
|
||||
it 'changes the setting' do
|
||||
page.within('.as-signup') do
|
||||
check 'Require admin approval for new sign-ups'
|
||||
click_button 'Save changes'
|
||||
end
|
||||
|
||||
expect(current_settings.require_admin_approval_after_user_signup).to be_truthy
|
||||
expect(page).to have_content "Application settings saved successfully"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: false)
|
||||
end
|
||||
|
||||
it 'does not show the the setting' do
|
||||
page.within('.as-signup') do
|
||||
expect(page).not_to have_selector('.application_setting_require_admin_approval_after_user_signup')
|
||||
end
|
||||
end
|
||||
expect(current_settings.require_admin_approval_after_user_signup).to be_truthy
|
||||
expect(page).to have_content "Application settings saved successfully"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,26 +75,12 @@ RSpec.describe "Admin::Users" do
|
|||
end
|
||||
|
||||
context '`Pending approval` tab' do
|
||||
context 'feature is enabled' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: true)
|
||||
visit admin_users_path
|
||||
end
|
||||
|
||||
it 'shows the `Pending approval` tab' do
|
||||
expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
|
||||
end
|
||||
before do
|
||||
visit admin_users_path
|
||||
end
|
||||
|
||||
context 'feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(admin_approval_for_new_user_signups: false)
|
||||
visit admin_users_path
|
||||
end
|
||||
|
||||
it 'does not show the `Pending approval` tab' do
|
||||
expect(page).not_to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
|
||||
end
|
||||
it 'shows the `Pending approval` tab' do
|
||||
expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
|
|||
|
||||
before do
|
||||
project.update!(container_registry_enabled: container_registry_enabled_on_project)
|
||||
project.container_expiration_policy.update!(enabled: true)
|
||||
|
||||
sign_in(user)
|
||||
stub_container_registry_config(enabled: container_registry_enabled)
|
||||
|
|
|
@ -123,7 +123,7 @@ exports[`Expiration Policy Form renders 1`] = `
|
|||
disabled="true"
|
||||
id="expiration-policy-name-matching"
|
||||
noresize="true"
|
||||
placeholder=".*"
|
||||
placeholder=""
|
||||
trim=""
|
||||
value=""
|
||||
/>
|
||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
|
|||
|
||||
it_behaves_like 'not creating the container expiration policy'
|
||||
|
||||
it "doesn't update the cadence" do
|
||||
it 'doesn\'t update the cadence' do
|
||||
expect { subject }
|
||||
.not_to change { container_expiration_policy.reload.cadence }
|
||||
end
|
||||
|
@ -47,6 +47,24 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with blank regex' do
|
||||
let_it_be(:params) { { project_path: project.full_path, name_regex: '', enabled: true } }
|
||||
|
||||
it_behaves_like 'not creating the container expiration policy'
|
||||
|
||||
it "doesn't update the cadence" do
|
||||
expect { subject }
|
||||
.not_to change { container_expiration_policy.reload.cadence }
|
||||
end
|
||||
|
||||
it 'returns an error' do
|
||||
expect(subject).to eq(
|
||||
container_expiration_policy: nil,
|
||||
errors: ['Name regex can\'t be blank']
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'denying access to container expiration policy' do
|
||||
|
|
|
@ -546,13 +546,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
subject { described_class.data[:counts] }
|
||||
|
||||
it 'gathers usage data' do
|
||||
expect(subject[:projects_with_expiration_policy_enabled]).to eq 22
|
||||
expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled]).to eq 18
|
||||
expect(subject[:projects_with_expiration_policy_disabled]).to eq 5
|
||||
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 16
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 12
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
|
||||
|
||||
|
@ -560,9 +560,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 18
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 14
|
||||
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 18
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 14
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
|
||||
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1
|
||||
|
|
|
@ -66,9 +66,15 @@ RSpec.describe ContainerExpirationPolicy, type: :model do
|
|||
end
|
||||
|
||||
context 'with a set of regexps' do
|
||||
let_it_be(:container_expiration_policy) { create(:container_expiration_policy) }
|
||||
|
||||
subject { container_expiration_policy }
|
||||
|
||||
valid_regexps = %w[master .* v.+ v10.1.* (?:v.+|master|release)]
|
||||
invalid_regexps = ['[', '(?:v.+|master|release']
|
||||
|
||||
it { is_expected.to validate_presence_of(:name_regex) }
|
||||
|
||||
valid_regexps.each do |valid_regexp|
|
||||
it { is_expected.to allow_value(valid_regexp).for(:name_regex) }
|
||||
it { is_expected.to allow_value(valid_regexp).for(:name_regex_keep) }
|
||||
|
@ -84,6 +90,8 @@ RSpec.describe ContainerExpirationPolicy, type: :model do
|
|||
|
||||
subject { container_expiration_policy }
|
||||
|
||||
it { is_expected.not_to validate_presence_of(:name_regex) }
|
||||
|
||||
valid_regexps.each do |valid_regexp|
|
||||
it { is_expected.to allow_value(valid_regexp).for(:name_regex) }
|
||||
it { is_expected.to allow_value(valid_regexp).for(:name_regex_keep) }
|
||||
|
|
|
@ -73,6 +73,29 @@ RSpec.describe 'Updating the container expiration policy' do
|
|||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'rejecting blank name_regex when enabled' do
|
||||
context "for blank name_regex" do
|
||||
let(:params) do
|
||||
{
|
||||
project_path: project.full_path,
|
||||
name_regex: '',
|
||||
enabled: true
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'returning response status', :success
|
||||
|
||||
it_behaves_like 'not creating the container expiration policy'
|
||||
|
||||
it 'returns an error' do
|
||||
subject
|
||||
|
||||
expect(graphql_data['updateContainerExpirationPolicy']['errors'].size).to eq(1)
|
||||
expect(graphql_data['updateContainerExpirationPolicy']['errors']).to include("Name regex can't be blank")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'accepting the mutation request updating the container expiration policy' do
|
||||
it_behaves_like 'updating the container expiration policy attributes', mode: :update, from: { cadence: '1d', keep_n: 10, older_than: '90d' }, to: { cadence: '3month', keep_n: 100, older_than: '14d' }
|
||||
|
||||
|
@ -80,6 +103,7 @@ RSpec.describe 'Updating the container expiration policy' do
|
|||
|
||||
it_behaves_like 'rejecting invalid regex for', :name_regex
|
||||
it_behaves_like 'rejecting invalid regex for', :name_regex_keep
|
||||
it_behaves_like 'rejecting blank name_regex when enabled'
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'accepting the mutation request creating the container expiration policy' do
|
||||
|
@ -89,6 +113,7 @@ RSpec.describe 'Updating the container expiration policy' do
|
|||
|
||||
it_behaves_like 'rejecting invalid regex for', :name_regex
|
||||
it_behaves_like 'rejecting invalid regex for', :name_regex_keep
|
||||
it_behaves_like 'rejecting blank name_regex when enabled'
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'denying the mutation request' do
|
||||
|
|
|
@ -2659,6 +2659,7 @@ RSpec.describe API::Projects do
|
|||
project_param = {
|
||||
container_expiration_policy_attributes: {
|
||||
cadence: '1month',
|
||||
enabled: true,
|
||||
keep_n: 1,
|
||||
name_regex_keep: '['
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
|
|||
describe '#perform_work' do
|
||||
subject { worker.perform_work }
|
||||
|
||||
before do
|
||||
policy.update_column(:enabled, true)
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'handling all repository conditions' do
|
||||
it 'sends the repository for cleaning' do
|
||||
expect(ContainerExpirationPolicies::CleanupService)
|
||||
|
|
Loading…
Reference in New Issue