Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
98f1353fcd
commit
96740a3316
|
|
@ -697,8 +697,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
|||
- spec/lib/gitlab/closing_issue_extractor_spec.rb
|
||||
- spec/lib/gitlab/composer/cache_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/email/handler/service_desk_handler_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/reactive_cache_set_cache_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/shell_spec.rb
|
||||
- spec/models/abuse_report_spec.rb
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { sortBy, cloneDeep } from 'lodash';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { ListType, NOT_FILTER } from './constants';
|
||||
import { ListType, NOT_FILTER, AssigneeIdParamValues } from './constants';
|
||||
|
||||
export function getMilestone() {
|
||||
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
|
||||
export function transformBoardConfig() {
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,20 @@ import boardBlockingIssuesQuery from './graphql/board_blocking_issues.query.grap
|
|||
import issueSetSubscriptionMutation from './graphql/issue_set_subscription.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 = {
|
||||
issue: 'issue',
|
||||
epic: 'epic',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import * as Sentry from '@sentry/browser';
|
||||
import { pick } from 'lodash';
|
||||
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 issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
|
||||
|
|
@ -11,6 +10,7 @@ import {
|
|||
ISSUABLE,
|
||||
titleQueries,
|
||||
subscriptionQueries,
|
||||
SupportedFilters,
|
||||
} from '~/boards/constants';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import createGqClient, { fetchPolicies } from '~/lib/graphql';
|
||||
|
|
@ -27,6 +27,7 @@ import {
|
|||
transformNotFilters,
|
||||
moveItemListHelper,
|
||||
getMoveData,
|
||||
getSupportedParams,
|
||||
} from '../boards_util';
|
||||
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
|
||||
import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql';
|
||||
|
|
@ -65,16 +66,11 @@ export default {
|
|||
},
|
||||
|
||||
setFilters: ({ commit }, filters) => {
|
||||
const filterParams = pick(filters, [
|
||||
'assigneeUsername',
|
||||
'authorUsername',
|
||||
'labelName',
|
||||
'milestoneTitle',
|
||||
'releaseTag',
|
||||
'search',
|
||||
'myReactionEmoji',
|
||||
]);
|
||||
filterParams.not = transformNotFilters(filters);
|
||||
const filterParams = {
|
||||
...getSupportedParams(filters, SupportedFilters),
|
||||
not: transformNotFilters(filters),
|
||||
};
|
||||
|
||||
commit(types.SET_FILTERS, filterParams);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -393,6 +393,7 @@ export default {
|
|||
v-model="variable.variable_type"
|
||||
:class="$options.formElementClasses"
|
||||
:options="$options.typeOptions"
|
||||
data-testid="pipeline-form-ci-variable-type"
|
||||
/>
|
||||
<gl-form-input
|
||||
v-model="variable.key"
|
||||
|
|
|
|||
|
|
@ -81,11 +81,12 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<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
|
||||
v-model.trim="searchTerm"
|
||||
:is-loading="isLoading"
|
||||
:placeholder="__('Search refs')"
|
||||
data-testid="search-refs"
|
||||
/>
|
||||
<gl-dropdown-section-header>{{ __('Branches') }}</gl-dropdown-section-header>
|
||||
<gl-dropdown-item
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ export default {
|
|||
>
|
||||
<gl-button
|
||||
:loading="isMakingRequest"
|
||||
variant="success"
|
||||
variant="confirm"
|
||||
data-qa-selector="mr_rebase_button"
|
||||
@click="rebase"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
|
||||
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
|
||||
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_filter_jobs, project, default_enabled: :yaml)
|
||||
push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml)
|
||||
|
|
|
|||
|
|
@ -193,8 +193,12 @@ module InProductMarketingHelper
|
|||
end
|
||||
end
|
||||
|
||||
def in_product_marketing_progress(track, series)
|
||||
s_('InProductMarketing|This is email %{series} of 3 in the %{track} series.') % { series: series + 1, track: track.to_s.humanize }
|
||||
def in_product_marketing_progress(track, series, format: nil)
|
||||
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
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
def unsubscribe(format: nil)
|
||||
parts = [
|
||||
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) }
|
||||
]
|
||||
def unsubscribe(track, series, format: nil)
|
||||
parts = Gitlab.com? ? unsubscribe_com(format) : unsubscribe_self_managed(track, series, format)
|
||||
|
||||
case format
|
||||
when :html
|
||||
parts.join(' ')
|
||||
|
|
@ -235,6 +237,20 @@ module InProductMarketingHelper
|
|||
|
||||
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)
|
||||
{
|
||||
create: [
|
||||
|
|
@ -314,9 +330,23 @@ module InProductMarketingHelper
|
|||
|
||||
def unsubscribe_link(format)
|
||||
unsubscribe_url = Gitlab.com? ? '%tag_unsubscribe_url%' : profile_notifications_url
|
||||
|
||||
link(s_('InProductMarketing|unsubscribe'), unsubscribe_url, format)
|
||||
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)
|
||||
case format
|
||||
when :html
|
||||
|
|
|
|||
|
|
@ -166,6 +166,10 @@
|
|||
= about_link('mailers/in_product_marketing', 'gitlab-logo-gray-rgb.png', 200)
|
||||
%tr
|
||||
%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
|
||||
%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)
|
||||
|
|
@ -183,10 +187,6 @@
|
|||
%tr
|
||||
%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)
|
||||
%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;" }
|
||||
%td{ align: "center", style: "padding:75px 20px 25px;" }
|
||||
= about_link('', 'gitlab_logo.png', 80)
|
||||
|
|
@ -202,4 +202,4 @@
|
|||
%tr{ style: "background-color: #ffffff;" }
|
||||
%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;" }
|
||||
= unsubscribe(format: :html).html_safe
|
||||
= unsubscribe(@track, @series, format: :html).html_safe
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@
|
|||
|
||||
<%= address %>
|
||||
|
||||
<%= unsubscribe %>
|
||||
<%= unsubscribe(@track, @series) %>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
%li{ class: active_when(scope.nil?) }>
|
||||
= link_to schedule_path_proc.call(nil) do
|
||||
= 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))
|
||||
|
||||
%li{ class: active_when(scope == 'active') }>
|
||||
= link_to schedule_path_proc.call('active') do
|
||||
= 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))
|
||||
|
||||
%li{ class: active_when(scope == 'inactive') }>
|
||||
= link_to schedule_path_proc.call('inactive') do
|
||||
= 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))
|
||||
|
|
|
|||
|
|
@ -1,55 +1,17 @@
|
|||
- breadcrumb_title _('Pipelines')
|
||||
- page_title s_('Pipeline|Run pipeline')
|
||||
- settings_link = link_to _('CI/CD settings'), project_settings_ci_cd_path(@project)
|
||||
|
||||
%h3.page-title
|
||||
= s_('Pipeline|Run pipeline')
|
||||
%hr
|
||||
|
||||
- if Feature.enabled?(:new_pipeline_form, @project, default_enabled: :yaml)
|
||||
#js-new-pipeline{ data: { project_id: @project.id,
|
||||
pipelines_path: project_pipelines_path(@project),
|
||||
config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project),
|
||||
default_branch: @project.default_branch,
|
||||
ref_param: params[:ref] || @project.default_branch,
|
||||
var_param: params[:var].to_json,
|
||||
file_param: params[:file_var].to_json,
|
||||
project_refs_endpoint: refs_project_path(@project, sort: 'updated_desc'),
|
||||
settings_link: project_settings_ci_cd_path(@project),
|
||||
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
|
||||
#js-new-pipeline{ data: { project_id: @project.id,
|
||||
pipelines_path: project_pipelines_path(@project),
|
||||
config_variables_path: config_variables_namespace_project_pipelines_path(@project.namespace, @project),
|
||||
default_branch: @project.default_branch,
|
||||
ref_param: params[:ref] || @project.default_branch,
|
||||
var_param: params[:var].to_json,
|
||||
file_param: params[:file_var].to_json,
|
||||
project_refs_endpoint: refs_project_path(@project, sort: 'updated_desc'),
|
||||
settings_link: project_settings_ci_cd_path(@project),
|
||||
max_warnings: ::Gitlab::Ci::Warnings::MAX_LIMIT } }
|
||||
|
|
|
|||
|
|
@ -2,23 +2,23 @@
|
|||
%li{ class: active_when(scope.nil?) }>
|
||||
= link_to build_path_proc.call(nil) do
|
||||
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)
|
||||
|
||||
%li{ class: active_when(scope == 'pending') }>
|
||||
= link_to build_path_proc.call('pending') do
|
||||
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)
|
||||
|
||||
%li{ class: active_when(scope == 'running') }>
|
||||
= link_to build_path_proc.call('running') do
|
||||
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)
|
||||
|
||||
%li{ class: active_when(scope == 'finished') }>
|
||||
= link_to build_path_proc.call('finished') do
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add gl-badge for badges in jobs page nav
|
||||
merge_request: 57938
|
||||
author: Yogi (@yo)
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add gl-badge for badges in pipeline schedules nav
|
||||
merge_request: 57937
|
||||
author: Yogi (@yo)
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix EmptyLineAfterFinalLetItBe offenses in spec/lib/gitlab/database
|
||||
merge_request: 58251
|
||||
author: Huzaifa Iftikhar @huzaifaiftikhar
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix EmptyLineAfterFinalLetItBe offenses in spec/lib/gitlab/repository
|
||||
merge_request: 58308
|
||||
author: Huzaifa Iftikhar @huzaifaiftikhar
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Enable the new pipeline form by default
|
||||
merge_request: 55250
|
||||
author:
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Correct variant of Rebase button in MR widget
|
||||
merge_request: 59684
|
||||
author:
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Change unsubscribe language for email campaign on self managed
|
||||
merge_request: 59121
|
||||
author:
|
||||
type: changed
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
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:
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ To create an issue:
|
|||
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
|
||||
|
||||
A reference topic provides information in an easily-scannable format,
|
||||
|
|
@ -133,6 +136,9 @@ Introductory sentence.
|
|||
| **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 topics can be one of two categories:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
recreating it for each example.
|
||||
|
||||
Objects created inside a `factory_default: :keep`, and using
|
||||
`create_default` inside a `let_it_be` should be frozen to prevent accidental reliance
|
||||
between test examples.
|
||||
To prevent accidental reliance between test examples, objects created
|
||||
with `create_default` are
|
||||
[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
|
||||
can create one and reuse it. In addition, we can see that only about 1/3 of the
|
||||
|
|
|
|||
|
|
@ -5571,9 +5571,6 @@ msgstr ""
|
|||
msgid "CI/CD for external repo"
|
||||
msgstr ""
|
||||
|
||||
msgid "CI/CD settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "CICDAnalytics|%{percent}%{percentSymbol}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16580,6 +16577,9 @@ msgstr ""
|
|||
msgid "InProductMarketing|How to build and test faster"
|
||||
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,"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16688,12 +16688,18 @@ msgstr ""
|
|||
msgid "InProductMarketing|This is email %{series} of 3 in the %{track} series."
|
||||
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"
|
||||
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}."
|
||||
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}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16772,6 +16778,9 @@ msgstr ""
|
|||
msgid "InProductMarketing|unsubscribe"
|
||||
msgstr ""
|
||||
|
||||
msgid "InProductMarketing|update your preferences"
|
||||
msgstr ""
|
||||
|
||||
msgid "InProductMarketing|using a CI/CD template"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23495,9 +23504,6 @@ msgstr ""
|
|||
msgid "Pipeline|Duration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pipeline|Existing branch name or tag"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pipeline|Failed"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23540,9 +23546,6 @@ msgstr ""
|
|||
msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
|
||||
msgstr ""
|
||||
|
||||
msgid "Pipeline|Run for"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pipeline|Run for branch name or tag"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23552,18 +23555,12 @@ msgstr ""
|
|||
msgid "Pipeline|Running"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pipeline|Search branches"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pipeline|Skipped"
|
||||
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."
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -5,22 +5,7 @@ FactoryBot.define do
|
|||
sequence(:name) { |n| "namespace#{n}" }
|
||||
path { name.downcase.gsub(/\s/, '_') }
|
||||
|
||||
# This is a workaround to avoid the user creating another namespace via
|
||||
# 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
|
||||
owner { association(:user, strategy: :build, namespace: instance, username: path) }
|
||||
|
||||
trait :with_aggregation_schedule do
|
||||
after(:create) do |namespace|
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ RSpec.describe "Populate new pipeline CI variables with url params", :js do
|
|||
let(:page_path) { new_project_pipeline_path(project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(new_pipeline_form: false)
|
||||
sign_in(user)
|
||||
project.add_maintainer(user)
|
||||
|
||||
|
|
@ -16,18 +15,18 @@ RSpec.describe "Populate new pipeline CI variables with url params", :js do
|
|||
end
|
||||
|
||||
it "var[key1]=value1 populates env_var variable correctly" do
|
||||
page.within('.ci-variable-list .js-row:nth-child(1)') do
|
||||
expect(find('.js-ci-variable-input-variable-type').value).to eq('env_var')
|
||||
expect(find('.js-ci-variable-input-key').value).to eq('key1')
|
||||
expect(find('.js-ci-variable-input-value').text).to eq('value1')
|
||||
page.within(all("[data-testid='ci-variable-row']")[0]) do
|
||||
expect(find("[data-testid='pipeline-form-ci-variable-type']").value).to eq('env_var')
|
||||
expect(find("[data-testid='pipeline-form-ci-variable-key']").value).to eq('key1')
|
||||
expect(find("[data-testid='pipeline-form-ci-variable-value']").value).to eq('value1')
|
||||
end
|
||||
end
|
||||
|
||||
it "file_var[key2]=value2 populates file variable correctly" do
|
||||
page.within('.ci-variable-list .js-row:nth-child(2)') do
|
||||
expect(find('.js-ci-variable-input-variable-type').value).to eq('file')
|
||||
expect(find('.js-ci-variable-input-key').value).to eq('key2')
|
||||
expect(find('.js-ci-variable-input-value').text).to eq('value2')
|
||||
page.within(all("[data-testid='ci-variable-row']")[1]) do
|
||||
expect(find("[data-testid='pipeline-form-ci-variable-type']").value).to eq('file')
|
||||
expect(find("[data-testid='pipeline-form-ci-variable-key']").value).to eq('key2')
|
||||
expect(find("[data-testid='pipeline-form-ci-variable-value']").value).to eq('value2')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -657,26 +657,28 @@ RSpec.describe 'Pipelines', :js do
|
|||
let(:project) { create(:project, :repository) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(new_pipeline_form: false)
|
||||
visit new_project_pipeline_path(project)
|
||||
end
|
||||
|
||||
context 'for valid commit', :js do
|
||||
before do
|
||||
click_button project.default_branch
|
||||
wait_for_requests
|
||||
|
||||
page.within '.dropdown-menu' do
|
||||
click_link 'master'
|
||||
end
|
||||
find('p', text: 'master').click
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
context 'with gitlab-ci.yml' do
|
||||
context 'with gitlab-ci.yml', :js do
|
||||
before do
|
||||
stub_ci_pipeline_to_return_yaml_file
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
expect(Ci::Pipeline.last).to be_web
|
||||
|
|
@ -684,12 +686,15 @@ RSpec.describe 'Pipelines', :js do
|
|||
|
||||
context 'when variables are specified' do
|
||||
it 'creates a new pipeline with variables' do
|
||||
page.within '.ci-variable-row-body' do
|
||||
fill_in "Input variable key", with: "key_name"
|
||||
fill_in "Input variable value", with: "value"
|
||||
page.within(find("[data-testid='ci-variable-row']")) do
|
||||
find("[data-testid='pipeline-form-ci-variable-key']").set('key_name')
|
||||
find("[data-testid='pipeline-form-ci-variable-value']").set('value')
|
||||
end
|
||||
|
||||
expect { click_on 'Run pipeline' }
|
||||
expect do
|
||||
click_on 'Run pipeline'
|
||||
wait_for_requests
|
||||
end
|
||||
.to change { Ci::Pipeline.count }.by(1)
|
||||
|
||||
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
|
||||
before do
|
||||
click_on 'Run pipeline'
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
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
|
||||
click_button project.default_branch
|
||||
|
||||
stub_ci_pipeline_to_return_yaml_file
|
||||
|
||||
page.within '.dropdown-menu' do
|
||||
click_link 'master'
|
||||
expect do
|
||||
click_on 'Run pipeline'
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
expect { click_on 'Run pipeline' }
|
||||
.to change { Ci::Pipeline.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
|
@ -760,14 +763,13 @@ RSpec.describe 'Pipelines', :js do
|
|||
let(:project) { create(:project, :repository) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(new_pipeline_form: false)
|
||||
visit new_project_pipeline_path(project)
|
||||
end
|
||||
|
||||
describe 'new pipeline page' do
|
||||
it 'has field to add a new pipeline' do
|
||||
expect(page).to have_selector('.js-branch-select')
|
||||
expect(find('.js-branch-select')).to have_content project.default_branch
|
||||
expect(page).to have_selector('[data-testid="ref-select"]')
|
||||
expect(find('[data-testid="ref-select"]')).to have_content project.default_branch
|
||||
expect(page).to have_content('Run for')
|
||||
end
|
||||
end
|
||||
|
|
@ -776,10 +778,10 @@ RSpec.describe 'Pipelines', :js do
|
|||
it 'shows filtered pipelines', :js do
|
||||
click_button project.default_branch
|
||||
|
||||
page.within '.dropdown-menu' do
|
||||
find('.dropdown-input-field').native.send_keys('fix')
|
||||
page.within '[data-testid="ref-select"]' do
|
||||
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')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -66,20 +66,32 @@ describe('setInitialBoardData', () => {
|
|||
});
|
||||
|
||||
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 = {
|
||||
filters: {},
|
||||
};
|
||||
|
||||
const filters = { labelName: 'label' };
|
||||
|
||||
testAction(
|
||||
actions.setFilters,
|
||||
filters,
|
||||
state,
|
||||
[{ type: types.SET_FILTERS, payload: { ...filters, not: {} } }],
|
||||
[{ type: types.SET_FILTERS, payload: updatedFilters }],
|
||||
[],
|
||||
done,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers
|
|||
end
|
||||
|
||||
let_it_be(:connection) { ActiveRecord::Base.connection }
|
||||
|
||||
let(:referenced_table) { :issues }
|
||||
let(:function_name) { '_test_partitioned_foreign_keys_function' }
|
||||
let(:trigger_name) { '_test_partitioned_foreign_keys_trigger' }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::TableManagementHe
|
|||
end
|
||||
|
||||
let_it_be(:connection) { ActiveRecord::Base.connection }
|
||||
|
||||
let(:source_table) { :_test_original_table }
|
||||
let(:partitioned_table) { '_test_migration_partitioned_table' }
|
||||
let(:function_name) { '_test_migration_function_name' }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::RepositoryCache do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:backend) { double('backend').as_null_object }
|
||||
let(:repository) { project.repository }
|
||||
let(:namespace) { "#{repository.full_path}:#{project.id}" }
|
||||
|
|
@ -38,6 +39,7 @@ RSpec.describe Gitlab::RepositoryCache do
|
|||
|
||||
describe 'personal snippet repository' do
|
||||
let_it_be(:personal_snippet) { create(:personal_snippet) }
|
||||
|
||||
let(:namespace) { repository.full_path }
|
||||
|
||||
it_behaves_like 'cache_key examples' do
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ require "spec_helper"
|
|||
|
||||
RSpec.describe Gitlab::RepositoryHashCache, :clean_gitlab_redis_cache do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:repository) { project.repository }
|
||||
let(:namespace) { "#{repository.full_path}:#{project.id}" }
|
||||
let(:cache) { described_class.new(repository) }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:repository) { project.repository }
|
||||
let(:namespace) { "#{repository.full_path}:#{project.id}" }
|
||||
let(:cache) { described_class.new(repository) }
|
||||
|
|
@ -34,6 +35,7 @@ RSpec.describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do
|
|||
|
||||
describe 'personal snippet repository' do
|
||||
let_it_be(:personal_snippet) { create(:personal_snippet) }
|
||||
|
||||
let(:namespace) { repository.full_path }
|
||||
|
||||
it_behaves_like 'cache_key examples' do
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::RepositorySizeChecker do
|
||||
let_it_be(:namespace) { nil }
|
||||
|
||||
let(:current_size) { 0 }
|
||||
let(:limit) { 50 }
|
||||
let(:enabled) { true }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::RepositorySizeErrorMessage do
|
||||
let_it_be(:namespace) { build(:namespace) }
|
||||
|
||||
let(:checker) do
|
||||
Gitlab::RepositorySizeChecker.new(
|
||||
current_size_proc: -> { 15.megabytes },
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ RSpec.describe Namespace do
|
|||
end
|
||||
|
||||
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.reload
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,16 @@ RSpec.describe SlackService do
|
|||
end
|
||||
|
||||
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') }
|
||||
|
||||
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'
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,17 @@
|
|||
# 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|
|
||||
config.after do |ex|
|
||||
TestProf::FactoryDefault.reset unless ex.metadata[:factory_default] == :keep
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -12,8 +12,6 @@ RSpec.describe 'projects/pipelines/show' do
|
|||
before do
|
||||
assign(:project, project)
|
||||
assign(:pipeline, presented_pipeline)
|
||||
|
||||
stub_feature_flags(new_pipeline_form: false)
|
||||
end
|
||||
|
||||
context 'when pipeline has errors' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue