Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
cc273dad6e
commit
c1ce2b78fa
|
|
@ -18,10 +18,6 @@ stages:
|
|||
- GIT_DEPTH
|
||||
- GIT_STRATEGY
|
||||
|
||||
workflow:
|
||||
auto_cancel:
|
||||
on_new_commit: none
|
||||
|
||||
variables:
|
||||
GIT_DEPTH: 20
|
||||
GIT_STRATEGY: fetch
|
||||
|
|
@ -66,16 +62,11 @@ release-environments-deploy:
|
|||
variables:
|
||||
VERSIONS: "${VERSIONS}"
|
||||
ENVIRONMENT: "${ENVIRONMENT}"
|
||||
before_script:
|
||||
# Make sure pipelines run in order
|
||||
# See https://docs.gitlab.com/ee/ci/resource_groups/index.html#change-the-process-mode
|
||||
- curl --request PUT --data "process_mode=oldest_first" --header "PRIVATE-TOKEN:${ENVIRONMENT_API_TOKEN}" "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/resource_groups/release-environment-${CI_COMMIT_REF_SLUG}"
|
||||
trigger:
|
||||
project: gitlab-com/gl-infra/release-environments
|
||||
branch: main
|
||||
strategy: depend
|
||||
needs: ["release-environments-deploy-env"]
|
||||
resource_group: release-environment-${CI_COMMIT_REF_SLUG}
|
||||
|
||||
release-environments-qa:
|
||||
stage: qa
|
||||
|
|
@ -89,7 +80,6 @@ release-environments-qa:
|
|||
GITLAB_INITIAL_ROOT_PASSWORD: "${RELEASE_ENVIRONMENTS_ROOT_PASSWORD}"
|
||||
QA_PRAEFECT_REPOSITORY_STORAGE: "default"
|
||||
SIGNUP_DISABLED: "true"
|
||||
resource_group: release-environment-${CI_COMMIT_REF_SLUG}
|
||||
|
||||
release-environments-notification-failure:
|
||||
stage: finish
|
||||
|
|
|
|||
|
|
@ -934,6 +934,7 @@ Gitlab/NamespacedClass:
|
|||
- 'ee/db/**/*.rb'
|
||||
- 'ee/elastic/**/*.rb'
|
||||
- 'scripts/**/*'
|
||||
- 'spec/fixtures/migrations/**/*.rb'
|
||||
- 'spec/migrations/**/*.rb'
|
||||
- 'app/experiments/**/*_experiment.rb'
|
||||
- 'ee/app/experiments/**/*_experiment.rb'
|
||||
|
|
|
|||
|
|
@ -2,19 +2,6 @@
|
|||
# Cop supports --autocorrect.
|
||||
Layout/FirstHashElementIndentation:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/system_info_controller.rb'
|
||||
- 'app/controllers/concerns/milestone_actions.rb'
|
||||
- 'app/controllers/concerns/render_service_results.rb'
|
||||
- 'app/controllers/concerns/sourcegraph_decorator.rb'
|
||||
- 'app/controllers/projects/badges_controller.rb'
|
||||
- 'app/controllers/projects/merge_requests_controller.rb'
|
||||
- 'app/controllers/repositories/lfs_locks_api_controller.rb'
|
||||
- 'app/graphql/mutations/notes/create/diff_note.rb'
|
||||
- 'app/graphql/mutations/notes/create/image_diff_note.rb'
|
||||
- 'app/graphql/mutations/notes/create/note.rb'
|
||||
- 'app/graphql/resolvers/ci/runner_projects_resolver.rb'
|
||||
- 'app/graphql/resolvers/group_packages_resolver.rb'
|
||||
- 'app/helpers/commits_helper.rb'
|
||||
- 'app/helpers/projects/project_members_helper.rb'
|
||||
- 'app/helpers/search_helper.rb'
|
||||
- 'app/helpers/ssh_keys_helper.rb'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
<script>
|
||||
import { GlAlert, GlButton, GlFormSelect, GlFormGroup, GlIcon, GlLink, GlToken } from '@gitlab/ui';
|
||||
import { isNumber } from 'lodash';
|
||||
import Vue from 'vue';
|
||||
import { s__, __ } from '~/locale';
|
||||
import {
|
||||
EMPTY_PARAMETERS,
|
||||
|
|
@ -114,7 +113,8 @@ export default {
|
|||
},
|
||||
removeScope(environment) {
|
||||
if (isNumber(environment.id)) {
|
||||
Vue.set(environment, 'shouldBeDestroyed', true);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
environment.shouldBeDestroyed = true;
|
||||
} else {
|
||||
this.environments = this.environments.filter((e) => e !== environment);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import Vue from 'vue';
|
||||
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
|
||||
import * as types from './mutation_types';
|
||||
|
||||
const updateFlag = (state, flag) => {
|
||||
const index = state.featureFlags.findIndex(({ id }) => id === flag.id);
|
||||
Vue.set(state.featureFlags, index, flag);
|
||||
const copy = [...state.featureFlags];
|
||||
copy[index] = flag;
|
||||
state.featureFlags = copy;
|
||||
};
|
||||
|
||||
const createPaginationInfo = (headers) => {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
|
|||
import { __ } from '~/locale';
|
||||
import {
|
||||
OPERATORS_IS,
|
||||
OPERATORS_IS_NOT,
|
||||
OPERATORS_IS_NOT_OR,
|
||||
OPERATORS_AFTER_BEFORE,
|
||||
TOKEN_TITLE_ASSIGNEE,
|
||||
|
|
@ -309,9 +308,6 @@ export default {
|
|||
typeTokenOptions() {
|
||||
return [...defaultTypeTokenOptions, ...this.eeTypeTokenOptions];
|
||||
},
|
||||
hasOrFeature() {
|
||||
return this.glFeatures.orIssuableQueries;
|
||||
},
|
||||
hasSearch() {
|
||||
return Boolean(
|
||||
this.searchQuery ||
|
||||
|
|
@ -383,7 +379,7 @@ export default {
|
|||
token: UserToken,
|
||||
dataType: 'user',
|
||||
defaultUsers: [],
|
||||
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
|
||||
operators: OPERATORS_IS_NOT_OR,
|
||||
fullPath: this.fullPath,
|
||||
isProject: this.isProject,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-author`,
|
||||
|
|
@ -396,7 +392,7 @@ export default {
|
|||
icon: 'user',
|
||||
token: UserToken,
|
||||
dataType: 'user',
|
||||
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
|
||||
operators: OPERATORS_IS_NOT_OR,
|
||||
fullPath: this.fullPath,
|
||||
isProject: this.isProject,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-assignee`,
|
||||
|
|
@ -418,7 +414,7 @@ export default {
|
|||
title: TOKEN_TITLE_LABEL,
|
||||
icon: 'labels',
|
||||
token: LabelToken,
|
||||
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
|
||||
operators: OPERATORS_IS_NOT_OR,
|
||||
fetchLabels: this.fetchLabels,
|
||||
fetchLatestLabels: this.glFeatures.frontendCaching ? this.fetchLatestLabels : null,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-label`,
|
||||
|
|
@ -956,12 +952,12 @@ export default {
|
|||
:show-bulk-edit-sidebar="showBulkEditSidebar"
|
||||
:show-pagination-controls="showPaginationControls"
|
||||
:default-page-size="pageSize"
|
||||
show-filtered-search-friendly-text
|
||||
sync-filter-and-sort
|
||||
use-keyset-pagination
|
||||
:show-page-size-change-controls="showPageSizeControls"
|
||||
:has-next-page="pageInfo.hasNextPage"
|
||||
:has-previous-page="pageInfo.hasPreviousPage"
|
||||
:show-filtered-search-friendly-text="hasOrFeature"
|
||||
:is-grid-view="isGridView"
|
||||
:active-issuable="activeIssuable"
|
||||
show-work-item-type-icon
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ import {
|
|||
getFilterTokens,
|
||||
getSortOptions,
|
||||
} from '~/issues/list/utils';
|
||||
import {
|
||||
OPERATORS_IS_NOT,
|
||||
OPERATORS_IS_NOT_OR,
|
||||
} from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
import { OPERATORS_IS_NOT_OR } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
import {
|
||||
CLOSED_MOVED,
|
||||
CLOSED,
|
||||
|
|
@ -247,9 +244,6 @@ export default {
|
|||
canShowIssuesList() {
|
||||
return this.isLoading || this.issuesError.length || this.hasAnyServiceDeskIssue;
|
||||
},
|
||||
hasOrFeature() {
|
||||
return this.glFeatures.orIssuableQueries;
|
||||
},
|
||||
hasSearch() {
|
||||
return Boolean(
|
||||
this.searchQuery ||
|
||||
|
|
@ -285,7 +279,7 @@ export default {
|
|||
},
|
||||
{
|
||||
...assigneeTokenBase,
|
||||
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
|
||||
operators: OPERATORS_IS_NOT_OR,
|
||||
fetchUsers: this.fetchUsers,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-assignee`,
|
||||
preloadedUsers,
|
||||
|
|
@ -297,7 +291,7 @@ export default {
|
|||
},
|
||||
{
|
||||
...labelTokenBase,
|
||||
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
|
||||
operators: OPERATORS_IS_NOT_OR,
|
||||
fetchLabels: this.fetchLabels,
|
||||
fetchLatestLabels: this.glFeatures.frontendCaching ? this.fetchLatestLabels : null,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-label`,
|
||||
|
|
@ -575,7 +569,6 @@ export default {
|
|||
:search-tokens="searchTokens"
|
||||
:issuables-loading="isLoading"
|
||||
:initial-filter-value="filterTokens"
|
||||
:show-filtered-search-friendly-text="hasOrFeature"
|
||||
:show-pagination-controls="showPaginationControls"
|
||||
:show-page-size-change-controls="showPageSizeControls"
|
||||
:sort-options="sortOptions"
|
||||
|
|
@ -588,6 +581,7 @@ export default {
|
|||
:default-page-size="pageSize"
|
||||
:has-next-page="pageInfo.hasNextPage"
|
||||
:has-previous-page="pageInfo.hasPreviousPage"
|
||||
show-filtered-search-friendly-text
|
||||
sync-filter-and-sort
|
||||
use-keyset-pagination
|
||||
@click-tab="handleClickTab"
|
||||
|
|
|
|||
|
|
@ -99,12 +99,12 @@ table {
|
|||
tr.responsive-table-border-start,
|
||||
tr.responsive-table-border-end {
|
||||
display: block;
|
||||
border: solid $gl-text-color-quaternary;
|
||||
border: solid $gray-100;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
> td {
|
||||
border-color: $gl-text-color-quaternary;
|
||||
border-color: $gray-100;
|
||||
|
||||
&,
|
||||
&:last-child {
|
||||
|
|
@ -125,7 +125,7 @@ table {
|
|||
}
|
||||
|
||||
> td:last-child {
|
||||
border-bottom: 1px solid $gl-text-color-quaternary;
|
||||
border-bottom: 1px solid $gray-100;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,6 @@ $gl-font-weight-bold: 600;
|
|||
$gl-text-color: $gray-900;
|
||||
$gl-text-color-secondary: $gray-500 !default;
|
||||
$gl-text-color-tertiary: $gray-400;
|
||||
$gl-text-color-quaternary: #d6d6d6;
|
||||
$gl-text-color-inverted: $white;
|
||||
$gl-text-color-secondary-inverted: rgba($white, 0.85);
|
||||
$gl-text-color-disabled: $gray-400;
|
||||
|
|
|
|||
|
|
@ -759,7 +759,7 @@ $tabs-holder-z-index: 250;
|
|||
border: 1px solid var(--border-color, $border-color);
|
||||
|
||||
.circle-icon-container {
|
||||
color: var(--gray-100, $gl-text-color-quaternary);
|
||||
color: var(--gray-100, $gray-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ class Admin::SystemInfoController < Admin::ApplicationController
|
|||
begin
|
||||
disk = Sys::Filesystem.stat(mount.mount_point)
|
||||
@disks.push({
|
||||
bytes_total: disk.bytes_total,
|
||||
bytes_used: disk.bytes_used,
|
||||
disk_name: mount.name,
|
||||
mount_path: disk.path
|
||||
})
|
||||
bytes_total: disk.bytes_total,
|
||||
bytes_used: disk.bytes_used,
|
||||
disk_name: mount.name,
|
||||
mount_path: disk.path
|
||||
})
|
||||
rescue Sys::Filesystem::Error
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ module MilestoneActions
|
|||
format.html { redirect_to milestone_redirect_path }
|
||||
format.json do
|
||||
render json: tabs_json("shared/milestones/_issues_tab", {
|
||||
issues: @milestone.sorted_issues(current_user), # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
|
||||
})
|
||||
issues: @milestone.sorted_issues(current_user), # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -20,9 +20,9 @@ module MilestoneActions
|
|||
format.html { redirect_to milestone_redirect_path }
|
||||
format.json do
|
||||
render json: tabs_json("shared/milestones/_merge_requests_tab", {
|
||||
merge_requests: @milestone.sorted_merge_requests(current_user).preload_milestoneish_associations, # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
|
||||
})
|
||||
merge_requests: @milestone.sorted_merge_requests(current_user).preload_milestoneish_associations, # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
show_project_name: Gitlab::Utils.to_boolean(params[:show_project_name])
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -32,8 +32,8 @@ module MilestoneActions
|
|||
format.html { redirect_to milestone_redirect_path }
|
||||
format.json do
|
||||
render json: tabs_json("shared/milestones/_participants_tab", {
|
||||
users: @milestone.issue_participants_visible_by_user(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
})
|
||||
users: @milestone.issue_participants_visible_by_user(current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -46,10 +46,10 @@ module MilestoneActions
|
|||
milestone_labels = @milestone.issue_labels_visible_by_user(current_user)
|
||||
|
||||
render json: tabs_json("shared/milestones/_labels_tab", {
|
||||
labels: milestone_labels.map do |label|
|
||||
label.present(issuable_subject: @milestone.resource_parent)
|
||||
end
|
||||
})
|
||||
labels: milestone_labels.map do |label|
|
||||
label.present(issuable_subject: @milestone.resource_parent)
|
||||
end
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,25 +5,25 @@ module RenderServiceResults
|
|||
|
||||
def success_response(result)
|
||||
render({
|
||||
status: result[:http_status],
|
||||
json: result[:body]
|
||||
})
|
||||
status: result[:http_status],
|
||||
json: result[:body]
|
||||
})
|
||||
end
|
||||
|
||||
def continue_polling_response
|
||||
render({
|
||||
status: :no_content,
|
||||
json: {
|
||||
status: _('processing'),
|
||||
message: _('Not ready yet. Try again later.')
|
||||
}
|
||||
})
|
||||
status: :no_content,
|
||||
json: {
|
||||
status: _('processing'),
|
||||
message: _('Not ready yet. Try again later.')
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
def error_response(result)
|
||||
render({
|
||||
status: result[:http_status] || :bad_request,
|
||||
json: { status: result[:status], message: result[:message] }
|
||||
})
|
||||
status: result[:http_status] || :bad_request,
|
||||
json: { status: result[:status], message: result[:message] }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ module SourcegraphDecorator
|
|||
return unless sourcegraph_enabled?
|
||||
|
||||
gon.push({
|
||||
sourcegraph: { url: Gitlab::CurrentSettings.sourcegraph_url }
|
||||
})
|
||||
sourcegraph: { url: Gitlab::CurrentSettings.sourcegraph_url }
|
||||
})
|
||||
end
|
||||
|
||||
def sourcegraph_enabled?
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ class GroupsController < Groups::ApplicationController
|
|||
before_action :check_export_rate_limit!, only: [:export, :download_export]
|
||||
|
||||
before_action only: :issues do
|
||||
push_frontend_feature_flag(:or_issuable_queries, group)
|
||||
push_frontend_feature_flag(:frontend_caching, group)
|
||||
push_force_frontend_feature_flag(:work_items, group.work_items_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_beta, group.work_items_beta_feature_flag_enabled?)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ class Projects::BadgesController < Projects::ApplicationController
|
|||
def pipeline
|
||||
pipeline_status = Gitlab::Ci::Badge::Pipeline::Status
|
||||
.new(project, params[:ref], opts: {
|
||||
ignore_skipped: params[:ignore_skipped],
|
||||
key_text: params[:key_text],
|
||||
key_width: params[:key_width]
|
||||
})
|
||||
ignore_skipped: params[:ignore_skipped],
|
||||
key_text: params[:key_text],
|
||||
key_width: params[:key_width]
|
||||
})
|
||||
|
||||
render_badge pipeline_status
|
||||
end
|
||||
|
|
@ -24,13 +24,13 @@ class Projects::BadgesController < Projects::ApplicationController
|
|||
def coverage
|
||||
coverage_report = Gitlab::Ci::Badge::Coverage::Report
|
||||
.new(project, params[:ref], opts: {
|
||||
job: params[:job],
|
||||
key_text: params[:key_text],
|
||||
key_width: params[:key_width],
|
||||
min_good: params[:min_good],
|
||||
min_acceptable: params[:min_acceptable],
|
||||
min_medium: params[:min_medium]
|
||||
})
|
||||
job: params[:job],
|
||||
key_text: params[:key_text],
|
||||
key_width: params[:key_width],
|
||||
min_good: params[:min_good],
|
||||
min_acceptable: params[:min_acceptable],
|
||||
min_medium: params[:min_medium]
|
||||
})
|
||||
|
||||
render_badge coverage_report
|
||||
end
|
||||
|
|
@ -38,11 +38,11 @@ class Projects::BadgesController < Projects::ApplicationController
|
|||
def release
|
||||
latest_release = Gitlab::Ci::Badge::Release::LatestRelease
|
||||
.new(project, current_user, opts: {
|
||||
key_text: params[:key_text],
|
||||
key_width: params[:key_width],
|
||||
value_width: params[:value_width],
|
||||
order_by: params[:order_by]
|
||||
})
|
||||
key_text: params[:key_text],
|
||||
key_width: params[:key_width],
|
||||
value_width: params[:value_width],
|
||||
order_by: params[:order_by]
|
||||
})
|
||||
|
||||
render_badge latest_release
|
||||
end
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
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(:group_multi_select_tokens, project)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ module Repositories
|
|||
|
||||
def error_payload(message, custom_attrs = {})
|
||||
custom_attrs.merge({
|
||||
message: message,
|
||||
documentation_url: help_url
|
||||
})
|
||||
message: message,
|
||||
documentation_url: help_url
|
||||
})
|
||||
end
|
||||
|
||||
def split_by_owner(locks)
|
||||
|
|
|
|||
|
|
@ -373,8 +373,7 @@ class IssuableFinder
|
|||
|
||||
def by_author(items)
|
||||
Issuables::AuthorFilter.new(
|
||||
params: original_params,
|
||||
or_filters_enabled: or_filters_enabled?
|
||||
params: original_params
|
||||
).filter(items)
|
||||
end
|
||||
|
||||
|
|
@ -385,8 +384,7 @@ class IssuableFinder
|
|||
def assignee_filter
|
||||
strong_memoize(:assignee_filter) do
|
||||
Issuables::AssigneeFilter.new(
|
||||
params: original_params,
|
||||
or_filters_enabled: or_filters_enabled?
|
||||
params: original_params
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -400,8 +398,7 @@ class IssuableFinder
|
|||
Issuables::LabelFilter.new(
|
||||
params: original_params,
|
||||
project: params.project,
|
||||
group: params.group,
|
||||
or_filters_enabled: or_filters_enabled?
|
||||
group: params.group
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -492,16 +489,6 @@ class IssuableFinder
|
|||
Issuables::CrmOrganizationFilter.new(params: original_params).filter(items)
|
||||
end
|
||||
|
||||
def or_filters_enabled?
|
||||
strong_memoize(:or_filters_enabled) do
|
||||
Feature.enabled?(:or_issuable_queries, feature_flag_scope)
|
||||
end
|
||||
end
|
||||
|
||||
def feature_flag_scope
|
||||
params.group || params.project
|
||||
end
|
||||
|
||||
def can_filter_by_crm_contact?
|
||||
current_user&.can?(:read_crm_contact, root_group)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ module Issuables
|
|||
end
|
||||
|
||||
def by_assignee_union(issuables)
|
||||
return issuables unless or_filters_enabled? && has_assignee_param?(or_params)
|
||||
return issuables unless has_assignee_param?(or_params)
|
||||
|
||||
issuables.assigned_to(assignee_ids(or_params))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module Issuables
|
|||
end
|
||||
|
||||
def by_author_union(issuables)
|
||||
return issuables unless or_filters_enabled? && or_params&.fetch(:author_username, false).present?
|
||||
return issuables unless or_params&.fetch(:author_username, false).present?
|
||||
|
||||
issuables.authored(User.by_username(or_params[:author_username]))
|
||||
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/419221")
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@ module Issuables
|
|||
FILTER_NONE = 'none'
|
||||
FILTER_ANY = 'any'
|
||||
|
||||
def initialize(params:, or_filters_enabled: false)
|
||||
def initialize(params:)
|
||||
@params = params
|
||||
@or_filters_enabled = or_filters_enabled
|
||||
end
|
||||
|
||||
def filter
|
||||
|
|
@ -25,9 +24,5 @@ module Issuables
|
|||
def not_params
|
||||
params[:not]
|
||||
end
|
||||
|
||||
def or_filters_enabled?
|
||||
@or_filters_enabled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ module Issuables
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def by_label_union(issuables)
|
||||
return issuables unless or_filters_enabled? && label_names_from_or_params.present?
|
||||
return issuables unless label_names_from_or_params.present?
|
||||
|
||||
if root_namespace
|
||||
all_label_ids = find_label_ids(label_names_from_or_params).flatten
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ module Mutations
|
|||
|
||||
def create_note_params(noteable, args)
|
||||
super(noteable, args).merge({
|
||||
type: 'DiffNote',
|
||||
position: position(noteable, args),
|
||||
merge_request_diff_head_sha: args[:position][:head_sha]
|
||||
})
|
||||
type: 'DiffNote',
|
||||
position: position(noteable, args),
|
||||
merge_request_diff_head_sha: args[:position][:head_sha]
|
||||
})
|
||||
end
|
||||
|
||||
def position(noteable, args)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ module Mutations
|
|||
|
||||
def create_note_params(noteable, args)
|
||||
super(noteable, args).merge({
|
||||
type: 'DiffNote',
|
||||
position: position(noteable, args)
|
||||
})
|
||||
type: 'DiffNote',
|
||||
position: position(noteable, args)
|
||||
})
|
||||
end
|
||||
|
||||
def position(noteable, args)
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ module Mutations
|
|||
end
|
||||
|
||||
super(noteable, args).merge({
|
||||
in_reply_to_discussion_id: discussion_id,
|
||||
merge_request_diff_head_sha: args[:merge_request_diff_head_sha]
|
||||
})
|
||||
in_reply_to_discussion_id: discussion_id,
|
||||
merge_request_diff_head_sha: args[:merge_request_diff_head_sha]
|
||||
})
|
||||
end
|
||||
|
||||
def authorize_discussion!(discussion)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module Resolvers
|
|||
alias_method :list, :object
|
||||
|
||||
def resolve(**args)
|
||||
filters = item_filters(args[:filters], list.board.resource_parent)
|
||||
filters = item_filters(args[:filters])
|
||||
mutually_exclusive_milestone_args!(filters)
|
||||
|
||||
filter_params = filters.merge(board_id: list.board.id, id: list.id)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ module Resolvers
|
|||
|
||||
def resolve(id: nil, issue_filters: {})
|
||||
Gitlab::Graphql::Lazy.with_value(find_list(id: id)) do |list|
|
||||
context.scoped_set!(:issue_filters, item_filters(issue_filters, list&.board&.resource_parent))
|
||||
context.scoped_set!(:issue_filters, item_filters(issue_filters))
|
||||
list if authorized_resource?(list)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module Resolvers
|
|||
|
||||
def resolve_with_lookahead(id: nil, issue_filters: {})
|
||||
lists = board_lists(id)
|
||||
context.scoped_set!(:issue_filters, item_filters(issue_filters, board.resource_parent))
|
||||
context.scoped_set!(:issue_filters, item_filters(issue_filters))
|
||||
|
||||
List.preload_preferences_for_user(lists, current_user) if load_preferences?
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module BoardItemFilterable
|
|||
|
||||
private
|
||||
|
||||
def item_filters(args, resource_parent)
|
||||
def item_filters(args)
|
||||
filters = args.to_h
|
||||
|
||||
set_filter_values(filters)
|
||||
|
|
@ -13,11 +13,6 @@ module BoardItemFilterable
|
|||
set_filter_values(filters[:not]) if filters[:not]
|
||||
|
||||
if filters[:or]
|
||||
if ::Feature.disabled?(:or_issuable_queries, resource_parent)
|
||||
raise ::Gitlab::Graphql::Errors::ArgumentError,
|
||||
"'or' arguments are only allowed when the `or_issuable_queries` feature flag is enabled."
|
||||
end
|
||||
|
||||
rewrite_param_name(filters[:or], :author_usernames, :author_username)
|
||||
rewrite_param_name(filters[:or], :assignee_usernames, :assignee_username)
|
||||
rewrite_param_name(filters[:or], :label_names, :label_name)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ module Resolvers
|
|||
default_value: :created_desc
|
||||
|
||||
GROUP_SORT_TO_PARAMS_MAP = SORT_TO_PARAMS_MAP.merge({
|
||||
project_path_desc: { order_by: 'project_path', sort: 'desc' },
|
||||
project_path_asc: { order_by: 'project_path', sort: 'asc' }
|
||||
}).freeze
|
||||
project_path_desc: { order_by: 'project_path', sort: 'desc' },
|
||||
project_path_asc: { order_by: 'project_path', sort: 'asc' }
|
||||
}).freeze
|
||||
|
||||
def resolve(sort:, **filters)
|
||||
return unless packages_available?
|
||||
|
|
|
|||
|
|
@ -104,11 +104,6 @@ module Resolvers
|
|||
end
|
||||
|
||||
def ready?(**args)
|
||||
if args[:or].present? && or_issuable_queries_disabled?
|
||||
raise ::Gitlab::Graphql::Errors::ArgumentError,
|
||||
"'or' arguments are only allowed when the `or_issuable_queries` feature flag is enabled."
|
||||
end
|
||||
|
||||
args[:not] = args[:not].to_h if args[:not]
|
||||
args[:or] = args[:or].to_h if args[:or]
|
||||
|
||||
|
|
@ -117,14 +112,6 @@ module Resolvers
|
|||
|
||||
private
|
||||
|
||||
def or_issuable_queries_disabled?
|
||||
if respond_to?(:resource_parent, true)
|
||||
::Feature.disabled?(:or_issuable_queries, resource_parent)
|
||||
else
|
||||
::Feature.disabled?(:or_issuable_queries)
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_finder_params(args)
|
||||
params = super(args)
|
||||
params[:not] = params[:not].to_h if params[:not]
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: or_issuable_queries
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54444
|
||||
rollout_issue_url:
|
||||
milestone: '13.10'
|
||||
type: development
|
||||
group: group::project management
|
||||
default_enabled: true
|
||||
|
|
@ -1,5 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
module Tasks
|
||||
module DatabaseTasks
|
||||
def migrate_status
|
||||
# rubocop:disable Database/MultipleDatabases -- From Rails base code which doesn't follow our style guide
|
||||
# rubocop:disable Rails/Output -- From Rails base code which doesn't follow our style guide
|
||||
unless ActiveRecord::Base.connection.schema_migration.table_exists?
|
||||
Kernel.abort "Schema migrations table does not exist yet."
|
||||
end
|
||||
|
||||
puts "\ndatabase: #{ActiveRecord::Base.connection_db_config.database}\n\n"
|
||||
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} #{'Type'.ljust(7)} #{'Milestone'.ljust(11)} Name"
|
||||
puts "-" * 50
|
||||
status_with_milestones.each do |status, version, type, milestone, name|
|
||||
puts "#{status.center(8)} #{version.ljust(14)} #{type.ljust(7)} #{milestone.ljust(11)} #{name}"
|
||||
end
|
||||
puts
|
||||
# rubocop:enable Rails/Output
|
||||
# rubocop:enable Database/MultipleDatabases
|
||||
end
|
||||
|
||||
def status_with_milestones
|
||||
# rubocop:disable Database/MultipleDatabases -- From Rails base code which doesn't follow our style guide
|
||||
versions = ActiveRecord::SchemaMigration.all_versions.map(&:to_i)
|
||||
ActiveRecord::Base.connection.migration_context.migrations.sort_by(&:version).map do |m|
|
||||
[
|
||||
(versions.include?(m.version.to_i) ? 'up' : 'down'),
|
||||
m.version.to_s,
|
||||
m.version.try(:type).to_s,
|
||||
m.try(:milestone).to_s,
|
||||
m.name
|
||||
]
|
||||
end
|
||||
# rubocop:enable Database/MultipleDatabases
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unless Gitlab.ee?
|
||||
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
|
|
|
|||
|
|
@ -1,26 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Gitlab::Database::Migrations::LockRetryMixin.patch!
|
||||
Gitlab::Database::Migrations::MigrationOrderMixin.patch!
|
||||
Gitlab::Database::Migrations::PgBackendPid.patch!
|
||||
Gitlab::Database::Migrations::RunnerBackoff::ActiveRecordMixin.patch!
|
||||
|
||||
# This patch rolls back to Rails 6.1 behavior:
|
||||
#
|
||||
# https://github.com/rails/rails/blob/v6.1.4.3/activerecord/lib/active_record/migration.rb#L1044
|
||||
#
|
||||
# It fixes the tests that relies on the fact that the same constants have the same object_id.
|
||||
# For example to make sure that stub_const works correctly.
|
||||
#
|
||||
# It overrides the new behavior that removes the constant first:
|
||||
#
|
||||
# https://github.com/rails/rails/blob/v7.0.5/activerecord/lib/active_record/migration.rb#L1054
|
||||
module ActiveRecord
|
||||
class MigrationProxy
|
||||
private
|
||||
|
||||
def load_migration
|
||||
require(File.expand_path(filename))
|
||||
name.constantize.new(name, version)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16956,7 +16956,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="boardepicancestorsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
|
||||
| <a id="boardepicancestorsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
|
||||
| <a id="boardepicancestorsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
|
||||
| <a id="boardepicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in GitLab 15.9. **Status**: Experiment. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="boardepicancestorsor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="boardepicancestorssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="boardepicancestorssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
|
||||
| <a id="boardepicancestorsstate"></a>`state` | [`EpicState`](#epicstate) | Filter epics by state. |
|
||||
|
|
@ -16993,7 +16993,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="boardepicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
|
||||
| <a id="boardepicchildrenmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
|
||||
| <a id="boardepicchildrennot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
|
||||
| <a id="boardepicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in GitLab 15.9. **Status**: Experiment. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="boardepicchildrenor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="boardepicchildrensearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="boardepicchildrensort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
|
||||
| <a id="boardepicchildrenstate"></a>`state` | [`EpicState`](#epicstate) | Filter epics by state. |
|
||||
|
|
@ -20130,7 +20130,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="epicancestorsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
|
||||
| <a id="epicancestorsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
|
||||
| <a id="epicancestorsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
|
||||
| <a id="epicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in GitLab 15.9. **Status**: Experiment. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="epicancestorsor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="epicancestorssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="epicancestorssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
|
||||
| <a id="epicancestorsstate"></a>`state` | [`EpicState`](#epicstate) | Filter epics by state. |
|
||||
|
|
@ -20167,7 +20167,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="epicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
|
||||
| <a id="epicchildrenmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
|
||||
| <a id="epicchildrennot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
|
||||
| <a id="epicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in GitLab 15.9. **Status**: Experiment. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="epicchildrenor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="epicchildrensearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="epicchildrensort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
|
||||
| <a id="epicchildrenstate"></a>`state` | [`EpicState`](#epicstate) | Filter epics by state. |
|
||||
|
|
@ -21672,7 +21672,7 @@ Returns [`Epic`](#epic).
|
|||
| <a id="groupepicmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
|
||||
| <a id="groupepicmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
|
||||
| <a id="groupepicnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
|
||||
| <a id="groupepicor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in GitLab 15.9. **Status**: Experiment. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="groupepicor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="groupepicsearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="groupepicsort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
|
||||
| <a id="groupepicstate"></a>`state` | [`EpicState`](#epicstate) | Filter epics by state. |
|
||||
|
|
@ -21721,7 +21721,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="groupepicsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
|
||||
| <a id="groupepicsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
|
||||
| <a id="groupepicsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
|
||||
| <a id="groupepicsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in GitLab 15.9. **Status**: Experiment. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="groupepicsor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="groupepicssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="groupepicssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
|
||||
| <a id="groupepicsstate"></a>`state` | [`EpicState`](#epicstate) | Filter epics by state. |
|
||||
|
|
@ -37539,7 +37539,7 @@ Filter parameters for projects to be aggregated for DORA metrics.
|
|||
| <a id="epicfilterslabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
|
||||
| <a id="epicfiltersmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
|
||||
| <a id="epicfiltersnot"></a>`not` | [`NegatedEpicBoardIssueInput`](#negatedepicboardissueinput) | Negated epic arguments. |
|
||||
| <a id="epicfiltersor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
|
||||
| <a id="epicfiltersor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. |
|
||||
| <a id="epicfilterssearch"></a>`search` | [`String`](#string) | Search query for epic title or description. |
|
||||
|
||||
### `EpicTreeNodeFieldsInputType`
|
||||
|
|
|
|||
|
|
@ -265,15 +265,10 @@ To filter:
|
|||
### Filter with the OR operator
|
||||
|
||||
> - OR filtering for labels and authors was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/382969) in GitLab 15.9 [with a flag](../../../administration/feature_flags.md) named `or_issuable_queries`. Disabled by default.
|
||||
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104292) in GitLab 15.9.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/296031) in GitLab 17.0. Feature flag `or_issuable_queries` removed.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available.
|
||||
To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `or_issuable_queries`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
This feature is not ready for production use.
|
||||
|
||||
When this feature is enabled, you can use the OR operator (**is one of: `||`**)
|
||||
when you [filter the list of epics](#filter-the-list-of-epics) by:
|
||||
You can use the OR operator (**is one of: `||`**) when you [filter the list of epics](#filter-the-list-of-epics) by:
|
||||
|
||||
- Authors
|
||||
- Labels
|
||||
|
|
|
|||
|
|
@ -510,14 +510,9 @@ It's a limitation of PostgreSQL full text search.
|
|||
> - OR filtering for author and assignee was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23532) in GitLab 15.6 [with a flag](../../../administration/feature_flags.md) named `or_issuable_queries`. Disabled by default.
|
||||
> - OR filtering for label was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23532) in GitLab 15.8 [with a flag](../../../administration/feature_flags.md) named `or_issuable_queries`. Disabled by default.
|
||||
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104292) in GitLab 15.9.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/296031) in GitLab 17.0. Feature flag `or_issuable_queries` removed.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is available.
|
||||
To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `or_issuable_queries`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is available.
|
||||
|
||||
When this feature is enabled, you can use the OR operator (**is one of: `||`**)
|
||||
when you [filter the list of issues](#filter-the-list-of-issues) by:
|
||||
You can use the OR operator (**is one of: `||`**) when you [filter the list of issues](#filter-the-list-of-issues) by:
|
||||
|
||||
- Assignees
|
||||
- Author
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ module Gitlab
|
|||
end
|
||||
|
||||
class V2_2 < V2_1
|
||||
def self.inherited(subclass)
|
||||
super
|
||||
subclass.instance_variable_set(:@_defining_file, caller_locations.first.absolute_path)
|
||||
end
|
||||
|
||||
include Gitlab::Database::Migrations::MilestoneMixin
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# The patch to load_migration rolls back to Rails 6.1 behavior:
|
||||
#
|
||||
# https://github.com/rails/rails/blob/v6.1.4.3/activerecord/lib/active_record/migration.rb#L1044
|
||||
#
|
||||
# It fixes the tests that relies on the fact that the same constants have the same object_id.
|
||||
# For example to make sure that stub_const works correctly.
|
||||
#
|
||||
# It overrides the new behavior that removes the constant first:
|
||||
#
|
||||
# https://github.com/rails/rails/blob/v7.0.5/activerecord/lib/active_record/migration.rb#L1054
|
||||
|
||||
# The following is a reminder for when we upgrade to Rails 7.1. In particular,
|
||||
# we need to pay special attention to ensure that our ActiveRecord overrides are
|
||||
# compatible.
|
||||
|
||||
if ::ActiveRecord::VERSION::STRING >= "7.1"
|
||||
raise 'New version of active-record detected, please remove or update this patch'
|
||||
end
|
||||
|
||||
module Gitlab
|
||||
module Database
|
||||
module Migrations
|
||||
module MigrationOrderMixin
|
||||
module MigrationProxyOverrides
|
||||
def version
|
||||
migration.version
|
||||
end
|
||||
|
||||
def milestone
|
||||
migration.try(:milestone)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_migration
|
||||
require(File.expand_path(filename))
|
||||
|
||||
name.constantize.new(name, self[:version])
|
||||
end
|
||||
end
|
||||
|
||||
module MigratorOverrides
|
||||
def current_version
|
||||
migrations
|
||||
.sort_by(&:version)
|
||||
.reverse
|
||||
.find { |m| migrated.include?(m.version) }
|
||||
.try(:version) || 0
|
||||
end
|
||||
end
|
||||
|
||||
def self.patch!
|
||||
ActiveRecord::MigrationProxy.prepend(MigrationProxyOverrides)
|
||||
ActiveRecord::Migrator.prepend(MigratorOverrides)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -19,10 +19,23 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def initialize(name = self.class.name, version = nil, _type = nil)
|
||||
def type_from_path(path)
|
||||
dir = File.dirname(path)
|
||||
return :post if dir.match?(%r{db/(\w+/)?post_migrate})
|
||||
return :regular if dir.match?(%r{db/(\w+/)?migrate})
|
||||
|
||||
raise 'unknown migration path'
|
||||
end
|
||||
|
||||
def initialize(name = self.class.name, version = nil)
|
||||
raise MilestoneNotSetError, "Milestone is not set for #{name}" if milestone.nil?
|
||||
|
||||
super(name, version)
|
||||
@version = Gitlab::Database::Migrations::Version.new(
|
||||
version,
|
||||
milestone,
|
||||
type_from_path(self.class.instance_variable_get(:@_defining_file))
|
||||
)
|
||||
end
|
||||
|
||||
def milestone # rubocop:disable Lint/DuplicateMethods
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module Gitlab
|
|||
|
||||
def initialize(timestamp, milestone, type)
|
||||
@timestamp = timestamp
|
||||
@milestone = milestone
|
||||
@milestone = Gitlab::VersionInfo.parse_from_milestone(milestone)
|
||||
self.type = type
|
||||
end
|
||||
|
||||
|
|
@ -29,6 +29,10 @@ module Gitlab
|
|||
@type_value = TYPE_VALUES.fetch(value.to_sym) { raise InvalidTypeError }
|
||||
end
|
||||
|
||||
def milestone=(milestone_str)
|
||||
@milestone = Gitlab::VersionInfo.parse_from_milestone(milestone_str)
|
||||
end
|
||||
|
||||
def regular?
|
||||
@type_value == TYPE_VALUES[:regular]
|
||||
end
|
||||
|
|
@ -38,9 +42,12 @@ module Gitlab
|
|||
end
|
||||
|
||||
def <=>(other)
|
||||
return 0 if other.is_a?(Integer) && @timestamp == other
|
||||
|
||||
return 1 unless other.is_a?(self.class)
|
||||
|
||||
return milestone <=> other.milestone if milestone != other.milestone
|
||||
compare_milestones = milestone <=> other.milestone
|
||||
return compare_milestones if compare_milestones != 0
|
||||
|
||||
return @type_value <=> other.type_value if @type_value != other.type_value
|
||||
|
||||
|
|
@ -55,7 +62,7 @@ module Gitlab
|
|||
@timestamp.to_i
|
||||
end
|
||||
|
||||
def coerce(_other)
|
||||
def coerce(_)
|
||||
[-1, timestamp.to_i]
|
||||
end
|
||||
|
||||
|
|
@ -68,7 +75,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def hash
|
||||
[timestamp, milestone, @type_value].hash
|
||||
timestamp.hash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ActiveRecord::Tasks::DatabaseTasks, feature_category: :database do
|
||||
let(:db_config) { Gitlab::Database.database_base_models.first }
|
||||
|
||||
it 'does not raise an error' do
|
||||
expect { described_class.migrate_status }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
|
@ -12,10 +12,6 @@ RSpec.describe 'Group issues page', feature_category: :groups_and_projects do
|
|||
let(:project_with_issues_disabled) { create(:project, :issues_disabled, group: group) }
|
||||
let(:path) { issues_group_path(group) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
end
|
||||
|
||||
context 'with shared examples', :js do
|
||||
let(:issuable) { create(:issue, project: project, title: "this is my created issuable") }
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ RSpec.describe 'Groups > User sees users dropdowns in issuables list', :js, feat
|
|||
let!(:project) { create(:project, group: group) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
group.add_developer(user_in_dropdown)
|
||||
sign_in(user_in_dropdown)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@ RSpec.describe 'Dropdown assignee', :js, feature_category: :team_planning do
|
|||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
end
|
||||
|
||||
describe 'behavior' do
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ RSpec.describe 'Dropdown author', :js, feature_category: :team_planning do
|
|||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ RSpec.describe 'Dropdown base', :js, feature_category: :team_planning do
|
|||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ RSpec.describe 'Dropdown emoji', :js, feature_category: :team_planning do
|
|||
let_it_be(:award_emoji_star) { create(:award_emoji, name: 'star', user: user, awardable: issue) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
create_list(:award_emoji, 2, user: user, name: 'thumbsup')
|
||||
create_list(:award_emoji, 1, user: user, name: 'thumbsdown')
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ RSpec.describe 'Dropdown hint', :js, feature_category: :team_planning do
|
|||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
end
|
||||
|
||||
|
|
@ -68,11 +67,11 @@ RSpec.describe 'Dropdown hint', :js, feature_category: :team_planning do
|
|||
expect_visible_suggestions_list
|
||||
expect_suggestion '='
|
||||
|
||||
click_link '= is'
|
||||
click_link 'is ='
|
||||
|
||||
expect_visible_suggestions_list
|
||||
expect_token_segment 'Author'
|
||||
expect_token_segment '='
|
||||
expect_token_segment 'is'
|
||||
expect_empty_search_term
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ RSpec.describe 'Dropdown label', :js, feature_category: :team_planning do
|
|||
let_it_be(:label) { create(:label, project: project, title: 'bug-label') }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ RSpec.describe 'Dropdown milestone', :js, feature_category: :team_planning do
|
|||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ RSpec.describe 'Dropdown release', :js, feature_category: :team_planning do
|
|||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ RSpec.describe 'Filter issues', :js, feature_category: :team_planning do
|
|||
end
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_maintainer(user)
|
||||
|
||||
create(:issue, project: project, author: user2, title: "Bug report 1")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ RSpec.describe 'Visual tokens', :js, feature_category: :team_planning do
|
|||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
project.add_member(user, :maintainer)
|
||||
project.add_member(user_rock, :maintainer)
|
||||
sign_in(user)
|
||||
|
|
@ -91,7 +90,7 @@ RSpec.describe 'Visual tokens', :js, feature_category: :team_planning do
|
|||
expect_suggestion '='
|
||||
expect_suggestion '!='
|
||||
|
||||
click_on '= is'
|
||||
click_on 'is ='
|
||||
|
||||
expect_suggestion(user.name)
|
||||
expect_suggestion(user_rock.name)
|
||||
|
|
@ -111,10 +110,10 @@ RSpec.describe 'Visual tokens', :js, feature_category: :team_planning do
|
|||
|
||||
it 'does retain hint token when mix of typing and clicks are performed' do
|
||||
select_tokens 'Label'
|
||||
click_on '= is'
|
||||
click_on 'is ='
|
||||
|
||||
expect_token_segment 'Label'
|
||||
expect_token_segment '='
|
||||
expect_token_segment 'is'
|
||||
end
|
||||
|
||||
describe 'Any/None option' do
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ RSpec.describe 'Labels Hierarchy', :js, feature_category: :team_planning do
|
|||
let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') }
|
||||
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
grandparent.add_owner(user)
|
||||
|
||||
sign_in(user)
|
||||
|
|
@ -61,7 +60,7 @@ RSpec.describe 'Labels Hierarchy', :js, feature_category: :team_planning do
|
|||
within_testid('filtered-search-input') do
|
||||
click_filtered_search_bar
|
||||
click_on 'Label'
|
||||
click_on '= is'
|
||||
click_on 'is ='
|
||||
click_on label.title
|
||||
send_keys :enter
|
||||
end
|
||||
|
|
@ -112,7 +111,7 @@ RSpec.describe 'Labels Hierarchy', :js, feature_category: :team_planning do
|
|||
within_testid('filtered-search-input') do
|
||||
click_filtered_search_bar
|
||||
click_on 'Label'
|
||||
click_on '= is'
|
||||
click_on 'is ='
|
||||
click_on label.title
|
||||
send_keys :enter
|
||||
end
|
||||
|
|
|
|||
|
|
@ -55,16 +55,6 @@ RSpec.describe MergeRequestsFinder, feature_category: :code_review_workflow do
|
|||
it 'returns merge requests created by any of the given users' do
|
||||
expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
end
|
||||
|
||||
it 'does not add any filter' do
|
||||
expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request4, merge_request5)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with nonexistent author ID and MR term using CTE for search' do
|
||||
|
|
|
|||
7
spec/fixtures/migrations/db/migration_ordering/migrate/30000000000000_ordering_test_one.rb
vendored
Normal file
7
spec/fixtures/migrations/db/migration_ordering/migrate/30000000000000_ordering_test_one.rb
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class OrderingTestOne < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
# no op
|
||||
end
|
||||
end
|
||||
7
spec/fixtures/migrations/db/migration_ordering/migrate/30000000000001_ordering_test_two.rb
vendored
Normal file
7
spec/fixtures/migrations/db/migration_ordering/migrate/30000000000001_ordering_test_two.rb
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class OrderingTestTwo < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
# no op
|
||||
end
|
||||
end
|
||||
|
|
@ -40,6 +40,7 @@ describe('Feature flags strategy', () => {
|
|||
|
||||
const findStrategyParameters = () => wrapper.findComponent(StrategyParameters);
|
||||
const findDocsLinks = () => wrapper.findAllComponents(GlLink);
|
||||
const findToken = () => wrapper.findComponent(GlToken);
|
||||
|
||||
const factory = (
|
||||
opts = {
|
||||
|
|
@ -140,7 +141,7 @@ describe('Feature flags strategy', () => {
|
|||
});
|
||||
|
||||
it('should revert to all-environments scope when last scope is removed', async () => {
|
||||
const token = wrapper.findComponent(GlToken);
|
||||
const token = findToken();
|
||||
token.vm.$emit('close');
|
||||
await nextTick();
|
||||
expect(wrapper.findAllComponents(GlToken)).toHaveLength(0);
|
||||
|
|
@ -154,6 +155,34 @@ describe('Feature flags strategy', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with a single environment scope defined and existing feature flag', () => {
|
||||
let strategy;
|
||||
beforeEach(() => {
|
||||
strategy = {
|
||||
name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
|
||||
parameters: { percentage: '50', groupId: 'default' },
|
||||
scopes: [{ environmentScope: 'production', id: 1 }],
|
||||
};
|
||||
const propsData = { strategy, index: 0 };
|
||||
factory({ propsData, provide });
|
||||
});
|
||||
|
||||
it('should revert single environment scope when last scope is removed', async () => {
|
||||
findToken().vm.$emit('close');
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.emitted('change')).toEqual([
|
||||
[
|
||||
{
|
||||
name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
|
||||
parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
|
||||
scopes: [{ environmentScope: 'production', id: 1, shouldBeDestroyed: true }],
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with an all-environments scope defined', () => {
|
||||
let strategy;
|
||||
|
||||
|
|
@ -169,7 +198,8 @@ describe('Feature flags strategy', () => {
|
|||
|
||||
it('should change the parameters if a different strategy is chosen', async () => {
|
||||
const select = wrapper.findComponent(GlFormSelect);
|
||||
select.setValue(ROLLOUT_STRATEGY_ALL_USERS);
|
||||
select.element.value = ROLLOUT_STRATEGY_ALL_USERS;
|
||||
select.trigger('change');
|
||||
await nextTick();
|
||||
expect(last(wrapper.emitted('change'))).toEqual([
|
||||
{
|
||||
|
|
@ -185,7 +215,7 @@ describe('Feature flags strategy', () => {
|
|||
dropdown.vm.$emit('add', 'production');
|
||||
await nextTick();
|
||||
expect(wrapper.findAllComponents(GlToken)).toHaveLength(1);
|
||||
expect(wrapper.findComponent(GlToken).text()).toBe('production');
|
||||
expect(findToken().text()).toBe('production');
|
||||
});
|
||||
|
||||
it('should display all selected scopes', async () => {
|
||||
|
|
@ -237,7 +267,7 @@ describe('Feature flags strategy', () => {
|
|||
dropdown.vm.$emit('add', 'production');
|
||||
await nextTick();
|
||||
expect(wrapper.findAllComponents(GlToken)).toHaveLength(1);
|
||||
expect(wrapper.findComponent(GlToken).text()).toBe('production');
|
||||
expect(findToken().text()).toBe('production');
|
||||
});
|
||||
|
||||
it('should display all selected scopes', async () => {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,9 @@ RSpec.describe Gitlab::Database::Migrations::LockRetryMixin, feature_category: :
|
|||
|
||||
let(:migration) do
|
||||
Class.new(Gitlab::Database::Migration[2.2]) do
|
||||
milestone 16.10
|
||||
milestone '16.10'
|
||||
|
||||
@_defining_file = 'db/migrate/1_test.rb'
|
||||
|
||||
def change
|
||||
# no-op
|
||||
|
|
|
|||
|
|
@ -12,12 +12,22 @@ RSpec.describe Gitlab::Database::Migrations::MilestoneMixin, feature_category: :
|
|||
end
|
||||
|
||||
let(:migration_mixin) do
|
||||
Class.new(Gitlab::Database::Migration[2.2])
|
||||
Class.new(Gitlab::Database::Migration[2.2]) do
|
||||
@_defining_file = 'db/migrate/00000000000000_example.rb'
|
||||
end
|
||||
end
|
||||
|
||||
let(:migration_mixin_version) do
|
||||
Class.new(Gitlab::Database::Migration[2.2]) do
|
||||
milestone '16.4'
|
||||
@_defining_file = 'db/migrate/00000000000000_example.rb'
|
||||
end
|
||||
end
|
||||
|
||||
let(:migration_mixin_version_post) do
|
||||
Class.new(Gitlab::Database::Migration[2.2]) do
|
||||
milestone '16.4'
|
||||
@_defining_file = 'db/post_migrate/00000000000000_example.rb'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -30,7 +40,7 @@ RSpec.describe Gitlab::Database::Migrations::MilestoneMixin, feature_category: :
|
|||
context 'when the mixin is included' do
|
||||
context 'when a milestone is not specified' do
|
||||
it "raises MilestoneNotSetError" do
|
||||
expect { migration_mixin.new(4, 4, :regular) }.to raise_error(
|
||||
expect { migration_mixin.new(4, 4) }.to raise_error(
|
||||
"#{described_class}::MilestoneNotSetError".constantize
|
||||
)
|
||||
end
|
||||
|
|
@ -38,7 +48,7 @@ RSpec.describe Gitlab::Database::Migrations::MilestoneMixin, feature_category: :
|
|||
|
||||
context 'when a milestone is specified' do
|
||||
it "does not raise an error" do
|
||||
expect { migration_mixin_version.new(4, 4, :regular) }.not_to raise_error
|
||||
expect { migration_mixin_version.new(4, 4) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -47,5 +57,17 @@ RSpec.describe Gitlab::Database::Migrations::MilestoneMixin, feature_category: :
|
|||
expect { migration_mixin_version.new }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context "when it's a regular migration" do
|
||||
it 'is a regular migration' do
|
||||
expect(migration_mixin_version.new(4, 4).version.type).to eq(:regular)
|
||||
end
|
||||
end
|
||||
|
||||
context "when it's a post-deployment migration" do
|
||||
it 'is a regular migration' do
|
||||
expect(migration_mixin_version_post.new(4, 4).version.type).to eq(:post)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,32 +7,35 @@ RSpec.describe Gitlab::Database::Migrations::Version, feature_category: :databas
|
|||
[
|
||||
4,
|
||||
5,
|
||||
described_class.new(6, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(6, '10.3', :regular),
|
||||
7,
|
||||
described_class.new(8, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(9, Gitlab::VersionInfo.parse_from_milestone('10.4'), :regular),
|
||||
described_class.new(10, Gitlab::VersionInfo.parse_from_milestone('10.3'), :post),
|
||||
described_class.new(11, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular)
|
||||
described_class.new(8, '10.3', :regular),
|
||||
described_class.new(9, '10.4', :regular),
|
||||
described_class.new(10, '10.3', :post),
|
||||
described_class.new(11, '10.3', :regular),
|
||||
described_class.new(12, '10.15', :regular)
|
||||
]
|
||||
end
|
||||
|
||||
describe "#<=>" do
|
||||
it 'sorts by existence of milestone, then by milestone, then by type, then by timestamp when sorted by version' do
|
||||
expect(test_versions.sort.map(&:to_i)).to eq [4, 5, 7, 6, 8, 11, 10, 9]
|
||||
expect(test_versions.sort.map(&:to_i)).to eq [4, 5, 7, 6, 8, 11, 10, 9, 12]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'initialize' do
|
||||
context 'when the type is :post or :regular' do
|
||||
it 'does not raise an error' do
|
||||
expect { described_class.new(4, 4, :regular) }.not_to raise_error
|
||||
expect { described_class.new(4, 4, :post) }.not_to raise_error
|
||||
expect { described_class.new(4, '10.3', :regular) }.not_to raise_error
|
||||
expect { described_class.new(4, '10.3', :post) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the type is anything else' do
|
||||
it 'does not raise an error' do
|
||||
expect { described_class.new(4, 4, 'foo') }.to raise_error("#{described_class}::InvalidTypeError".constantize)
|
||||
expect do
|
||||
described_class.new(4, '10.3', 'foo')
|
||||
end.to raise_error("#{described_class}::InvalidTypeError".constantize)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -41,23 +44,23 @@ RSpec.describe Gitlab::Database::Migrations::Version, feature_category: :databas
|
|||
where(:version1, :version2, :expected_equality) do
|
||||
[
|
||||
[
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(4, '10.3', :regular),
|
||||
described_class.new(4, '10.3', :regular),
|
||||
true
|
||||
],
|
||||
[
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.4'), :regular),
|
||||
described_class.new(4, '10.3', :regular),
|
||||
described_class.new(4, '10.4', :regular),
|
||||
false
|
||||
],
|
||||
[
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :post),
|
||||
described_class.new(4, '10.3', :regular),
|
||||
described_class.new(4, '10.3', :post),
|
||||
false
|
||||
],
|
||||
[
|
||||
described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(5, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular),
|
||||
described_class.new(4, '10.3', :regular),
|
||||
described_class.new(5, '10.3', :regular),
|
||||
false
|
||||
]
|
||||
]
|
||||
|
|
@ -75,7 +78,7 @@ RSpec.describe Gitlab::Database::Migrations::Version, feature_category: :databas
|
|||
end
|
||||
|
||||
describe 'type' do
|
||||
subject { described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), migration_type) }
|
||||
subject { described_class.new(4, '10.3', migration_type) }
|
||||
|
||||
context 'when the migration is regular' do
|
||||
let(:migration_type) { :regular }
|
||||
|
|
@ -99,7 +102,7 @@ RSpec.describe Gitlab::Database::Migrations::Version, feature_category: :databas
|
|||
end
|
||||
|
||||
describe 'to_s' do
|
||||
subject { described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular) }
|
||||
subject { described_class.new(4, '10.3', :regular) }
|
||||
|
||||
it 'returns the given timestamp value as a string' do
|
||||
expect(subject.to_s).to eql('4')
|
||||
|
|
@ -107,7 +110,7 @@ RSpec.describe Gitlab::Database::Migrations::Version, feature_category: :databas
|
|||
end
|
||||
|
||||
describe 'hash' do
|
||||
subject { described_class.new(4, Gitlab::VersionInfo.parse_from_milestone('10.3'), :regular) }
|
||||
subject { described_class.new(4, '10.3', :regular) }
|
||||
|
||||
let(:expected_hash) { subject.hash }
|
||||
|
||||
|
|
@ -117,4 +120,14 @@ RSpec.describe Gitlab::Database::Migrations::Version, feature_category: :databas
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '=' do
|
||||
subject { described_class.new(4, '10.3', :regular) }
|
||||
|
||||
it 'correctly assigns a new milestone object parsed from a string' do
|
||||
subject.milestone = '14.6'
|
||||
expect(subject.milestone.major).to be(14)
|
||||
expect(subject.milestone.minor).to be(6)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -122,16 +122,6 @@ RSpec.describe 'get board lists', feature_category: :team_planning do
|
|||
|
||||
expect(issue_id).to contain_exactly(issue1.to_gid.to_s, issue2.to_gid.to_s)
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
it 'returns an error' do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
|
||||
subject
|
||||
|
||||
expect_graphql_errors_to_include("'or' arguments are only allowed when the `or_issuable_queries` feature flag is enabled.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -152,23 +152,6 @@ RSpec.describe 'get board lists', feature_category: :team_planning do
|
|||
|
||||
expect(lists_data[0]['node']['issuesCount']).to eq 2
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
it 'returns an error' do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
|
||||
post_graphql(
|
||||
query(
|
||||
id: global_id_of(label_list),
|
||||
issueFilters: { or: { assignee_usernames: [user.username, another_user.username] } }
|
||||
), current_user: user
|
||||
)
|
||||
|
||||
expect_graphql_errors_to_include(
|
||||
"'or' arguments are only allowed when the `or_issuable_queries` feature flag is enabled."
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -192,11 +192,7 @@ module FilteredSearchHelpers
|
|||
# Move mouse away to prevent invoking tooltips on usernames, which blocks the search input
|
||||
find_button('Search').hover
|
||||
|
||||
if token == '='
|
||||
click_on '= is'
|
||||
else
|
||||
click_on token
|
||||
end
|
||||
click_on token.to_s, match: :first
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
|
@ -252,35 +248,35 @@ module FilteredSearchHelpers
|
|||
end
|
||||
|
||||
def expect_assignee_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Assignee = #{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Assignee (=|is) #{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_unioned_assignee_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Assignee is one of #{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Assignee is one of #{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_author_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Author = #{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Author (=|is) #{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_label_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Label = #{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Label (=|is) #{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_negated_label_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Label != #{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Label (!=|is not one of) #{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_milestone_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Milestone = %#{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Milestone (=|is) %#{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_negated_milestone_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Milestone != %#{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Milestone (!=|is not) %#{Regexp.escape(value)}/
|
||||
end
|
||||
|
||||
def expect_epic_token(value)
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: "Epic = #{value}"
|
||||
expect(page).to have_css '.gl-filtered-search-token', text: /Epic (=|is) #{value}/
|
||||
end
|
||||
|
||||
def expect_search_term(value)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ RSpec.shared_examples 'multiple issue boards' do
|
|||
include ListboxHelpers
|
||||
|
||||
context 'authorized user' do
|
||||
before_all do
|
||||
create(:callout, feature_name: :board_add_new_column_trigger_popover, user: user)
|
||||
end
|
||||
|
||||
before do
|
||||
parent.add_maintainer(user)
|
||||
|
||||
|
|
|
|||
|
|
@ -219,16 +219,6 @@ RSpec.shared_examples 'issues or work items finder' do |factory, execute_context
|
|||
it 'returns items created by any of the given users' do
|
||||
expect(items).to contain_exactly(item3, item6)
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
end
|
||||
|
||||
it 'does not add any filter' do
|
||||
expect(items).to contain_exactly(item1, item2, item3, item4, item5, item6)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'filtering by NOT author ID' do
|
||||
|
|
@ -502,16 +492,6 @@ RSpec.shared_examples 'issues or work items finder' do |factory, execute_context
|
|||
it 'returns items that have at least one of the given labels' do
|
||||
expect(items).to contain_exactly(item2, item3)
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
end
|
||||
|
||||
it 'does not add any filter' do
|
||||
expect(items).to contain_exactly(item1, item2, item3, item4, item5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -152,20 +152,6 @@ RSpec.shared_examples 'graphql issue list request spec' do
|
|||
expect_graphql_errors_to_be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
let(:issue_filter_params) { { or: { assignee_usernames: [current_user.username] } } }
|
||||
|
||||
it 'returns an error' do
|
||||
stub_feature_flags(or_issuable_queries: false)
|
||||
|
||||
post_query
|
||||
|
||||
expect_graphql_errors_to_include(
|
||||
"'or' arguments are only allowed when the `or_issuable_queries` feature flag is enabled."
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering by a blank negated argument' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue