Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-04-21 00:11:06 +00:00
parent 98f1353fcd
commit 96740a3316
44 changed files with 256 additions and 207 deletions

View File

@ -697,8 +697,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- spec/lib/gitlab/closing_issue_extractor_spec.rb - spec/lib/gitlab/closing_issue_extractor_spec.rb
- spec/lib/gitlab/composer/cache_spec.rb - spec/lib/gitlab/composer/cache_spec.rb
- spec/lib/gitlab/data_builder/wiki_page_spec.rb - spec/lib/gitlab/data_builder/wiki_page_spec.rb
- spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb
- spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb
- spec/lib/gitlab/deploy_key_access_spec.rb - spec/lib/gitlab/deploy_key_access_spec.rb
- spec/lib/gitlab/email/handler/service_desk_handler_spec.rb - spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
- spec/lib/gitlab/git/lfs_changes_spec.rb - spec/lib/gitlab/git/lfs_changes_spec.rb
@ -716,11 +714,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- spec/lib/gitlab/prometheus/query_variables_spec.rb - spec/lib/gitlab/prometheus/query_variables_spec.rb
- spec/lib/gitlab/reactive_cache_set_cache_spec.rb - spec/lib/gitlab/reactive_cache_set_cache_spec.rb
- spec/lib/gitlab/reference_extractor_spec.rb - spec/lib/gitlab/reference_extractor_spec.rb
- spec/lib/gitlab/repository_cache_spec.rb
- spec/lib/gitlab/repository_hash_cache_spec.rb
- spec/lib/gitlab/repository_set_cache_spec.rb
- spec/lib/gitlab/repository_size_checker_spec.rb
- spec/lib/gitlab/repository_size_error_message_spec.rb
- spec/lib/gitlab/search_results_spec.rb - spec/lib/gitlab/search_results_spec.rb
- spec/lib/gitlab/shell_spec.rb - spec/lib/gitlab/shell_spec.rb
- spec/models/abuse_report_spec.rb - spec/models/abuse_report_spec.rb

View File

@ -1,6 +1,6 @@
import { sortBy, cloneDeep } from 'lodash'; import { sortBy, cloneDeep } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ListType, NOT_FILTER } from './constants'; import { ListType, NOT_FILTER, AssigneeIdParamValues } from './constants';
export function getMilestone() { export function getMilestone() {
return null; return null;
@ -186,6 +186,35 @@ export function transformNotFilters(filters) {
}, {}); }, {});
} }
export function getSupportedParams(filters, supportedFilters) {
return supportedFilters.reduce((acc, f) => {
/**
* TODO the API endpoint for the classic boards
* accepts assignee wildcard value as 'assigneeId' param -
* while the GraphQL query accepts the value in 'assigneWildcardId' field.
* Once we deprecate the classics boards,
* we should change the filtered search bar to use 'asssigneeWildcardId' as a token name.
*/
if (f === 'assigneeId' && filters[f]) {
return AssigneeIdParamValues.includes(filters[f])
? {
...acc,
assigneeWildcardId: filters[f].toUpperCase(),
}
: acc;
}
if (filters[f]) {
return {
...acc,
[f]: filters[f],
};
}
return acc;
}, {});
}
// EE-specific feature. Find the implementation in the `ee/`-folder // EE-specific feature. Find the implementation in the `ee/`-folder
export function transformBoardConfig() { export function transformBoardConfig() {
return ''; return '';

View File

@ -5,6 +5,20 @@ import boardBlockingIssuesQuery from './graphql/board_blocking_issues.query.grap
import issueSetSubscriptionMutation from './graphql/issue_set_subscription.mutation.graphql'; import issueSetSubscriptionMutation from './graphql/issue_set_subscription.mutation.graphql';
import issueSetTitleMutation from './graphql/issue_set_title.mutation.graphql'; import issueSetTitleMutation from './graphql/issue_set_title.mutation.graphql';
export const SupportedFilters = [
'assigneeUsername',
'authorUsername',
'labelName',
'milestoneTitle',
'releaseTag',
'search',
'myReactionEmoji',
'assigneeId',
];
/* eslint-disable-next-line @gitlab/require-i18n-strings */
export const AssigneeIdParamValues = ['Any', 'None'];
export const issuableTypes = { export const issuableTypes = {
issue: 'issue', issue: 'issue',
epic: 'epic', epic: 'epic',

View File

@ -1,5 +1,4 @@
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { pick } from 'lodash';
import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql'; import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql';
import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql'; import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql'; import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
@ -11,6 +10,7 @@ import {
ISSUABLE, ISSUABLE,
titleQueries, titleQueries,
subscriptionQueries, subscriptionQueries,
SupportedFilters,
} from '~/boards/constants'; } from '~/boards/constants';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import createGqClient, { fetchPolicies } from '~/lib/graphql'; import createGqClient, { fetchPolicies } from '~/lib/graphql';
@ -27,6 +27,7 @@ import {
transformNotFilters, transformNotFilters,
moveItemListHelper, moveItemListHelper,
getMoveData, getMoveData,
getSupportedParams,
} from '../boards_util'; } from '../boards_util';
import boardLabelsQuery from '../graphql/board_labels.query.graphql'; import boardLabelsQuery from '../graphql/board_labels.query.graphql';
import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql'; import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql';
@ -65,16 +66,11 @@ export default {
}, },
setFilters: ({ commit }, filters) => { setFilters: ({ commit }, filters) => {
const filterParams = pick(filters, [ const filterParams = {
'assigneeUsername', ...getSupportedParams(filters, SupportedFilters),
'authorUsername', not: transformNotFilters(filters),
'labelName', };
'milestoneTitle',
'releaseTag',
'search',
'myReactionEmoji',
]);
filterParams.not = transformNotFilters(filters);
commit(types.SET_FILTERS, filterParams); commit(types.SET_FILTERS, filterParams);
}, },

View File

@ -393,6 +393,7 @@ export default {
v-model="variable.variable_type" v-model="variable.variable_type"
:class="$options.formElementClasses" :class="$options.formElementClasses"
:options="$options.typeOptions" :options="$options.typeOptions"
data-testid="pipeline-form-ci-variable-type"
/> />
<gl-form-input <gl-form-input
v-model="variable.key" v-model="variable.key"

View File

@ -81,11 +81,12 @@ export default {
}; };
</script> </script>
<template> <template>
<gl-dropdown :text="refShortName" block @show.once="loadRefs"> <gl-dropdown :text="refShortName" block data-testid="ref-select" @show.once="loadRefs">
<gl-search-box-by-type <gl-search-box-by-type
v-model.trim="searchTerm" v-model.trim="searchTerm"
:is-loading="isLoading" :is-loading="isLoading"
:placeholder="__('Search refs')" :placeholder="__('Search refs')"
data-testid="search-refs"
/> />
<gl-dropdown-section-header>{{ __('Branches') }}</gl-dropdown-section-header> <gl-dropdown-section-header>{{ __('Branches') }}</gl-dropdown-section-header>
<gl-dropdown-item <gl-dropdown-item

View File

@ -175,7 +175,7 @@ export default {
> >
<gl-button <gl-button
:loading="isMakingRequest" :loading="isMakingRequest"
variant="success" variant="confirm"
data-qa-selector="mr_rebase_button" data-qa-selector="mr_rebase_button"
@click="rebase" @click="rebase"
> >

View File

@ -13,7 +13,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables] before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
before_action :authorize_update_pipeline!, only: [:retry, :cancel] before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do before_action do
push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: :yaml)
push_frontend_feature_flag(:pipeline_graph_layers_view, project, type: :development, default_enabled: :yaml) push_frontend_feature_flag(:pipeline_graph_layers_view, project, type: :development, default_enabled: :yaml)
push_frontend_feature_flag(:pipeline_filter_jobs, project, default_enabled: :yaml) push_frontend_feature_flag(:pipeline_filter_jobs, project, default_enabled: :yaml)
push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml) push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml)

View File

@ -193,8 +193,12 @@ module InProductMarketingHelper
end end
end end
def in_product_marketing_progress(track, series) def in_product_marketing_progress(track, series, format: nil)
s_('InProductMarketing|This is email %{series} of 3 in the %{track} series.') % { series: series + 1, track: track.to_s.humanize } if Gitlab.com?
s_('InProductMarketing|This is email %{series} of 3 in the %{track} series.') % { series: series + 1, track: track.to_s.humanize }
else
s_('InProductMarketing|This is email %{series} of 3 in the %{track} series. To disable notification emails sent by your local GitLab instance, either contact your administrator or %{unsubscribe_link}.') % { series: series + 1, track: track.to_s.humanize, unsubscribe_link: unsubscribe_link(format) }
end
end end
def footer_links(format: nil) def footer_links(format: nil)
@ -220,11 +224,9 @@ module InProductMarketingHelper
s_('InProductMarketing|%{strong_start}GitLab Inc.%{strong_end} 268 Bush Street, #350, San Francisco, CA 94104, USA').html_safe % strong_options(format) s_('InProductMarketing|%{strong_start}GitLab Inc.%{strong_end} 268 Bush Street, #350, San Francisco, CA 94104, USA').html_safe % strong_options(format)
end end
def unsubscribe(format: nil) def unsubscribe(track, series, format: nil)
parts = [ parts = Gitlab.com? ? unsubscribe_com(format) : unsubscribe_self_managed(track, series, format)
s_('InProductMarketing|If you no longer wish to receive marketing emails from us,'),
s_('InProductMarketing|you may %{unsubscribe_link} at any time.') % { unsubscribe_link: unsubscribe_link(format) }
]
case format case format
when :html when :html
parts.join(' ') parts.join(' ')
@ -235,6 +237,20 @@ module InProductMarketingHelper
private private
def unsubscribe_com(format)
[
s_('InProductMarketing|If you no longer wish to receive marketing emails from us,'),
s_('InProductMarketing|you may %{unsubscribe_link} at any time.') % { unsubscribe_link: unsubscribe_link(format) }
]
end
def unsubscribe_self_managed(track, series, format)
[
s_('InProductMarketing|To opt out of these onboarding emails, %{unsubscribe_link}.') % { unsubscribe_link: unsubscribe_link(format) },
s_("InProductMarketing|If you don't want to receive marketing emails directly from GitLab, %{marketing_preference_link}.") % { marketing_preference_link: marketing_preference_link(track, series, format) }
]
end
def in_product_marketing_cta_text(track, series) def in_product_marketing_cta_text(track, series)
{ {
create: [ create: [
@ -314,9 +330,23 @@ module InProductMarketingHelper
def unsubscribe_link(format) def unsubscribe_link(format)
unsubscribe_url = Gitlab.com? ? '%tag_unsubscribe_url%' : profile_notifications_url unsubscribe_url = Gitlab.com? ? '%tag_unsubscribe_url%' : profile_notifications_url
link(s_('InProductMarketing|unsubscribe'), unsubscribe_url, format) link(s_('InProductMarketing|unsubscribe'), unsubscribe_url, format)
end end
def marketing_preference_link(track, series, format)
params = {
utm_source: 'SM',
utm_medium: 'email',
utm_campaign: 'onboarding',
utm_term: "#{track}_#{series}"
}
preference_link = "https://about.gitlab.com/company/preference-center/?#{params.to_query}"
link(s_('InProductMarketing|update your preferences'), preference_link, format)
end
def link(text, link, format) def link(text, link, format)
case format case format
when :html when :html

View File

@ -166,6 +166,10 @@
= about_link('mailers/in_product_marketing', 'gitlab-logo-gray-rgb.png', 200) = about_link('mailers/in_product_marketing', 'gitlab-logo-gray-rgb.png', 200)
%tr %tr
%td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" } %td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" }
%tr{ style: "background-color: #ffffff;" }
%td{ style: "color: #424242; padding: 10px 30px; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;font-size: 16px; line-height: 22px; border: 1px solid #dddddd" }
%p
= in_product_marketing_progress(@track, @series, format: :html).html_safe
%tr %tr
%td{ bgcolor: "#ffffff", height: "auto", style: "max-width: 600px; width: 100%; text-align: center; height: 200px; padding: 25px 15px; mso-line-height-rule: exactly; min-height: 40px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;", valign: "middle", width: "100%" } %td{ bgcolor: "#ffffff", height: "auto", style: "max-width: 600px; width: 100%; text-align: center; height: 200px; padding: 25px 15px; mso-line-height-rule: exactly; min-height: 40px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;", valign: "middle", width: "100%" }
= in_product_marketing_logo(@track, @series) = in_product_marketing_logo(@track, @series)
@ -183,10 +187,6 @@
%tr %tr
%td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" } %td{ align: "center", style: "padding: 10px 20px 80px 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;" }
.cta_link= cta_link(@track, @series, @group, format: :html) .cta_link= cta_link(@track, @series, @group, format: :html)
%tr{ style: "background-color: #ffffff;" }
%td{ style: "color: #424242; padding: 10px 30px; text-align: center; font-family: 'Source Sans Pro', helvetica, arial, sans-serif;font-size: 16px; line-height: 22px; border: 1px solid #dddddd" }
%p
= in_product_marketing_progress(@track, @series)
%tr{ style: "background-color: #ffffff;" } %tr{ style: "background-color: #ffffff;" }
%td{ align: "center", style: "padding:75px 20px 25px;" } %td{ align: "center", style: "padding:75px 20px 25px;" }
= about_link('', 'gitlab_logo.png', 80) = about_link('', 'gitlab_logo.png', 80)
@ -202,4 +202,4 @@
%tr{ style: "background-color: #ffffff;" } %tr{ style: "background-color: #ffffff;" }
%td{ align: "left", style: "padding:20px 30px 20px 30px;" } %td{ align: "left", style: "padding:20px 30px 20px 30px;" }
%span.footernav{ style: "color: #6e49cb; font-size: 14px; line-height: 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#424242;" } %span.footernav{ style: "color: #6e49cb; font-size: 14px; line-height: 20px; font-family: 'Source Sans Pro', helvetica, arial, sans-serif; color:#424242;" }
= unsubscribe(format: :html).html_safe = unsubscribe(@track, @series, format: :html).html_safe

View File

@ -20,4 +20,4 @@
<%= address %> <%= address %>
<%= unsubscribe %> <%= unsubscribe(@track, @series) %>

View File

@ -2,17 +2,17 @@
%li{ class: active_when(scope.nil?) }> %li{ class: active_when(scope.nil?) }>
= link_to schedule_path_proc.call(nil) do = link_to schedule_path_proc.call(nil) do
= s_("PipelineSchedules|All") = s_("PipelineSchedules|All")
%span.badge.badge-pill.js-totalbuilds-count %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm.js-totalbuilds-count
= number_with_delimiter(all_schedules.count(:id)) = number_with_delimiter(all_schedules.count(:id))
%li{ class: active_when(scope == 'active') }> %li{ class: active_when(scope == 'active') }>
= link_to schedule_path_proc.call('active') do = link_to schedule_path_proc.call('active') do
= s_("PipelineSchedules|Active") = s_("PipelineSchedules|Active")
%span.badge.badge-pill %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= number_with_delimiter(all_schedules.active.count(:id)) = number_with_delimiter(all_schedules.active.count(:id))
%li{ class: active_when(scope == 'inactive') }> %li{ class: active_when(scope == 'inactive') }>
= link_to schedule_path_proc.call('inactive') do = link_to schedule_path_proc.call('inactive') do
= s_("PipelineSchedules|Inactive") = s_("PipelineSchedules|Inactive")
%span.badge.badge-pill %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= number_with_delimiter(all_schedules.inactive.count(:id)) = number_with_delimiter(all_schedules.inactive.count(:id))

View File

@ -1,55 +1,17 @@
- breadcrumb_title _('Pipelines') - breadcrumb_title _('Pipelines')
- page_title s_('Pipeline|Run pipeline') - page_title s_('Pipeline|Run pipeline')
- settings_link = link_to _('CI/CD settings'), project_settings_ci_cd_path(@project)
%h3.page-title %h3.page-title
= s_('Pipeline|Run pipeline') = s_('Pipeline|Run pipeline')
%hr %hr
- if Feature.enabled?(:new_pipeline_form, @project, default_enabled: :yaml) #js-new-pipeline{ data: { project_id: @project.id,
#js-new-pipeline{ data: { project_id: @project.id, pipelines_path: project_pipelines_path(@project),
pipelines_path: project_pipelines_path(@project), config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project),
config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project), default_branch: @project.default_branch,
default_branch: @project.default_branch, ref_param: params[:ref] || @project.default_branch,
ref_param: params[:ref] || @project.default_branch, var_param: params[:var].to_json,
var_param: params[:var].to_json, file_param: params[:file_var].to_json,
file_param: params[:file_var].to_json, project_refs_endpoint: refs_project_path(@project, sort: 'updated_desc'),
project_refs_endpoint: refs_project_path(@project, sort: 'updated_desc'), settings_link: project_settings_ci_cd_path(@project),
settings_link: project_settings_ci_cd_path(@project), max_warnings: ::Gitlab::Ci::Warnings::MAX_LIMIT } }
max_warnings: ::Gitlab::Ci::Warnings::MAX_LIMIT } }
- else
= form_for @pipeline, as: :pipeline, url: project_pipelines_path(@project), html: { id: "new-pipeline-form", class: "js-new-pipeline-form js-requires-input" } do |f|
= form_errors(@pipeline)
= pipeline_warnings(@pipeline)
.form-group.row
.col-sm-12
= f.label :ref, s_('Pipeline|Run for'), class: 'col-form-label'
= hidden_field_tag 'pipeline[ref]', params[:ref] || @project.default_branch
= dropdown_tag(params[:ref] || @project.default_branch,
options: { toggle_class: 'js-branch-select wide monospace',
filter: true, dropdown_class: "dropdown-menu-selectable git-revision-dropdown", placeholder: s_("Pipeline|Search branches"),
data: { selected: params[:ref] || @project.default_branch, field_name: 'pipeline[ref]' } })
.form-text.text-muted
= s_("Pipeline|Existing branch name or tag")
.col-sm-12.gl-mt-3.js-ci-variable-list-section
%label
= s_('Pipeline|Variables')
%ul.ci-variable-list
- if params[:var]
- params[:var].each do |variable|
= render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
- if params[:file_var]
- params[:file_var].each do |variable|
- variable.push("file")
= render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
= render 'ci/variables/variable_row', form_field: 'pipeline', only_key_value: true
.form-text.text-muted
= (s_("Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default.") % {settings_link: settings_link}).html_safe
.form-actions
= f.submit s_('Pipeline|Run pipeline'), class: 'btn gl-button btn-confirm gl-mr-3 js-variables-save-button'
= link_to _('Cancel'), project_pipelines_path(@project), class: 'btn gl-button btn-default'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe

View File

@ -2,23 +2,23 @@
%li{ class: active_when(scope.nil?) }> %li{ class: active_when(scope.nil?) }>
= link_to build_path_proc.call(nil) do = link_to build_path_proc.call(nil) do
All All
%span.badge.badge-pill.js-totalbuilds-count %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm.js-totalbuilds-count
= limited_counter_with_delimiter(all_builds) = limited_counter_with_delimiter(all_builds)
%li{ class: active_when(scope == 'pending') }> %li{ class: active_when(scope == 'pending') }>
= link_to build_path_proc.call('pending') do = link_to build_path_proc.call('pending') do
Pending Pending
%span.badge.badge-pill %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= limited_counter_with_delimiter(all_builds.pending) = limited_counter_with_delimiter(all_builds.pending)
%li{ class: active_when(scope == 'running') }> %li{ class: active_when(scope == 'running') }>
= link_to build_path_proc.call('running') do = link_to build_path_proc.call('running') do
Running Running
%span.badge.badge-pill %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= limited_counter_with_delimiter(all_builds.running) = limited_counter_with_delimiter(all_builds.running)
%li{ class: active_when(scope == 'finished') }> %li{ class: active_when(scope == 'finished') }>
= link_to build_path_proc.call('finished') do = link_to build_path_proc.call('finished') do
Finished Finished
%span.badge.badge-pill %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm
= limited_counter_with_delimiter(all_builds.finished) = limited_counter_with_delimiter(all_builds.finished)

View File

@ -0,0 +1,5 @@
---
title: Add gl-badge for badges in jobs page nav
merge_request: 57938
author: Yogi (@yo)
type: changed

View File

@ -0,0 +1,5 @@
---
title: Add gl-badge for badges in pipeline schedules nav
merge_request: 57937
author: Yogi (@yo)
type: changed

View File

@ -0,0 +1,5 @@
---
title: Fix EmptyLineAfterFinalLetItBe offenses in spec/lib/gitlab/database
merge_request: 58251
author: Huzaifa Iftikhar @huzaifaiftikhar
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Fix EmptyLineAfterFinalLetItBe offenses in spec/lib/gitlab/repository
merge_request: 58308
author: Huzaifa Iftikhar @huzaifaiftikhar
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Enable the new pipeline form by default
merge_request: 55250
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Correct variant of Rebase button in MR widget
merge_request: 59684
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Change unsubscribe language for email campaign on self managed
merge_request: 59121
author:
type: changed

View File

@ -1,8 +0,0 @@
---
name: new_pipeline_form
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35674
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/229632
milestone: '13.2'
type: development
group: group::continuous integration
default_enabled: true

View File

@ -70,7 +70,12 @@ Assuming the hook code is properly implemented, the hook code is executed as app
To create a Git hook that applies to all of the repositories in your instance, set a global server To create a Git hook that applies to all of the repositories in your instance, set a global server
hook. The default global server hook directory is in the GitLab Shell directory. Any hook. The default global server hook directory is in the GitLab Shell directory. Any
hook added there applies to all repositories. hook added there applies to all repositories, including:
- [Project and group wiki](../user/project/wiki/index.md) repositories,
whose storage directory names are in the format `<id>.wiki.git`.
- [Design management](../user/project/issues/design_management.md) repositories under a
project, whose storage directory names are in the format `<id>.design.git`.
The default directory: The default directory:

View File

@ -118,6 +118,9 @@ To create an issue:
The issue is created. You can view it by going to **Issues > List**. The issue is created. You can view it by going to **Issues > List**.
``` ```
If you have several tasks on a page that share prerequisites, you can make a
reference topic with the title **Prerequisites**, and link to it.
## Reference ## Reference
A reference topic provides information in an easily-scannable format, A reference topic provides information in an easily-scannable format,
@ -133,6 +136,9 @@ Introductory sentence.
| **Name** | Descriptive sentence about the setting. | | **Name** | Descriptive sentence about the setting. |
``` ```
If a feature or concept has its own prerequisites, you can use the reference
topic type to create a **Prerequisites** header for the information.
## Troubleshooting ## Troubleshooting
Troubleshooting topics can be one of two categories: Troubleshooting topics can be one of two categories:

View File

@ -176,9 +176,9 @@ it as `namespace: namespace`. In order to make it work along with `let_it_be`, `
must be explicitly specified. That keeps the default factory for every example in a suite instead of must be explicitly specified. That keeps the default factory for every example in a suite instead of
recreating it for each example. recreating it for each example.
Objects created inside a `factory_default: :keep`, and using To prevent accidental reliance between test examples, objects created
`create_default` inside a `let_it_be` should be frozen to prevent accidental reliance with `create_default` are
between test examples. [frozen](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/support/factory_default.rb).
Maybe we don't need to create 208 different projects - we Maybe we don't need to create 208 different projects - we
can create one and reuse it. In addition, we can see that only about 1/3 of the can create one and reuse it. In addition, we can see that only about 1/3 of the

View File

@ -5571,9 +5571,6 @@ msgstr ""
msgid "CI/CD for external repo" msgid "CI/CD for external repo"
msgstr "" msgstr ""
msgid "CI/CD settings"
msgstr ""
msgid "CICDAnalytics|%{percent}%{percentSymbol}" msgid "CICDAnalytics|%{percent}%{percentSymbol}"
msgstr "" msgstr ""
@ -16580,6 +16577,9 @@ msgstr ""
msgid "InProductMarketing|How to build and test faster" msgid "InProductMarketing|How to build and test faster"
msgstr "" msgstr ""
msgid "InProductMarketing|If you don't want to receive marketing emails directly from GitLab, %{marketing_preference_link}."
msgstr ""
msgid "InProductMarketing|If you no longer wish to receive marketing emails from us," msgid "InProductMarketing|If you no longer wish to receive marketing emails from us,"
msgstr "" msgstr ""
@ -16688,12 +16688,18 @@ msgstr ""
msgid "InProductMarketing|This is email %{series} of 3 in the %{track} series." msgid "InProductMarketing|This is email %{series} of 3 in the %{track} series."
msgstr "" msgstr ""
msgid "InProductMarketing|This is email %{series} of 3 in the %{track} series. To disable notification emails sent by your local GitLab instance, either contact your administrator or %{unsubscribe_link}."
msgstr ""
msgid "InProductMarketing|Ticketmaster decreased their CI build time by 15X" msgid "InProductMarketing|Ticketmaster decreased their CI build time by 15X"
msgstr "" msgstr ""
msgid "InProductMarketing|Tired of wrestling with disparate tool chains, information silos and inefficient processes? GitLab's CI/CD is built on a DevOps platform with source code management, planning, monitoring and more ready to go. Find out %{ci_link}." msgid "InProductMarketing|Tired of wrestling with disparate tool chains, information silos and inefficient processes? GitLab's CI/CD is built on a DevOps platform with source code management, planning, monitoring and more ready to go. Find out %{ci_link}."
msgstr "" msgstr ""
msgid "InProductMarketing|To opt out of these onboarding emails, %{unsubscribe_link}."
msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}." msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr "" msgstr ""
@ -16772,6 +16778,9 @@ msgstr ""
msgid "InProductMarketing|unsubscribe" msgid "InProductMarketing|unsubscribe"
msgstr "" msgstr ""
msgid "InProductMarketing|update your preferences"
msgstr ""
msgid "InProductMarketing|using a CI/CD template" msgid "InProductMarketing|using a CI/CD template"
msgstr "" msgstr ""
@ -23495,9 +23504,6 @@ msgstr ""
msgid "Pipeline|Duration" msgid "Pipeline|Duration"
msgstr "" msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
msgid "Pipeline|Failed" msgid "Pipeline|Failed"
msgstr "" msgstr ""
@ -23540,9 +23546,6 @@ msgstr ""
msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens." msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
msgstr "" msgstr ""
msgid "Pipeline|Run for"
msgstr ""
msgid "Pipeline|Run for branch name or tag" msgid "Pipeline|Run for branch name or tag"
msgstr "" msgstr ""
@ -23552,18 +23555,12 @@ msgstr ""
msgid "Pipeline|Running" msgid "Pipeline|Running"
msgstr "" msgstr ""
msgid "Pipeline|Search branches"
msgstr ""
msgid "Pipeline|Skipped" msgid "Pipeline|Skipped"
msgstr "" msgstr ""
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default." msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{linkStart}CI/CD settings%{linkEnd} will be used by default."
msgstr "" msgstr ""
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
msgid "Pipeline|Stages" msgid "Pipeline|Stages"
msgstr "" msgstr ""

View File

@ -5,22 +5,7 @@ FactoryBot.define do
sequence(:name) { |n| "namespace#{n}" } sequence(:name) { |n| "namespace#{n}" }
path { name.downcase.gsub(/\s/, '_') } path { name.downcase.gsub(/\s/, '_') }
# This is a workaround to avoid the user creating another namespace via owner { association(:user, strategy: :build, namespace: instance, username: path) }
# User#ensure_namespace_correct. We should try to remove it and then
# we could remove this workaround
association :owner, factory: :user, strategy: :build
before(:create) do |namespace|
owner = namespace.owner
if owner
# We're changing the username here because we want to keep our path,
# and User#ensure_namespace_correct would change the path based on
# username, so we're forced to do this otherwise we'll need to change
# a lot of existing tests.
owner.username = namespace.path
owner.namespace = namespace
end
end
trait :with_aggregation_schedule do trait :with_aggregation_schedule do
after(:create) do |namespace| after(:create) do |namespace|

View File

@ -8,7 +8,6 @@ RSpec.describe "Populate new pipeline CI variables with url params", :js do
let(:page_path) { new_project_pipeline_path(project) } let(:page_path) { new_project_pipeline_path(project) }
before do before do
stub_feature_flags(new_pipeline_form: false)
sign_in(user) sign_in(user)
project.add_maintainer(user) project.add_maintainer(user)
@ -16,18 +15,18 @@ RSpec.describe "Populate new pipeline CI variables with url params", :js do
end end
it "var[key1]=value1 populates env_var variable correctly" do it "var[key1]=value1 populates env_var variable correctly" do
page.within('.ci-variable-list .js-row:nth-child(1)') do page.within(all("[data-testid='ci-variable-row']")[0]) do
expect(find('.js-ci-variable-input-variable-type').value).to eq('env_var') expect(find("[data-testid='pipeline-form-ci-variable-type']").value).to eq('env_var')
expect(find('.js-ci-variable-input-key').value).to eq('key1') expect(find("[data-testid='pipeline-form-ci-variable-key']").value).to eq('key1')
expect(find('.js-ci-variable-input-value').text).to eq('value1') expect(find("[data-testid='pipeline-form-ci-variable-value']").value).to eq('value1')
end end
end end
it "file_var[key2]=value2 populates file variable correctly" do it "file_var[key2]=value2 populates file variable correctly" do
page.within('.ci-variable-list .js-row:nth-child(2)') do page.within(all("[data-testid='ci-variable-row']")[1]) do
expect(find('.js-ci-variable-input-variable-type').value).to eq('file') expect(find("[data-testid='pipeline-form-ci-variable-type']").value).to eq('file')
expect(find('.js-ci-variable-input-key').value).to eq('key2') expect(find("[data-testid='pipeline-form-ci-variable-key']").value).to eq('key2')
expect(find('.js-ci-variable-input-value').text).to eq('value2') expect(find("[data-testid='pipeline-form-ci-variable-value']").value).to eq('value2')
end end
end end
end end

View File

@ -657,26 +657,28 @@ RSpec.describe 'Pipelines', :js do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
before do before do
stub_feature_flags(new_pipeline_form: false)
visit new_project_pipeline_path(project) visit new_project_pipeline_path(project)
end end
context 'for valid commit', :js do context 'for valid commit', :js do
before do before do
click_button project.default_branch click_button project.default_branch
wait_for_requests
page.within '.dropdown-menu' do find('p', text: 'master').click
click_link 'master' wait_for_requests
end
end end
context 'with gitlab-ci.yml' do context 'with gitlab-ci.yml', :js do
before do before do
stub_ci_pipeline_to_return_yaml_file stub_ci_pipeline_to_return_yaml_file
end end
it 'creates a new pipeline' do it 'creates a new pipeline' do
expect { click_on 'Run pipeline' } expect do
click_on 'Run pipeline'
wait_for_requests
end
.to change { Ci::Pipeline.count }.by(1) .to change { Ci::Pipeline.count }.by(1)
expect(Ci::Pipeline.last).to be_web expect(Ci::Pipeline.last).to be_web
@ -684,12 +686,15 @@ RSpec.describe 'Pipelines', :js do
context 'when variables are specified' do context 'when variables are specified' do
it 'creates a new pipeline with variables' do it 'creates a new pipeline with variables' do
page.within '.ci-variable-row-body' do page.within(find("[data-testid='ci-variable-row']")) do
fill_in "Input variable key", with: "key_name" find("[data-testid='pipeline-form-ci-variable-key']").set('key_name')
fill_in "Input variable value", with: "value" find("[data-testid='pipeline-form-ci-variable-value']").set('value')
end end
expect { click_on 'Run pipeline' } expect do
click_on 'Run pipeline'
wait_for_requests
end
.to change { Ci::Pipeline.count }.by(1) .to change { Ci::Pipeline.count }.by(1)
expect(Ci::Pipeline.last.variables.map { |var| var.slice(:key, :secret_value) }) expect(Ci::Pipeline.last.variables.map { |var| var.slice(:key, :secret_value) })
@ -701,19 +706,17 @@ RSpec.describe 'Pipelines', :js do
context 'without gitlab-ci.yml' do context 'without gitlab-ci.yml' do
before do before do
click_on 'Run pipeline' click_on 'Run pipeline'
wait_for_requests
end end
it { expect(page).to have_content('Missing CI config file') } it { expect(page).to have_content('Missing CI config file') }
it 'creates a pipeline after first request failed and a valid gitlab-ci.yml file is available when trying again' do it 'creates a pipeline after first request failed and a valid gitlab-ci.yml file is available when trying again' do
click_button project.default_branch
stub_ci_pipeline_to_return_yaml_file stub_ci_pipeline_to_return_yaml_file
page.within '.dropdown-menu' do expect do
click_link 'master' click_on 'Run pipeline'
wait_for_requests
end end
expect { click_on 'Run pipeline' }
.to change { Ci::Pipeline.count }.by(1) .to change { Ci::Pipeline.count }.by(1)
end end
end end
@ -760,14 +763,13 @@ RSpec.describe 'Pipelines', :js do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
before do before do
stub_feature_flags(new_pipeline_form: false)
visit new_project_pipeline_path(project) visit new_project_pipeline_path(project)
end end
describe 'new pipeline page' do describe 'new pipeline page' do
it 'has field to add a new pipeline' do it 'has field to add a new pipeline' do
expect(page).to have_selector('.js-branch-select') expect(page).to have_selector('[data-testid="ref-select"]')
expect(find('.js-branch-select')).to have_content project.default_branch expect(find('[data-testid="ref-select"]')).to have_content project.default_branch
expect(page).to have_content('Run for') expect(page).to have_content('Run for')
end end
end end
@ -776,10 +778,10 @@ RSpec.describe 'Pipelines', :js do
it 'shows filtered pipelines', :js do it 'shows filtered pipelines', :js do
click_button project.default_branch click_button project.default_branch
page.within '.dropdown-menu' do page.within '[data-testid="ref-select"]' do
find('.dropdown-input-field').native.send_keys('fix') find('[data-testid="search-refs"]').native.send_keys('fix')
page.within '.dropdown-content' do page.within '.gl-new-dropdown-contents' do
expect(page).to have_content('fix') expect(page).to have_content('fix')
end end
end end

View File

@ -66,20 +66,32 @@ describe('setInitialBoardData', () => {
}); });
describe('setFilters', () => { describe('setFilters', () => {
it('should commit mutation SET_FILTERS', (done) => { it.each([
[
'with correct filters as payload',
{
filters: { labelName: 'label' },
updatedFilters: { labelName: 'label', not: {} },
},
],
[
'and updates assigneeWildcardId',
{
filters: { assigneeId: 'None' },
updatedFilters: { assigneeWildcardId: 'NONE', not: {} },
},
],
])('should commit mutation SET_FILTERS %s', (_, { filters, updatedFilters }) => {
const state = { const state = {
filters: {}, filters: {},
}; };
const filters = { labelName: 'label' };
testAction( testAction(
actions.setFilters, actions.setFilters,
filters, filters,
state, state,
[{ type: types.SET_FILTERS, payload: { ...filters, not: {} } }], [{ type: types.SET_FILTERS, payload: updatedFilters }],
[], [],
done,
); );
}); });
}); });

View File

@ -10,6 +10,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers
end end
let_it_be(:connection) { ActiveRecord::Base.connection } let_it_be(:connection) { ActiveRecord::Base.connection }
let(:referenced_table) { :issues } let(:referenced_table) { :issues }
let(:function_name) { '_test_partitioned_foreign_keys_function' } let(:function_name) { '_test_partitioned_foreign_keys_function' }
let(:trigger_name) { '_test_partitioned_foreign_keys_trigger' } let(:trigger_name) { '_test_partitioned_foreign_keys_trigger' }

View File

@ -12,6 +12,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::TableManagementHe
end end
let_it_be(:connection) { ActiveRecord::Base.connection } let_it_be(:connection) { ActiveRecord::Base.connection }
let(:source_table) { :_test_original_table } let(:source_table) { :_test_original_table }
let(:partitioned_table) { '_test_migration_partitioned_table' } let(:partitioned_table) { '_test_migration_partitioned_table' }
let(:function_name) { '_test_migration_function_name' } let(:function_name) { '_test_migration_function_name' }

View File

@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::RepositoryCache do RSpec.describe Gitlab::RepositoryCache do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let(:backend) { double('backend').as_null_object } let(:backend) { double('backend').as_null_object }
let(:repository) { project.repository } let(:repository) { project.repository }
let(:namespace) { "#{repository.full_path}:#{project.id}" } let(:namespace) { "#{repository.full_path}:#{project.id}" }
@ -38,6 +39,7 @@ RSpec.describe Gitlab::RepositoryCache do
describe 'personal snippet repository' do describe 'personal snippet repository' do
let_it_be(:personal_snippet) { create(:personal_snippet) } let_it_be(:personal_snippet) { create(:personal_snippet) }
let(:namespace) { repository.full_path } let(:namespace) { repository.full_path }
it_behaves_like 'cache_key examples' do it_behaves_like 'cache_key examples' do

View File

@ -4,6 +4,7 @@ require "spec_helper"
RSpec.describe Gitlab::RepositoryHashCache, :clean_gitlab_redis_cache do RSpec.describe Gitlab::RepositoryHashCache, :clean_gitlab_redis_cache do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let(:repository) { project.repository } let(:repository) { project.repository }
let(:namespace) { "#{repository.full_path}:#{project.id}" } let(:namespace) { "#{repository.full_path}:#{project.id}" }
let(:cache) { described_class.new(repository) } let(:cache) { described_class.new(repository) }

View File

@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do RSpec.describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let(:repository) { project.repository } let(:repository) { project.repository }
let(:namespace) { "#{repository.full_path}:#{project.id}" } let(:namespace) { "#{repository.full_path}:#{project.id}" }
let(:cache) { described_class.new(repository) } let(:cache) { described_class.new(repository) }
@ -34,6 +35,7 @@ RSpec.describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do
describe 'personal snippet repository' do describe 'personal snippet repository' do
let_it_be(:personal_snippet) { create(:personal_snippet) } let_it_be(:personal_snippet) { create(:personal_snippet) }
let(:namespace) { repository.full_path } let(:namespace) { repository.full_path }
it_behaves_like 'cache_key examples' do it_behaves_like 'cache_key examples' do

View File

@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::RepositorySizeChecker do RSpec.describe Gitlab::RepositorySizeChecker do
let_it_be(:namespace) { nil } let_it_be(:namespace) { nil }
let(:current_size) { 0 } let(:current_size) { 0 }
let(:limit) { 50 } let(:limit) { 50 }
let(:enabled) { true } let(:enabled) { true }

View File

@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::RepositorySizeErrorMessage do RSpec.describe Gitlab::RepositorySizeErrorMessage do
let_it_be(:namespace) { build(:namespace) } let_it_be(:namespace) { build(:namespace) }
let(:checker) do let(:checker) do
Gitlab::RepositorySizeChecker.new( Gitlab::RepositorySizeChecker.new(
current_size_proc: -> { 15.megabytes }, current_size_proc: -> { 15.megabytes },

View File

@ -141,7 +141,7 @@ RSpec.describe Namespace do
end end
it 'allows updating other attributes for existing record' do it 'allows updating other attributes for existing record' do
namespace = build(:namespace, path: 'j') namespace = build(:namespace, path: 'j', owner: create(:user))
namespace.save(validate: false) namespace.save(validate: false)
namespace.reload namespace.reload

View File

@ -65,10 +65,16 @@ RSpec.describe SlackService do
end end
context 'wiki_page notification' do context 'wiki_page notification' do
let_it_be(:wiki_page) { create(:wiki_page, wiki: project.wiki, message: 'user created page: Awesome wiki_page') } let(:wiki_page) { create(:wiki_page, wiki: project.wiki, message: 'user created page: Awesome wiki_page') }
let(:data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') } let(:data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') }
before do
# Skip this method that is not relevant to this test to prevent having
# to update project which is frozen
allow(project.wiki).to receive(:after_wiki_activity)
end
it_behaves_like 'increases the usage data counter', 'i_ecosystem_slack_service_wiki_page_notification' it_behaves_like 'increases the usage data counter', 'i_ecosystem_slack_service_wiki_page_notification'
end end

View File

@ -1,5 +1,17 @@
# frozen_string_literal: true # frozen_string_literal: true
module Gitlab
module FreezeFactoryDefault
def set_factory_default(name, obj, preserve_traits: nil)
obj.freeze unless obj.frozen?
super
end
end
end
TestProf::FactoryDefault::DefaultSyntax.prepend Gitlab::FreezeFactoryDefault
RSpec.configure do |config| RSpec.configure do |config|
config.after do |ex| config.after do |ex|
TestProf::FactoryDefault.reset unless ex.metadata[:factory_default] == :keep TestProf::FactoryDefault.reset unless ex.metadata[:factory_default] == :keep

View File

@ -1,34 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'projects/pipelines/new' do
include Devise::Test::ControllerHelpers
let_it_be(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_pipeline, project: project) }
before do
assign(:project, project)
assign(:pipeline, pipeline)
stub_feature_flags(new_pipeline_form: false)
end
describe 'warning messages' do
let(:warning_messages) do
[double(content: 'warning 1'), double(content: 'warning 2')]
end
before do
allow(pipeline).to receive(:warning_messages).and_return(warning_messages)
end
it 'displays the warnings' do
render
expect(rendered).to have_css('div.bs-callout-warning')
expect(rendered).to have_content('warning 1')
expect(rendered).to have_content('warning 2')
end
end
end

View File

@ -12,8 +12,6 @@ RSpec.describe 'projects/pipelines/show' do
before do before do
assign(:project, project) assign(:project, project)
assign(:pipeline, presented_pipeline) assign(:pipeline, presented_pipeline)
stub_feature_flags(new_pipeline_form: false)
end end
context 'when pipeline has errors' do context 'when pipeline has errors' do

0
vendor/gitignore/C++.gitignore vendored Executable file → Normal file
View File

0
vendor/gitignore/Java.gitignore vendored Executable file → Normal file
View File