Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-02 09:09:17 +00:00
parent 4ea9f70a2f
commit 9cd5033338
38 changed files with 493 additions and 113 deletions

View File

@ -152,6 +152,12 @@ export default {
isLoading() {
return this.$apollo.queries.boardList.loading;
},
totalWeight() {
return this.boardList?.totalWeight;
},
canShowTotalWeight() {
return this.weightFeatureAvailable && !this.isLoading;
},
},
apollo: {
boardList: {
@ -356,7 +362,7 @@ export default {
<div v-if="weightFeatureAvailable && !isLoading">
<gl-sprintf :message="__('%{totalWeight} total weight')">
<template #totalWeight>{{ boardList.totalWeight }}</template>
<template #totalWeight>{{ totalWeight }}</template>
</gl-sprintf>
</div>
</gl-tooltip>
@ -381,11 +387,11 @@ export default {
/>
</span>
<!-- EE start -->
<template v-if="weightFeatureAvailable && !isEpicBoard && !isLoading">
<template v-if="canShowTotalWeight">
<gl-tooltip :target="() => $refs.weightTooltip" :title="weightCountToolTip" />
<span ref="weightTooltip" class="gl-display-inline-flex gl-ml-3">
<span ref="weightTooltip" class="gl-display-inline-flex gl-ml-3" data-testid="weight">
<gl-icon class="gl-mr-2" name="weight" />
{{ boardList.totalWeight }}
{{ totalWeight }}
</span>
</template>
<!-- EE end -->

View File

@ -106,7 +106,7 @@ export default {
<div class="gl-text-right">
<gl-button
ref="clipboardCopyBtn"
variant="success"
variant="confirm"
category="secondary"
:data-clipboard-text="yml"
class="gl-xs-w-full gl-xs-mb-3"
@ -116,7 +116,7 @@ export default {
</gl-button>
<gl-button
type="submit"
variant="success"
variant="confirm"
:disabled="panelPreviewIsLoading"
class="js-no-auto-disable gl-xs-w-full"
>
@ -170,7 +170,7 @@ export default {
</gl-button>
<gl-button
ref="openRepositoryBtn"
variant="success"
variant="confirm"
:href="projectPath"
class="gl-xs-w-full"
>

View File

@ -1,12 +1,14 @@
import $ from 'jquery';
export default function initProjectLoadingSpinner() {
const $formContainer = $('.project-edit-container');
const $loadingSpinner = $('.save-project-loader');
const formContainer = document.querySelector('.project-edit-container');
if (formContainer == null) {
return;
}
const loadingSpinner = document.querySelector('.save-project-loader');
// show loading spinner when saving
$formContainer.on('ajax:before', () => {
$formContainer.hide();
$loadingSpinner.show();
formContainer.addEventListener('ajax:before', () => {
formContainer.style.display = 'none';
loadingSpinner.style.display = 'block';
});
}

View File

@ -10,7 +10,7 @@ const PERSISTENT_USER_CALLOUTS = [
'.js-new-user-signups-cap-reached',
'.js-eoa-bronze-plan-banner',
'.js-security-newsletter-callout',
'.js-approaching-seats-count-threshold',
'.js-approaching-seat-count-threshold',
'.js-storage-enforcement-banner',
'.js-user-over-limit-free-plan-alert',
'.js-minute-limit-banner',

View File

@ -58,7 +58,16 @@ module Registrations
def path_for_signed_in_user(user)
return users_almost_there_path(email: user.email) if requires_confirmation?(user)
stored_location_for(user) || members_activity_path(user.members)
stored_url = stored_location_for(user)
if ::Feature.enabled?(:about_your_company_registration_flow) &&
stored_url&.include?(new_users_sign_up_company_path)
company_params = update_params.slice(:role, :other_role, :registration_objective)
.merge(params.permit(:jobs_to_be_done_other))
redirect_uri = Gitlab::Utils.add_url_parameters(stored_url, company_params)
store_location_for(:user, redirect_uri)
else
stored_url || members_activity_path(user.members)
end
end
def members_activity_path(members)

View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
# Convert any ActiveRecord::Relation to a Gitlab::SQL::CTE
module AsCte
extend ActiveSupport::Concern
class_methods do
def as_cte(name, **opts)
Gitlab::SQL::CTE.new(name, all, **opts)
end
end
end

View File

@ -5,6 +5,8 @@ module Namespaces
module LinearScopes
extend ActiveSupport::Concern
include AsCte
class_methods do
# When filtering namespaces by the traversal_ids column to compile a
# list of namespace IDs, it can be faster to reference the ID in
@ -25,25 +27,15 @@ module Namespaces
def self_and_ancestors(include_self: true, upto: nil, hierarchy_order: nil)
return super unless use_traversal_ids_for_ancestor_scopes?
ancestors_cte, base_cte = ancestor_ctes
namespaces = Arel::Table.new(:namespaces)
records = unscoped
.with(base_cte.to_arel, ancestors_cte.to_arel)
.distinct
.from([ancestors_cte.table, namespaces])
.where(namespaces[:id].eq(ancestors_cte.table[:ancestor_id]))
.order_by_depth(hierarchy_order)
unless include_self
records = records.where(ancestors_cte.table[:base_id].not_eq(ancestors_cte.table[:ancestor_id]))
if Feature.enabled?(:use_traversal_ids_for_ancestor_scopes_with_inner_join)
self_and_ancestors_from_inner_join(include_self: include_self,
upto: upto, hierarchy_order:
hierarchy_order)
else
self_and_ancestors_from_ancestors_cte(include_self: include_self,
upto: upto,
hierarchy_order: hierarchy_order)
end
if upto
records = records.where.not(id: unscoped.where(id: upto).select('unnest(traversal_ids)'))
end
records
end
def self_and_ancestor_ids(include_self: true)
@ -87,7 +79,7 @@ module Namespaces
depth_order = hierarchy_order == :asc ? :desc : :asc
all
.select(Arel.star, 'array_length(traversal_ids, 1) as depth')
.select(Namespace.default_select_columns, 'array_length(traversal_ids, 1) as depth')
.order(depth: depth_order, id: :asc)
end
@ -125,10 +117,73 @@ module Namespaces
use_traversal_ids?
end
def self_and_ancestors_from_ancestors_cte(include_self: true, upto: nil, hierarchy_order: nil)
base_cte = all.select('namespaces.id', 'namespaces.traversal_ids').as_cte(:base_ancestors_cte)
# We have to alias id with 'AS' to avoid ambiguous column references by calling methods.
ancestors_cte = unscoped
.unscope(where: [:type])
.select('id as base_id',
"#{unnest_func(base_cte.table['traversal_ids']).to_sql} as ancestor_id")
.from(base_cte.table)
.as_cte(:ancestors_cte)
namespaces = Arel::Table.new(:namespaces)
records = unscoped
.with(base_cte.to_arel, ancestors_cte.to_arel)
.distinct
.from([ancestors_cte.table, namespaces])
.where(namespaces[:id].eq(ancestors_cte.table[:ancestor_id]))
.order_by_depth(hierarchy_order)
unless include_self
records = records.where(ancestors_cte.table[:base_id].not_eq(ancestors_cte.table[:ancestor_id]))
end
if upto
records = records.where.not(id: unscoped.where(id: upto).select('unnest(traversal_ids)'))
end
records
end
def self_and_ancestors_from_inner_join(include_self: true, upto: nil, hierarchy_order: nil)
base_cte = all.reselect('namespaces.traversal_ids').as_cte(:base_ancestors_cte)
unnest = if include_self
base_cte.table[:traversal_ids]
else
base_cte_traversal_ids = 'base_ancestors_cte.traversal_ids'
traversal_ids_range = "1:array_length(#{base_cte_traversal_ids},1)-1"
Arel.sql("#{base_cte_traversal_ids}[#{traversal_ids_range}]")
end
ancestor_subselect = "SELECT DISTINCT #{unnest_func(unnest).to_sql} FROM base_ancestors_cte"
ancestors_join = <<~SQL
INNER JOIN (#{ancestor_subselect}) AS ancestors(ancestor_id) ON namespaces.id = ancestors.ancestor_id
SQL
namespaces = Arel::Table.new(:namespaces)
records = unscoped
.with(base_cte.to_arel)
.from(namespaces)
.joins(ancestors_join)
.order_by_depth(hierarchy_order)
if upto
upto_ancestor_ids = unscoped.where(id: upto).select(unnest_func(Arel.sql('traversal_ids')))
records = records.where.not(id: upto_ancestor_ids)
end
records
end
def self_and_descendants_with_comparison_operators(include_self: true)
base = all.select(:traversal_ids)
base = base.select(:id) if Feature.enabled?(:linear_scopes_superset)
base_cte = Gitlab::SQL::CTE.new(:descendants_base_cte, base)
base_cte = base.as_cte(:descendants_base_cte)
namespaces = Arel::Table.new(:namespaces)
@ -169,6 +224,10 @@ module Namespaces
Arel::Nodes::NamedFunction.new('next_traversal_ids_sibling', args)
end
def unnest_func(*args)
Arel::Nodes::NamedFunction.new('unnest', args)
end
def self_and_descendants_with_duplicates_with_array_operator(include_self: true)
base_ids = select(:id)
@ -197,20 +256,6 @@ module Namespaces
Gitlab::SQL::CTE.new(:superset, superset_sql, materialized: false)
end
def ancestor_ctes
base_scope = all.select('namespaces.id', 'namespaces.traversal_ids')
base_cte = Gitlab::SQL::CTE.new(:base_ancestors_cte, base_scope)
# We have to alias id with 'AS' to avoid ambiguous column references by calling methods.
ancestors_scope = unscoped
.unscope(where: [:type])
.select('id as base_id', 'unnest(traversal_ids) as ancestor_id')
.from(base_cte.table)
ancestors_cte = Gitlab::SQL::CTE.new(:ancestors_cte, ancestors_scope)
[ancestors_cte, base_cte]
end
end
end
end

View File

@ -4,7 +4,50 @@ module WorkItems
class ParentLink < ApplicationRecord
self.table_name = 'work_item_parent_links'
MAX_CHILDREN = 100
belongs_to :work_item
belongs_to :work_item_parent, class_name: 'WorkItem'
validates :work_item, :work_item_parent, presence: true
validate :validate_child_type
validate :validate_parent_type
validate :validate_same_project
validate :validate_max_children
private
def validate_child_type
return unless work_item
unless work_item.task?
errors.add :work_item, _('Only Task can be assigned as a child in hierarchy.')
end
end
def validate_parent_type
return unless work_item_parent
unless work_item_parent.issue?
errors.add :work_item_parent, _('Only Issue can be parent of Task.')
end
end
def validate_same_project
return if work_item.nil? || work_item_parent.nil?
if work_item.resource_parent != work_item_parent.resource_parent
errors.add :work_item_parent, _('Parent must be in the same project as child.')
end
end
def validate_max_children
return unless work_item_parent
max = persisted? ? MAX_CHILDREN : MAX_CHILDREN - 1
if work_item_parent.child_links.count > max
errors.add :work_item_parent, _('Parent already has maximum number of children.')
end
end
end
end

View File

@ -13,11 +13,10 @@ module Ci
def execute
return unless @user.present? && @user.can?(:update_runners_registration_token, scope)
case scope
when ::ApplicationSetting
if scope.respond_to?(:runners_registration_token)
scope.reset_runners_registration_token!
ApplicationSetting.current_without_cache.runners_registration_token
when ::Group, ::Project
scope.runners_registration_token
else
scope.reset_runners_token!
scope.runners_token
end

View File

@ -16,7 +16,7 @@
= yield :flash_message
= dispensable_render "shared/service_ping_consent"
= dispensable_render_if_exists "layouts/header/ee_subscribable_banner"
= dispensable_render_if_exists "layouts/header/seats_count_alert"
= dispensable_render_if_exists "layouts/header/seat_count_alert"
= dispensable_render_if_exists "shared/namespace_storage_limit_alert"
= dispensable_render_if_exists "shared/namespace_user_cap_reached_alert"
= dispensable_render_if_exists "shared/new_user_signups_cap_reached_alert"

View File

@ -0,0 +1,8 @@
---
name: group_level_protected_environment
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88506
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/363450
milestone: '15.1'
type: development
group: group::release
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: seat_count_alerts
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79563
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/362041
milestone: '15.1'
type: development
group: group::purchase
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: use_traversal_ids_for_ancestor_scopes_with_inner_join
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83371
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356628
milestone: '15.1'
type: development
group: group::workspace
default_enabled: false

View File

@ -54,7 +54,9 @@ required number of seconds.
"required": [
"id",
"path",
"created_at"
"created_at",
"shared_runners_enabled",
"group_runners_enabled"
],
"properties": {
"id": { "type": "integer" },

View File

@ -135,6 +135,9 @@ builds archival, to make it consistent and reliable.
Epic: [Partition CI/CD pipelines database tables](https://gitlab.com/groups/gitlab-org/-/epics/5417).
For more technical details about this topic see
[pipeline data partitioning design](pipeline_partitioning.md).
### Partition CI/CD builds queuing database tables
While working on the [CI/CD Scale](../ci_scale/index.md) blueprint, we have
@ -159,6 +162,9 @@ business rule is present in the product since the inception of GitLab CI.
Epic: [Partition CI/CD builds queuing database tables](https://gitlab.com/groups/gitlab-org/-/epics/7438).
For more technical details about this topic see
[pipeline data partitioning design](pipeline_partitioning.md).
## Principles
All the three tracks we will use to implement CI/CD time decay pattern are

View File

@ -148,12 +148,12 @@ This sync job runs daily around 3AM UTC. If the job fails, it is retried up to 1
The daily job provides **only** the following information to the Customers Portal:
- Company name
- Licensee name
- Licensee email
- Date
- Timestamp
- License key
- Company name (encrypted within license key)
- Licensee name (encrypted within license key)
- Licensee email (encrypted within license key)
- Historical maximum user count
- Billable users count
- GitLab version

View File

@ -1,29 +1,28 @@
---
type: reference, howto
stage: Manage
group: Import
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Migrate groups from another instance of GitLab **(FREE)**
# Migrating groups **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/249160) in GitLab 13.7 [with a flag](../../feature_flags.md) named `bulk_import`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/338985) in GitLab 14.3.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `bulk_import`. On GitLab.com, this feature is available.
On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to
[disable the feature flag](../../../administration/feature_flags.md) named `bulk_import`. On GitLab.com, this feature is
available.
You can migrate your existing top-level groups to any of the following:
- Another GitLab instance, including GitLab.com.
- Another top-level group.
- The subgroup of any existing top-level group.
- Another GitLab instance, including GitLab.com.
Migrating groups is not the same as [group import/export](../settings/import_export.md).
- Group import/export requires you to export a group to a file and then import that file in
another GitLab instance.
- Group migration automates this process.
Migrating groups using the method documented here is not the same as [migrating groups using file exports](../settings/import_export.md).
Importing and exporting groups using file exports requires you to export a group to a file and then import that file in
another GitLab instance. Migrating groups using the method documented here automates this step.
## Import your groups into GitLab

View File

@ -1,16 +1,24 @@
---
type: reference
stage: Manage
group: Import
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Group import/export **(FREE)**
# Migrating groups using file exports (deprecated) **(FREE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2888) in GitLab 13.0 as an experimental feature. May change in future releases.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2888) in GitLab 13.0 as an experimental feature. May change in future releases.
> - [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/4619) in GitLab 14.6.
You can export groups, with all their related data, from one GitLab instance to another.
You can also [export projects](../../project/settings/import_export.md).
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/4619) in GitLab 14.6 and replaced by
[a different migration method](../import/index.md). To follow progress on a solution for
[offline environments](../../application_security/offline_deployments/index.md), see
[the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/363406).
You can export groups, with all their related data, from one GitLab instance to another. You can also:
- [Migrate groups](../import/index.md) using the preferred method.
- [Migrate projects using file exports](../../project/settings/import_export.md).
## Enable export for a group
@ -63,10 +71,6 @@ For more details on the specific data persisted in a group export, see the
## Export a group
WARNING:
This feature will be [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/4619)
in GitLab 14.6 and replaced by [GitLab Migration](../import/).
Prerequisites:
- You must have the Owner role for the group.
@ -96,16 +100,11 @@ You can export groups from the [Community Edition to the Enterprise Edition](htt
The Enterprise Edition retains some group data that isn't part of the Community Edition. If you're exporting a group from the Enterprise Edition to the Community Edition, you may lose this data. For more information, see [downgrading from EE to CE](../../../index.md).
## Importing the group
WARNING:
This feature will be [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/4619)
in GitLab 14.8 and replaced by [GitLab Migration](../import/).
## Import the group
1. Create a new group:
- On the top bar, select **New** (**{plus}**) and then **New group**.
- On an existing group's page, select the **New subgroup** button.
1. Select **Import group**.
1. Enter your group name.
1. Accept or modify the associated group URL.

View File

@ -366,7 +366,7 @@ The chart shows data for the last 500 workflow items.
- In the **From** field, select a start date.
- In the **To** field, select an end date.
## Type of work - Tasks by type chart
## Tasks by type chart
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32421) in GitLab 12.10.

View File

@ -4,10 +4,13 @@ group: Import
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
---
# Project import/export **(FREE)**
# Migrating projects using file exports **(FREE)**
Existing projects on any self-managed GitLab instance or GitLab.com can be exported to a file and
then imported into a new GitLab instance.
then imported into a new GitLab instance. You can also:
- [Migrate groups](../../group/import/index.md) using the preferred method.
- [Migrate groups using file exports](../../group/settings/import_export.md).
## Set up project import/export
@ -34,8 +37,8 @@ Before you can import a project, you must export it.
Prerequisites:
- Review the list of [data that will be exported](#items-that-are-exported).
Not all data is exported.
- Review the list of [items that are exported](#items-that-are-exported).
Not all items are exported.
- You must have at least the Maintainer role for the project.
To export a project and its data, follow these steps:

View File

@ -83,7 +83,9 @@ module Gitlab
project: {
id: project.id,
path: project.full_path,
created_at: project.created_at&.iso8601
created_at: project.created_at&.iso8601,
shared_runners_enabled: project.shared_runners_enabled?,
group_runners_enabled: project.group_runners_enabled?
},
user: {
id: current_user.id,

View File

@ -63,6 +63,8 @@ module Gitlab
end
def build_mail
# See https://github.com/mikel/mail/blob/641060598f8f4be14d79bad8d703e9f2967e1cdb/spec/mail/message_spec.rb#L569
# for mail structure
Mail::Message.new(@raw)
rescue Encoding::UndefinedConversionError,
Encoding::InvalidByteSequenceError => e

View File

@ -23,6 +23,12 @@ module Gitlab
config.address.sub(Gitlab::IncomingEmail::WILDCARD_PLACEHOLDER, key)
end
def key_from_fallback_message_id(mail_id)
message_id_regexp = /\Areply\-(.+)@#{Gitlab.config.gitlab.host}\z/
mail_id[message_id_regexp, 1]
end
end
end
end

View File

@ -7173,6 +7173,9 @@ msgstr ""
msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"
msgstr ""
msgid "Cannot assign an issue that does not belong under the same group (or descendant) as the epic."
msgstr ""
msgid "Cannot be merged automatically"
msgstr ""
@ -11193,17 +11196,6 @@ msgstr ""
msgid "CycleAnalytics|Show"
msgstr ""
msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} label"
msgid_plural "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
msgstr[0] ""
msgstr[1] ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' and %{selectedProjectCount} projects from %{createdAfter} to %{createdBefore}"
msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
@ -11231,9 +11223,6 @@ msgstr ""
msgid "CycleAnalytics|Total time"
msgstr ""
msgid "CycleAnalytics|Type of work"
msgstr ""
msgid "CycleAnalytics|group dropdown filter"
msgstr ""
@ -15019,6 +15008,9 @@ msgstr ""
msgid "Estimated"
msgstr ""
msgid "Even if you reach the number of seats in your subscription, you can continue to add users, and GitLab will bill you for the overage."
msgstr ""
msgid "EventFilterBy|Filter by all"
msgstr ""
@ -26564,9 +26556,15 @@ msgstr ""
msgid "Only Issue ID or merge request ID is required"
msgstr ""
msgid "Only Issue can be parent of Task."
msgstr ""
msgid "Only Project Members"
msgstr ""
msgid "Only Task can be assigned as a child in hierarchy."
msgstr ""
msgid "Only active projects show up in the search and on the dashboard."
msgstr ""
@ -27319,12 +27317,18 @@ msgstr ""
msgid "Parent"
msgstr ""
msgid "Parent already has maximum number of children."
msgstr ""
msgid "Parent epic doesn't exist."
msgstr ""
msgid "Parent epic is not present."
msgstr ""
msgid "Parent must be in the same project as child."
msgstr ""
msgid "Parsing error for param :embed_json. %{message}"
msgstr ""
@ -41628,6 +41632,11 @@ msgstr ""
msgid "ValueStreamAnalytics|%{stageCount}+ items"
msgstr ""
msgid "ValueStreamAnalytics|%{subjectFilterText} and %{selectedLabelsCount} label"
msgid_plural "ValueStreamAnalytics|%{subjectFilterText} and %{selectedLabelsCount} labels"
msgstr[0] ""
msgstr[1] ""
msgid "ValueStreamAnalytics|%{value}M"
msgstr ""
@ -41682,13 +41691,22 @@ msgstr ""
msgid "ValueStreamAnalytics|Percentage of deployments that cause an incident in production."
msgstr ""
msgid "ValueStreamAnalytics|Shows %{selectedFiltersDescription} for group '%{groupName}' and %{selectedProjectCount} projects from %{createdAfter} to %{createdBefore}"
msgstr ""
msgid "ValueStreamAnalytics|Shows %{selectedFiltersDescription} for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
msgid "ValueStreamAnalytics|Tasks by type"
msgstr ""
msgid "ValueStreamAnalytics|There was an error while fetching value stream analytics %{requestTypeName} data."
msgstr ""
msgid "ValueStreamAnalytics|Total number of deploys to production."
msgstr ""
msgid "ValueStreamAnalytics|Value Stream"
msgid "ValueStreamAnalytics|Value stream"
msgstr ""
msgid "ValueStreamEvent|Items in stage"
@ -44175,8 +44193,10 @@ msgstr ""
msgid "Your subscription expired!"
msgstr ""
msgid "Your subscription has %{remaining_seats_count} out of %{total_seats_count} seats remaining. Even if you reach the number of seats in your subscription, you can continue to add users, and GitLab will bill you for the overage."
msgstr ""
msgid "Your subscription has %{remaining_seat_count} out of %{total_seat_count} seat remaining."
msgid_plural "Your subscription has %{remaining_seat_count} out of %{total_seat_count} seats remaining."
msgstr[0] ""
msgstr[1] ""
msgid "Your subscription is now expired. To renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can add this license to your instance. To use Free tier, remove your current license."
msgstr ""

View File

@ -107,7 +107,7 @@
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.22.7",
"core-js": "^3.22.8",
"cron-validator": "^1.1.1",
"cronstrue": "^1.122.0",
"cropper": "^2.3.0",

View File

@ -31,6 +31,7 @@ RSpec.describe Registrations::WelcomeController do
context 'when role and setup_for_company is set' do
before do
stub_feature_flags(about_your_company_registration_flow: false)
user.update!(setup_for_company: false)
sign_in(user)
end
@ -60,6 +61,10 @@ RSpec.describe Registrations::WelcomeController do
end
describe '#update' do
before do
stub_feature_flags(about_your_company_registration_flow: false)
end
subject(:update) do
patch :update, params: { user: { role: 'software_developer', setup_for_company: 'false' } }
end

View File

@ -9,5 +9,10 @@ FactoryBot.define do
relative_position { RelativePositioning::START_POSITION }
issue_type { :issue }
association :work_item_type, :default
trait :task do
issue_type { :task }
association :work_item_type, :default, :task
end
end
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
FactoryBot.define do
factory :parent_link, class: 'WorkItems::ParentLink' do
transient do
work_item { nil }
work_item_parent { nil }
end
after(:build) do |link, evaluator|
link.work_item = evaluator.work_item
link.work_item_parent = evaluator.work_item_parent
unless link.work_item && link.work_item_parent
project = link.work_item&.project || link.work_item_parent&.project || create(:project)
link.work_item ||= create(:work_item, :task, project: project)
link.work_item_parent ||= create(:work_item, project: project)
end
end
end
end

View File

@ -341,6 +341,7 @@ RSpec.describe 'Signup' do
end
it 'redirects to step 2 of the signup process, sets the role and redirects back' do
stub_feature_flags(about_your_company_registration_flow: false)
visit new_user_registration_path
fill_in_signup_form

View File

@ -12,12 +12,16 @@
"required": [
"id",
"path",
"created_at"
"created_at",
"shared_runners_enabled",
"group_runners_enabled"
],
"properties": {
"id": { "type": "integer" },
"path": { "type": "string" },
"created_at": { "type": ["string", "null"], "format": "date-time" }
"created_at": { "type": ["string", "null"], "format": "date-time" },
"shared_runners_enabled": { "type": "boolean" },
"group_runners_enabled": { "type": "boolean" }
}
},
"user": {

View File

@ -0,0 +1,31 @@
Return-Path: <jake@example.com>
Received: from myserver.example.com ([unix socket]) by myserver (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Received: from blabla.google.com (blabla.google.com. [1.1.1.1])
by bla.google.com with SMTPS id something.1.1.1.1.1.1.1
for <abc@appmail.example.com>
(Google Transport Security);
Mon, 21 Feb 2022 14:41:58 -0800 (PST)
References: <topic/35@some.other.server.example.com>
<abc123@discourse-app.mail>
Received: from mail.example.com (mail.example.com [IPv6:2607:f8b0:4001:c03::234]) by myserver.example.com (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@example.com>; Thu, 13 Jun 2013 17:03:50 -0400
From: "jake@example.com" <jake@example.com>
To: "some_unrelated_email@example.com" <some_unrelated_email@example.com>
Subject: Re: Insert hilarious subject line here
Date: Tue, 26 Nov 2019 14:22:41 +0000
Message-ID: <7e2296f83dbf4de388cbf5f56f52c11f@EXDAG29-1.EXCHANGE.INT>
Content-Type: multipart/alternative;
boundary="_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_"
MIME-Version: 1.0
--_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
--_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
This message has unhelpful References headers with no key, and no key in the To headers either.

View File

@ -778,3 +778,15 @@ export const boardListQueryResponse = (issuesCount = 20) => ({
},
},
});
export const epicBoardListQueryResponse = (totalWeight = 5) => ({
data: {
epicBoardList: {
__typename: 'EpicList',
id: 'gid://gitlab/Boards::EpicList/3',
metadata: {
totalWeight,
},
},
},
});

View File

@ -53,6 +53,18 @@ RSpec.describe Gitlab::Email::ServiceDeskReceiver do
end
end
context 'when the email contains no key in the To header and contains reference header with no key' do
let(:email) { fixture_file('emails/service_desk_reference_headers.eml') }
before do
stub_service_desk_email_setting(enabled: true, address: 'support+%{key}@example.com')
end
it 'sends a rejection email' do
expect { receiver.execute }.to raise_error(Gitlab::Email::UnknownIncomingEmail)
end
end
context 'when the email does not contain a valid email address' do
before do
stub_service_desk_email_setting(enabled: true, address: 'other_support+%{key}@example.com')

View File

@ -78,4 +78,10 @@ RSpec.describe Gitlab::ServiceDeskEmail do
end
end
end
context 'self.key_from_fallback_message_id' do
it 'returns reply key' do
expect(described_class.key_from_fallback_message_id('reply-key@localhost')).to eq('key')
end
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AsCte do
let(:klass) do
Class.new(ApplicationRecord) do
include AsCte
self.table_name = 'users'
end
end
let(:query) { klass.where(id: [1, 2, 3]) }
let(:name) { :klass_cte }
describe '.as_cte' do
subject { query.as_cte(name) }
it { expect(subject).to be_a(Gitlab::SQL::CTE) }
it { expect(subject.query).to eq(query) }
it { expect(subject.table.name).to eq(name.to_s) }
context 'with materialized parameter' do
subject { query.as_cte(name, materialized: materialized).to_arel.to_sql }
context 'as true' do
let(:materialized) { true }
it { expect(subject).to match /MATERIALIZE/ }
end
context 'as false' do
let(:materialized) { false }
it { expect(subject).not_to match /MATERIALIZE/ }
end
end
end
end

View File

@ -375,6 +375,14 @@ RSpec.describe Namespace do
context 'linear' do
it_behaves_like 'namespace traversal scopes'
context 'without inner join ancestors query' do
before do
stub_feature_flags(use_traversal_ids_for_ancestor_scopes_with_inner_join: false)
end
it_behaves_like 'namespace traversal scopes'
end
end
shared_examples 'makes recursive queries' do

View File

@ -7,4 +7,60 @@ RSpec.describe WorkItems::ParentLink do
it { is_expected.to belong_to(:work_item) }
it { is_expected.to belong_to(:work_item_parent).class_name('WorkItem') }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:work_item) }
it { is_expected.to validate_presence_of(:work_item_parent) }
describe 'hierarchy' do
let_it_be(:project) { create(:project) }
let_it_be(:issue) { build(:work_item, project: project) }
let_it_be(:task1) { build(:work_item, :task, project: project) }
let_it_be(:task2) { build(:work_item, :task, project: project) }
it 'is valid if not-task parent has task child' do
expect(build(:parent_link, work_item: task1, work_item_parent: issue)).to be_valid
end
it 'is not valid if child is not task' do
link = build(:parent_link, work_item: issue)
expect(link).not_to be_valid
expect(link.errors[:work_item]).to include('Only Task can be assigned as a child in hierarchy.')
end
it 'is not valid if parent is task' do
link = build(:parent_link, work_item_parent: task1)
expect(link).not_to be_valid
expect(link.errors[:work_item_parent]).to include('Only Issue can be parent of Task.')
end
it 'is not valid if parent is in other project' do
link = build(:parent_link, work_item_parent: task1, work_item: build(:work_item))
expect(link).not_to be_valid
expect(link.errors[:work_item_parent]).to include('Parent must be in the same project as child.')
end
context 'when parent already has maximum number of links' do
let_it_be(:link1) { create(:parent_link, work_item_parent: issue, work_item: task1) }
before do
stub_const("#{described_class}::MAX_CHILDREN", 1)
end
it 'is not valid when another link is added' do
link2 = build(:parent_link, work_item_parent: issue, work_item: task2)
expect(link2).not_to be_valid
expect(link2.errors[:work_item_parent]).to include('Parent already has maximum number of children.')
end
it 'existing link is still valid' do
expect(link1).to be_valid
end
end
end
end
end

View File

@ -3847,10 +3847,10 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@^3.22.7:
version "3.22.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.7.tgz#8d6c37f630f6139b8732d10f2c114c3f1d00024f"
integrity sha512-Jt8SReuDKVNZnZEzyEQT5eK6T2RRCXkfTq7Lo09kpm+fHjgGewSbNjV+Wt4yZMhPDdzz2x1ulI5z/w4nxpBseg==
core-js@^3.22.8:
version "3.22.8"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.8.tgz#23f860b1fe60797cc4f704d76c93fea8a2f60631"
integrity sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==
core-js@~2.3.0:
version "2.3.0"