Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2e1b10493f
commit
0c4a28ded2
|
|
@ -802,7 +802,7 @@ fail-pipeline-early:
|
|||
GIT_DEPTH: 1
|
||||
before_script:
|
||||
- source scripts/utils.sh
|
||||
- install_api_client_dependencies_with_apt
|
||||
- install_gitlab_gem
|
||||
script:
|
||||
- fail_pipeline_early
|
||||
# EE: Canonical MR pipelines
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ review-build-cng:
|
|||
stage: review-prepare
|
||||
before_script:
|
||||
- source ./scripts/utils.sh
|
||||
- install_api_client_dependencies_with_apk
|
||||
- install_gitlab_gem
|
||||
needs:
|
||||
- job: compile-production-assets
|
||||
|
|
|
|||
|
|
@ -97,26 +97,6 @@ Rails/SaveBang:
|
|||
- 'ee/spec/models/visible_approvable_spec.rb'
|
||||
- 'ee/spec/models/vulnerabilities/feedback_spec.rb'
|
||||
- 'ee/spec/models/vulnerabilities/issue_link_spec.rb'
|
||||
- 'ee/spec/requests/api/boards_spec.rb'
|
||||
- 'ee/spec/requests/api/epic_issues_spec.rb'
|
||||
- 'ee/spec/requests/api/epic_links_spec.rb'
|
||||
- 'ee/spec/requests/api/epics_spec.rb'
|
||||
- 'ee/spec/requests/api/geo_nodes_spec.rb'
|
||||
- 'ee/spec/requests/api/geo_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/group/epics_spec.rb'
|
||||
- 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb'
|
||||
- 'ee/spec/requests/api/groups_spec.rb'
|
||||
- 'ee/spec/requests/api/issues_spec.rb'
|
||||
- 'ee/spec/requests/api/ldap_group_links_spec.rb'
|
||||
- 'ee/spec/requests/api/merge_request_approval_rules_spec.rb'
|
||||
- 'ee/spec/requests/api/merge_request_approvals_spec.rb'
|
||||
- 'ee/spec/requests/api/merge_requests_spec.rb'
|
||||
- 'ee/spec/requests/api/project_approvals_spec.rb'
|
||||
- 'ee/spec/requests/api/projects_spec.rb'
|
||||
- 'ee/spec/requests/api/protected_branches_spec.rb'
|
||||
- 'ee/spec/requests/api/scim_spec.rb'
|
||||
- 'ee/spec/requests/api/todos_spec.rb'
|
||||
- 'ee/spec/requests/lfs_http_spec.rb'
|
||||
- 'ee/spec/services/approval_rules/finalize_service_spec.rb'
|
||||
- 'ee/spec/services/approval_rules/update_service_spec.rb'
|
||||
- 'ee/spec/services/ee/boards/issues/create_service_spec.rb'
|
||||
|
|
@ -566,7 +546,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
|||
- ee/spec/lib/gitlab/graphql/aggregations/vulnerability_statistics/lazy_aggregate_spec.rb
|
||||
- ee/spec/lib/gitlab/insights/project_insights_config_spec.rb
|
||||
- ee/spec/lib/gitlab/sitemaps/url_extractor_spec.rb
|
||||
- ee/spec/migrations/backfill_version_author_and_created_at_spec.rb
|
||||
- ee/spec/models/analytics/cycle_analytics/group_level_spec.rb
|
||||
- ee/spec/models/burndown_spec.rb
|
||||
- ee/spec/models/ci/build_spec.rb
|
||||
|
|
@ -805,9 +784,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
|||
- spec/features/cycle_analytics_spec.rb
|
||||
- spec/features/dashboard/datetime_on_tooltips_spec.rb
|
||||
- spec/features/dashboard/merge_requests_spec.rb
|
||||
- spec/features/error_tracking/user_filters_errors_by_status_spec.rb
|
||||
- spec/features/error_tracking/user_searches_sentry_errors_spec.rb
|
||||
- spec/features/error_tracking/user_sees_error_index_spec.rb
|
||||
- spec/features/file_uploads/group_import_spec.rb
|
||||
- spec/features/file_uploads/project_import_spec.rb
|
||||
- spec/features/file_uploads/user_avatar_spec.rb
|
||||
|
|
@ -1017,13 +993,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
|||
- spec/models/blob_viewer/metrics_dashboard_yml_spec.rb
|
||||
- spec/models/chat_name_spec.rb
|
||||
- spec/models/chat_team_spec.rb
|
||||
- spec/models/ci/artifact_blob_spec.rb
|
||||
- spec/models/ci/build_spec.rb
|
||||
- spec/models/ci/build_trace_chunk_spec.rb
|
||||
- spec/models/ci/daily_build_group_report_result_spec.rb
|
||||
- spec/models/ci/pipeline_spec.rb
|
||||
- spec/models/ci/runner_spec.rb
|
||||
- spec/models/ci/stage_spec.rb
|
||||
- spec/models/clusters/kubernetes_namespace_spec.rb
|
||||
- spec/models/commit_spec.rb
|
||||
- spec/models/deploy_token_spec.rb
|
||||
|
|
|
|||
|
|
@ -2,14 +2,20 @@
|
|||
|
||||
import $ from 'jquery';
|
||||
import Cookies from 'js-cookie';
|
||||
import createFlash from '~/flash';
|
||||
import { s__ } from '~/locale';
|
||||
import { localTimeAgo } from './lib/utils/datetime_utility';
|
||||
import Pager from './pager';
|
||||
|
||||
export default class Activities {
|
||||
constructor(container = '') {
|
||||
this.container = container;
|
||||
constructor(containerSelector = '') {
|
||||
this.containerSelector = containerSelector;
|
||||
this.containerEl = this.containerSelector
|
||||
? document.querySelector(this.containerSelector)
|
||||
: undefined;
|
||||
this.$contentList = $('.content_list');
|
||||
|
||||
Pager.init(20, true, false, (data) => data, this.updateTooltips, this.container);
|
||||
this.loadActivities();
|
||||
|
||||
$('.event-filter-link').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
|
@ -18,13 +24,30 @@ export default class Activities {
|
|||
});
|
||||
}
|
||||
|
||||
loadActivities() {
|
||||
Pager.init({
|
||||
limit: 20,
|
||||
preload: true,
|
||||
prepareData: (data) => data,
|
||||
successCallback: () => this.updateTooltips(),
|
||||
errorCallback: () =>
|
||||
createFlash({
|
||||
message: s__(
|
||||
'Activity|An error occured while retrieving activity. Reload the page to try again.',
|
||||
),
|
||||
parent: this.containerEl,
|
||||
}),
|
||||
container: this.containerSelector,
|
||||
});
|
||||
}
|
||||
|
||||
updateTooltips() {
|
||||
localTimeAgo($('.js-timeago', '.content_list'));
|
||||
}
|
||||
|
||||
reloadActivities() {
|
||||
$('.content_list').html('');
|
||||
Pager.init(20, true, false, (data) => data, this.updateTooltips, this.container);
|
||||
this.$contentList.html('');
|
||||
this.loadActivities();
|
||||
}
|
||||
|
||||
toggleFilter(sender) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export default class CommitsList {
|
|||
|
||||
this.$contentList = $('.content_list');
|
||||
|
||||
Pager.init(parseInt(limit, 10), false, false, this.processCommits.bind(this));
|
||||
Pager.init({ limit: parseInt(limit, 10), prepareData: this.processCommits.bind(this) });
|
||||
|
||||
this.content = $('#commits-list');
|
||||
this.searchField = $('#commits-search');
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const typeWithPlaceholder = {
|
|||
|
||||
const placeholderForType = {
|
||||
[typeWithPlaceholder.SLACK]: __('Slack channels (e.g. general, development)'),
|
||||
[typeWithPlaceholder.MATTERMOST]: __('Channel handle (e.g. town-square)'),
|
||||
[typeWithPlaceholder.MATTERMOST]: __('my-channel'),
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -8,19 +8,21 @@ const ENDLESS_SCROLL_BOTTOM_PX = 400;
|
|||
const ENDLESS_SCROLL_FIRE_DELAY_MS = 1000;
|
||||
|
||||
export default {
|
||||
init(
|
||||
init({
|
||||
limit = 0,
|
||||
preload = false,
|
||||
disable = false,
|
||||
prepareData = $.noop,
|
||||
callback = $.noop,
|
||||
successCallback = $.noop,
|
||||
errorCallback = $.noop,
|
||||
container = '',
|
||||
) {
|
||||
} = {}) {
|
||||
this.limit = limit;
|
||||
this.offset = parseInt(getParameterByName('offset'), 10) || this.limit;
|
||||
this.disable = disable;
|
||||
this.prepareData = prepareData;
|
||||
this.callback = callback;
|
||||
this.successCallback = successCallback;
|
||||
this.errorCallback = errorCallback;
|
||||
this.loading = $(`${container} .loading`).first();
|
||||
if (preload) {
|
||||
this.offset = 0;
|
||||
|
|
@ -42,7 +44,7 @@ export default {
|
|||
})
|
||||
.then(({ data }) => {
|
||||
this.append(data.count, this.prepareData(data.html));
|
||||
this.callback();
|
||||
this.successCallback();
|
||||
|
||||
// keep loading until we've filled the viewport height
|
||||
if (!this.disable && !this.isScrollable()) {
|
||||
|
|
@ -51,7 +53,8 @@ export default {
|
|||
this.loading.hide();
|
||||
}
|
||||
})
|
||||
.catch(() => this.loading.hide());
|
||||
.catch((err) => this.errorCallback(err))
|
||||
.finally(() => this.loading.hide());
|
||||
},
|
||||
|
||||
append(count, html) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import Activities from '~/activities';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => new Activities());
|
||||
// eslint-disable-next-line no-new
|
||||
new Activities();
|
||||
|
|
|
|||
|
|
@ -104,12 +104,7 @@ export default {
|
|||
const firstJobDefined = Boolean(group.jobs?.[0]);
|
||||
|
||||
if (!firstJobDefined) {
|
||||
const currentGroup = this.groups.find((element) => element.name === group.name);
|
||||
const serializedGroup = Object.entries(currentGroup).join(' ');
|
||||
reportToSentry(
|
||||
'stage_column_component',
|
||||
`undefined_job_hunt, serialized group: ${serializedGroup}`,
|
||||
);
|
||||
reportToSentry('stage_column_component', 'undefined_job_hunt');
|
||||
}
|
||||
|
||||
return group.size === 1 && firstJobDefined;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { reportToSentry } from '../utils';
|
||||
|
||||
const unwrapGroups = (stages) => {
|
||||
return stages.map((stage) => {
|
||||
const {
|
||||
|
|
@ -8,6 +10,10 @@ const unwrapGroups = (stages) => {
|
|||
};
|
||||
|
||||
const unwrapNodesWithName = (jobArray, prop, field = 'name') => {
|
||||
if (jobArray.length < 1) {
|
||||
reportToSentry('unwrapping_utils', 'undefined_job_hunt, array empty from backend');
|
||||
}
|
||||
|
||||
return jobArray.map((job) => {
|
||||
return { ...job, [prop]: job[prop].nodes.map((item) => item[field] || '') };
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,22 +27,33 @@ const DEFAULT_SNOWPLOW_OPTIONS = {
|
|||
pageUnloadTimer: 10,
|
||||
};
|
||||
|
||||
const addExperimentContext = (opts) => {
|
||||
const { experiment, ...options } = opts;
|
||||
if (experiment) {
|
||||
const data = getExperimentData(experiment);
|
||||
if (data) {
|
||||
const context = { schema: TRACKING_CONTEXT_SCHEMA, data };
|
||||
return { ...options, context };
|
||||
}
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
const createEventPayload = (el, { suffix = '' } = {}) => {
|
||||
const action = (el.dataset.trackAction || el.dataset.trackEvent) + (suffix || '');
|
||||
let value = el.dataset.trackValue || el.value || undefined;
|
||||
if (el.type === 'checkbox' && !el.checked) value = false;
|
||||
|
||||
let context = el.dataset.trackContext;
|
||||
if (el.dataset.trackExperiment) {
|
||||
const data = getExperimentData(el.dataset.trackExperiment);
|
||||
if (data) context = { schema: TRACKING_CONTEXT_SCHEMA, data };
|
||||
}
|
||||
const context = addExperimentContext({
|
||||
experiment: el.dataset.trackExperiment,
|
||||
context: el.dataset.trackContext,
|
||||
});
|
||||
|
||||
const data = {
|
||||
label: el.dataset.trackLabel,
|
||||
property: el.dataset.trackProperty,
|
||||
value,
|
||||
context,
|
||||
...context,
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
@ -150,7 +161,8 @@ export default class Tracking {
|
|||
return localCategory || opts.category;
|
||||
},
|
||||
trackingOptions() {
|
||||
return { ...opts, ...this.tracking };
|
||||
const options = addExperimentContext(opts);
|
||||
return { ...options, ...this.tracking };
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ class Projects::NetworkController < Projects::ApplicationController
|
|||
include ExtractsPath
|
||||
include ApplicationHelper
|
||||
|
||||
before_action :disable_query_limiting
|
||||
before_action :require_non_empty_project
|
||||
before_action :assign_ref_vars
|
||||
before_action :authorize_download_code!
|
||||
|
|
@ -41,8 +40,4 @@ class Projects::NetworkController < Projects::ApplicationController
|
|||
|
||||
@commit = @repo.commit(@options[:extended_sha1])
|
||||
end
|
||||
|
||||
def disable_query_limiting
|
||||
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20782')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,29 +4,29 @@ module ServicesHelper
|
|||
def service_event_description(event)
|
||||
case event
|
||||
when "push", "push_events"
|
||||
s_("ProjectService|Event triggered when someone pushes to the repository.")
|
||||
s_("ProjectService|Trigger event for pushes to the repository.")
|
||||
when "tag_push", "tag_push_events"
|
||||
s_("ProjectService|Event triggered when a new tag is pushed to the repository.")
|
||||
s_("ProjectService|Trigger event for new tags pushed to the repository.")
|
||||
when "note", "note_events"
|
||||
s_("ProjectService|Event triggered when someone adds a comment.")
|
||||
s_("ProjectService|Trigger event for new comments.")
|
||||
when "confidential_note", "confidential_note_events"
|
||||
s_("ProjectService|Event triggered when someone adds a comment on a confidential issue.")
|
||||
s_("ProjectService|Trigger event for new comments on confidential issues.")
|
||||
when "issue", "issue_events"
|
||||
s_("ProjectService|Event triggered when an issue is created, updated, or closed.")
|
||||
s_("ProjectService|Trigger event when an issue is created, updated, or closed.")
|
||||
when "confidential_issue", "confidential_issue_events"
|
||||
s_("ProjectService|Event triggered when a confidential issue is created, updated, or closed.")
|
||||
s_("ProjectService|Trigger event when a confidential issue is created, updated, or closed.")
|
||||
when "merge_request", "merge_request_events"
|
||||
s_("ProjectService|Event triggered when a merge request is created, updated, or merged.")
|
||||
s_("ProjectService|Trigger event when a merge request is created, updated, or merged.")
|
||||
when "pipeline", "pipeline_events"
|
||||
s_("ProjectService|Event triggered when a pipeline status changes.")
|
||||
s_("ProjectService|Trigger event when a pipeline status changes.")
|
||||
when "wiki_page", "wiki_page_events"
|
||||
s_("ProjectService|Event triggered when a wiki page is created or updated.")
|
||||
s_("ProjectService|Trigger event when a wiki page is created or updated.")
|
||||
when "commit", "commit_events"
|
||||
s_("ProjectService|Event triggered when a commit is created or updated.")
|
||||
s_("ProjectService|Trigger event when a commit is created or updated.")
|
||||
when "deployment"
|
||||
s_("ProjectService|Event triggered when a deployment starts or finishes.")
|
||||
s_("ProjectService|Trigger event when a deployment starts or finishes.")
|
||||
when "alert"
|
||||
s_("ProjectService|Event triggered when a new, unique alert is recorded.")
|
||||
s_("ProjectService|Trigger event when a new, unique alert is recorded.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -61,11 +61,11 @@ class ChatNotificationService < Service
|
|||
|
||||
def default_fields
|
||||
[
|
||||
{ type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}", required: true }.freeze,
|
||||
{ type: 'text', name: 'username', placeholder: 'e.g. GitLab' }.freeze,
|
||||
{ type: 'checkbox', name: 'notify_only_broken_pipelines' }.freeze,
|
||||
{ type: 'text', name: 'webhook', placeholder: "#{webhook_placeholder}", required: true }.freeze,
|
||||
{ type: 'text', name: 'username', placeholder: 'GitLab-integration' }.freeze,
|
||||
{ type: 'checkbox', name: 'notify_only_broken_pipelines', help: 'Do not send notifications for successful pipelines.' }.freeze,
|
||||
{ type: 'select', name: 'branches_to_be_notified', choices: branch_choices }.freeze,
|
||||
{ type: 'text', name: 'labels_to_be_notified', placeholder: 'e.g. ~backend', help: 'Only supported for issue, merge request and note events.' }.freeze
|
||||
{ type: 'text', name: 'labels_to_be_notified', placeholder: '~backend,~frontend', help: 'Send notifications for issue, merge request, and comment events with the listed labels only. Leave blank to receive notifications for all events.' }.freeze
|
||||
].freeze
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
class MattermostService < ChatNotificationService
|
||||
include SlackMattermost::Notifier
|
||||
include ActionView::Helpers::UrlHelper
|
||||
|
||||
def title
|
||||
'Mattermost notifications'
|
||||
s_('Mattermost notifications')
|
||||
end
|
||||
|
||||
def description
|
||||
'Receive event notifications in Mattermost'
|
||||
s_('Send notifications about project events to Mattermost channels.')
|
||||
end
|
||||
|
||||
def self.to_param
|
||||
|
|
@ -16,21 +17,15 @@ class MattermostService < ChatNotificationService
|
|||
end
|
||||
|
||||
def help
|
||||
'This service sends notifications about projects events to Mattermost channels.<br />
|
||||
To set up this service:
|
||||
<ol>
|
||||
<li><a href="https://docs.mattermost.com/developer/webhooks-incoming.html#enabling-incoming-webhooks">Enable incoming webhooks</a> in your Mattermost installation.</li>
|
||||
<li><a href="https://docs.mattermost.com/developer/webhooks-incoming.html#creating-integrations-using-incoming-webhooks">Add an incoming webhook</a> in your Mattermost team. The default channel can be overridden for each event.</li>
|
||||
<li>Paste the webhook <strong>URL</strong> into the field below.</li>
|
||||
<li>Select events below to enable notifications. The <strong>Channel handle</strong> and <strong>Username</strong> fields are optional.</li>
|
||||
</ol>'
|
||||
docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/mattermost'), target: '_blank', rel: 'noopener noreferrer'
|
||||
s_('Send notifications about project events to Mattermost channels. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
|
||||
end
|
||||
|
||||
def default_channel_placeholder
|
||||
"Channel handle (e.g. town-square)"
|
||||
'my-channel'
|
||||
end
|
||||
|
||||
def webhook_placeholder
|
||||
'http://mattermost.example.com/hooks/…'
|
||||
'http://mattermost.example.com/hooks/'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,14 +15,18 @@ module IssuableLinks
|
|||
return error(not_found_message, 404) unless permission_to_remove_relation?
|
||||
|
||||
remove_relation
|
||||
create_notes
|
||||
track_event
|
||||
after_destroy
|
||||
|
||||
success(message: 'Relation was removed')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def after_destroy
|
||||
create_notes
|
||||
track_event
|
||||
end
|
||||
|
||||
def remove_relation
|
||||
link.destroy!
|
||||
end
|
||||
|
|
|
|||
|
|
@ -110,7 +110,12 @@ module Projects
|
|||
setup_authorizations
|
||||
|
||||
current_user.invalidate_personal_projects_count
|
||||
create_prometheus_service
|
||||
|
||||
if Feature.enabled?(:projects_post_creation_worker, current_user, default_enabled: :yaml)
|
||||
Projects::PostCreationWorker.perform_async(@project.id)
|
||||
else
|
||||
create_prometheus_service
|
||||
end
|
||||
|
||||
create_readme if @initialize_with_readme
|
||||
end
|
||||
|
|
@ -193,6 +198,7 @@ module Projects
|
|||
@project
|
||||
end
|
||||
|
||||
# Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/326665
|
||||
def create_prometheus_service
|
||||
service = @project.find_or_initialize_service(::PrometheusService.to_param)
|
||||
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@
|
|||
|
||||
- if profile_tab?(:activity)
|
||||
#activity.tab-pane
|
||||
.flash-container
|
||||
- if can?(current_user, :read_cross_project)
|
||||
%h4.prepend-top-20
|
||||
= s_('UserProfile|Most Recent Activity')
|
||||
|
|
|
|||
|
|
@ -2112,6 +2112,14 @@
|
|||
:weight: 1
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: projects_post_creation
|
||||
:feature_category: :source_code_management
|
||||
:has_external_dependencies:
|
||||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: projects_schedule_bulk_repository_shard_moves
|
||||
:feature_category: :gitaly
|
||||
:has_external_dependencies:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
class PostCreationWorker
|
||||
include ApplicationWorker
|
||||
|
||||
feature_category :source_code_management
|
||||
idempotent!
|
||||
|
||||
def perform(project_id)
|
||||
project = Project.find_by_id(project_id)
|
||||
|
||||
return unless project
|
||||
|
||||
create_prometheus_service(project)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_prometheus_service(project)
|
||||
service = project.find_or_initialize_service(::PrometheusService.to_param)
|
||||
|
||||
# If the service has already been inserted in the database, that
|
||||
# means it came from a template, and there's nothing more to do.
|
||||
return if service.persisted?
|
||||
|
||||
return unless service.prometheus_available?
|
||||
|
||||
service.save!
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
Gitlab::ErrorTracking.track_exception(e, extra: { project_id: project.id })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Extract creation of prometheus service from Projects::CreateService
|
||||
merge_request:
|
||||
author:
|
||||
type: added
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove unused feature flag checks
|
||||
merge_request: 58469
|
||||
author:
|
||||
type: removed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Display error message when dashboard activity fetch fails
|
||||
merge_request: 57935
|
||||
author:
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add btn-default class for toggle button in admin templates
|
||||
merge_request: 58041
|
||||
author: Yogi (@yo)
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix EmptyLineAfterFinalLetItBe offenses for error tracking module
|
||||
merge_request: 58182
|
||||
author: Huzaifa Iftikhar @huzaifaiftikhar
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix EmptyLineAfterFinalLetItBe offenses in spec/models/ci
|
||||
merge_request: 58327
|
||||
author: Huzaifa Iftikhar @huzaifaiftikhar
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove On-call Edit feature flag
|
||||
merge_request: 56445
|
||||
author:
|
||||
type: other
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update mattermost integration UI text
|
||||
merge_request: 58570
|
||||
author:
|
||||
type: other
|
||||
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/322599
|
|||
milestone: '13.10'
|
||||
type: development
|
||||
group: group::continuous integration
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: usage_data_i_analytics_dev_ops_adoption
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57104
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326450
|
||||
name: projects_post_creation_worker
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58119
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326665
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::optimize
|
||||
default_enabled: true
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: usage_data_g_compliance_dashboard
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
milestone:
|
||||
type: development
|
||||
group: group::compliance
|
||||
default_enabled: true
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: usage_data_i_analytics_cohorts
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54329
|
||||
rollout_issue_url:
|
||||
milestone: '13.9'
|
||||
type: development
|
||||
group: group::optimize
|
||||
default_enabled: true
|
||||
|
|
@ -298,6 +298,8 @@
|
|||
- 1
|
||||
- - projects_git_garbage_collect
|
||||
- 1
|
||||
- - projects_post_creation
|
||||
- 1
|
||||
- - projects_schedule_bulk_repository_shard_moves
|
||||
- 1
|
||||
- - projects_update_repository_storage
|
||||
|
|
|
|||
|
|
@ -393,8 +393,8 @@ Additional information:
|
|||
GitLab recommends:
|
||||
|
||||
- Creating a [Gitaly Cluster](#gitaly-cluster) as soon as possible.
|
||||
- [Moving your projects](praefect.md#migrate-existing-repositories-to-gitaly-cluster) from NFS-based
|
||||
storage to the Gitaly Cluster.
|
||||
- [Moving your repositories](praefect.md#migrate-to-gitaly-cluster) from NFS-based storage to Gitaly
|
||||
Cluster.
|
||||
|
||||
We welcome your feedback on this process: raise a support ticket, or [comment on the epic](https://gitlab.com/groups/gitlab-org/-/epics/4916).
|
||||
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ application server, or a Gitaly node.
|
|||
WARNING:
|
||||
If you have data on an already existing storage called
|
||||
`default`, you should configure the virtual storage with another name and
|
||||
[migrate the data to the Gitaly Cluster storage](#migrate-existing-repositories-to-gitaly-cluster)
|
||||
[migrate the data to the Gitaly Cluster storage](#migrate-to-gitaly-cluster)
|
||||
afterwards.
|
||||
|
||||
Replace `PRAEFECT_INTERNAL_TOKEN` with a strong secret, which is used by
|
||||
|
|
@ -760,7 +760,7 @@ Particular attention should be shown to:
|
|||
|
||||
WARNING:
|
||||
If you have existing data stored on the default Gitaly storage,
|
||||
you should [migrate the data your Gitaly Cluster storage](#migrate-existing-repositories-to-gitaly-cluster)
|
||||
you should [migrate the data your Gitaly Cluster storage](#migrate-to-gitaly-cluster)
|
||||
first.
|
||||
|
||||
```ruby
|
||||
|
|
@ -1294,7 +1294,7 @@ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.t
|
|||
- Replace the placeholder `<up-to-date-storage>` with the Gitaly storage name containing up to date repositories.
|
||||
- Replace the placeholder `<outdated-storage>` with the Gitaly storage name containing outdated repositories.
|
||||
|
||||
## Migrate existing repositories to Gitaly Cluster
|
||||
## Migrate to Gitaly Cluster
|
||||
|
||||
To migrate to Gitaly Cluster, existing repositories stored outside Gitaly Cluster must be
|
||||
moved. There is no automatic migration but the moves can be scheduled with the GitLab API.
|
||||
|
|
@ -1308,8 +1308,8 @@ until the move has completed.
|
|||
|
||||
After creating and configuring Gitaly Cluster:
|
||||
|
||||
1. Ensure all storages are accessible to the GitLab instance. In this example, these
|
||||
are `<original_storage_name>` and `<cluster_storage_name>`.
|
||||
1. Ensure all storages are accessible to the GitLab instance. In this example, these are
|
||||
`<original_storage_name>` and `<cluster_storage_name>`.
|
||||
1. [Configure repository storage weights](../repository_storage_paths.md#configure-where-new-repositories-are-stored)
|
||||
so that the Gitaly Cluster receives all new projects. This stops new projects being created
|
||||
on existing Gitaly nodes while the migration is in progress.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ For more information, see:
|
|||
querying and scheduling snippet repository moves.
|
||||
- [The API documentation](../../api/group_repository_storage_moves.md) details the endpoints for
|
||||
querying and scheduling group repository moves **(PREMIUM SELF)**.
|
||||
- [Migrate existing repositories to Gitaly Cluster](../gitaly/praefect.md#migrate-existing-repositories-to-gitaly-cluster).
|
||||
- [Migrate to Gitaly Cluster](../gitaly/praefect.md#migrate-to-gitaly-cluster).
|
||||
|
||||
## Migrating to another GitLab instance
|
||||
|
||||
|
|
|
|||
|
|
@ -15,25 +15,29 @@ full list of reference architectures, see
|
|||
> - **High Availability:** Yes ([Praefect](#configure-praefect-postgresql) needs a third-party PostgreSQL solution for HA)
|
||||
> - **Test requests per second (RPS) rates:** API: 200 RPS, Web: 20 RPS, Git (Pull): 20 RPS, Git (Push): 4 RPS
|
||||
|
||||
| Service | Nodes | Configuration | GCP | AWS | Azure |
|
||||
|--------------------------------------------|-------------|-------------------------|-----------------|-------------|----------|
|
||||
| External load balancing node | 1 | 2 vCPU, 1.8 GB memory | n1-highcpu-2 | `c5.large` | F2s v2 |
|
||||
| Consul | 3 | 2 vCPU, 1.8 GB memory | n1-highcpu-2 | `c5.large` | F2s v2 |
|
||||
| PostgreSQL | 3 | 8 vCPU, 30 GB memory | n1-standard-8 | `m5.2xlarge` | D8s v3 |
|
||||
| PgBouncer | 3 | 2 vCPU, 1.8 GB memory | n1-highcpu-2 | `c5.large` | F2s v2 |
|
||||
| Internal load balancing node | 1 | 2 vCPU, 1.8 GB memory | n1-highcpu-2 | `c5.large` | F2s v2 |
|
||||
| Redis - Cache | 3 | 4 vCPU, 15 GB memory | n1-standard-4 | `m5.xlarge` | D4s v3 |
|
||||
| Redis - Queues / Shared State | 3 | 4 vCPU, 15 GB memory | n1-standard-4 | `m5.xlarge` | D4s v3 |
|
||||
| Redis Sentinel - Cache | 3 | 1 vCPU, 1.7 GB memory | g1-small | `t3.small` | B1MS |
|
||||
| Redis Sentinel - Queues / Shared State | 3 | 1 vCPU, 1.7 GB memory | g1-small | `t3.small` | B1MS |
|
||||
| Gitaly | 3 | 16 vCPU, 60 GB memory | n1-standard-16 | `m5.4xlarge` | D16s v3 |
|
||||
| Praefect | 3 | 2 vCPU, 1.8 GB memory | n1-highcpu-2 | `c5.large` | F2s v2 |
|
||||
| Praefect PostgreSQL | 1+* | 2 vCPU, 1.8 GB memory | n1-highcpu-2 | `c5.large` | F2s v2 |
|
||||
| Sidekiq | 4 | 4 vCPU, 15 GB memory | n1-standard-4 | `m5.xlarge` | D4s v3 |
|
||||
| GitLab Rails | 3 | 32 vCPU, 28.8 GB memory | n1-highcpu-32 | `c5.9xlarge` | F32s v2 |
|
||||
| Monitoring node | 1 | 4 vCPU, 3.6 GB memory | n1-highcpu-4 | `c5.xlarge` | F4s v2 |
|
||||
| Object storage | n/a | n/a | n/a | n/a | n/a |
|
||||
| NFS server | 1 | 4 vCPU, 3.6 GB memory | n1-highcpu-4 | `c5.xlarge` | F4s v2 |
|
||||
| Service | Nodes | Configuration | GCP | AWS | Azure |
|
||||
|--------------------------------------------|-------------|-------------------------|------------------|--------------|-----------|
|
||||
| External load balancing node | 1 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
|
||||
| Consul | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
|
||||
| PostgreSQL | 3 | 8 vCPU, 30 GB memory | `n1-standard-8` | `m5.2xlarge` | `D8s v3` |
|
||||
| PgBouncer | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
|
||||
| Internal load balancing node | 1 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
|
||||
| Redis - Cache* | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | `D4s v3` |
|
||||
| Redis - Queues / Shared State* | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | `D4s v3` |
|
||||
| Redis Sentinel - Cache* | 3 | 1 vCPU, 1.7 GB memory | `g1-small` | `t3.small` | `B1MS` |
|
||||
| Redis Sentinel - Queues / Shared State* | 3 | 1 vCPU, 1.7 GB memory | `g1-small` | `t3.small` | `B1MS` |
|
||||
| Gitaly | 3 | 16 vCPU, 60 GB memory | `n1-standard-16` | `m5.4xlarge` | `D16s v3` |
|
||||
| Praefect | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
|
||||
| Praefect PostgreSQL* | 1+ | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | `F2s v2` |
|
||||
| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | `D4s v3` |
|
||||
| GitLab Rails | 3 | 32 vCPU, 28.8 GB memory | `n1-highcpu-32` | `c5.9xlarge` | `F32s v2` |
|
||||
| Monitoring node | 1 | 4 vCPU, 3.6 GB memory | `n1-highcpu-4` | `c5.xlarge` | `F4s v2` |
|
||||
| Object storage | n/a | n/a | n/a | n/a | n/a |
|
||||
| NFS server | 1 | 4 vCPU, 3.6 GB memory | `n1-highcpu-4` | `c5.xlarge` | `F4s v2` |
|
||||
|
||||
NOTE:
|
||||
Components marked with * can be optionally run on reputable
|
||||
third party external PaaS solutions such as Google Cloud SQL or Memorystore.
|
||||
|
||||
```plantuml
|
||||
@startuml 10k
|
||||
|
|
@ -2349,29 +2353,142 @@ considered and customer technical support will be considered out of scope.
|
|||
</a>
|
||||
</div>
|
||||
|
||||
## Cloud Native Deployment (optional)
|
||||
## Cloud Native Hybrid reference architecture with Helm Charts (alternative)
|
||||
|
||||
As an alternative approach, you can also run select components of GitLab as Cloud Native
|
||||
in Kubernetes via our official [Helm Charts](https://docs.gitlab.com/charts/).
|
||||
In this setup, we support running the equivalent of GitLab Rails and Sidekiq nodes
|
||||
in a Kubernetes cluster, named Webservice and Sidekiq respectively. In addition,
|
||||
the following other supporting services are supported: NGINX, Task Runner, Migrations,
|
||||
Prometheus and Grafana.
|
||||
|
||||
Hybrid installations leverage the benefits of both cloud native and traditional
|
||||
deployments. We recommend shifting the Sidekiq and Webservice components into
|
||||
Kubernetes to reap cloud native workload management benefits while the others
|
||||
are deployed using the traditional server method already described.
|
||||
Kubernetes, you can reap certain cloud native workload management benefits while
|
||||
the others are deployed in compute VMs with Omnibus as described above in this
|
||||
page.
|
||||
|
||||
The following sections detail this hybrid approach.
|
||||
It should be noted though that this is an advanced setup as running services in
|
||||
Kubernetes is well known to be complex. **This setup is only recommended** if
|
||||
you have strong working knowledge and experience in Kubernetes. The rest of this
|
||||
section will assume this.
|
||||
|
||||
### Cluster topology
|
||||
|
||||
The following table provides a starting point for hybrid
|
||||
deployment infrastructure. The recommendations use Google Cloud's Kubernetes Engine (GKE)
|
||||
and associated machine types, but the memory and CPU requirements should
|
||||
translate to most other providers.
|
||||
The following tables and diagram details the hybrid environment using the same formats
|
||||
as the normal environment above.
|
||||
|
||||
Machine count | Machine type | Allocatable vCPUs | Allocatable memory (GB) | Purpose
|
||||
-|-|-|-|-
|
||||
2 | `n1-standard-4` | 7.75 | 25 | Non-GitLab resources, including Grafana, NGINX, and Prometheus
|
||||
4 | `n1-standard-4` | 15.5 | 50 | GitLab Sidekiq pods
|
||||
4 | `n1-highcpu-32` | 127.5 | 118 | GitLab Webservice pods
|
||||
First starting with the components that run in Kubernetes. The recommendations at this
|
||||
time use Google Cloud’s Kubernetes Engine (GKE) and associated machine types, but the memory
|
||||
and CPU requirements should translate to most other providers. We hope to update this in the
|
||||
future with further specific cloud provider details.
|
||||
|
||||
"Allocatable" in this table refers to the amount of resources available to workloads deployed in Kubernetes _after_ accounting for the overhead of running Kubernetes itself.
|
||||
| Service | Nodes | Configuration | GCP | Allocatable CPUs and Memory |
|
||||
|-------------------------------------------------------|-------|-------------------------|------------------|-----------------------------|
|
||||
| Webservice | 4 | 32 vCPU, 28.8 GB memory | `n1-standard-32` | 127.5 vCPU, 118 GB memory |
|
||||
| Sidekiq | 4 | 4 vCPU, 15 GB memory | `n1-standard-4` | 15.5 vCPU, 50 GB memory |
|
||||
| Supporting services such as NGINX, Prometheus, etc... | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | 7.75 vCPU, 25 GB memory |
|
||||
|
||||
Next are the backend components that run on static compute VMs via Omnibus (or External PaaS
|
||||
services where applicable):
|
||||
|
||||
| Service | Nodes | Configuration | GCP |
|
||||
|--------------------------------------------|-------|-------------------------|------------------|
|
||||
| Consul | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` |
|
||||
| PostgreSQL* | 3 | 8 vCPU, 30 GB memory | `n1-standard-8` |
|
||||
| PgBouncer | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` |
|
||||
| Internal load balancing node | 1 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` |
|
||||
| Redis - Cache* | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` |
|
||||
| Redis - Queues / Shared State* | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` |
|
||||
| Redis Sentinel - Cache* | 3 | 1 vCPU, 1.7 GB memory | `g1-small` |
|
||||
| Redis Sentinel - Queues / Shared State* | 3 | 1 vCPU, 1.7 GB memory | `g1-small` |
|
||||
| Gitaly | 3 | 16 vCPU, 60 GB memory | `n1-standard-16` |
|
||||
| Praefect | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` |
|
||||
| Praefect PostgreSQL* | 1+ | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` |
|
||||
| Object storage | n/a | n/a | n/a |
|
||||
|
||||
NOTE:
|
||||
Components marked with * can be optionally run on reputable
|
||||
third party external PaaS solutions such as Google Cloud SQL or Memorystore.
|
||||
|
||||
```plantuml
|
||||
@startuml 10k
|
||||
|
||||
card "Kubernetes via Helm Charts" as kubernetes {
|
||||
card "**External Load Balancer**" as elb #6a9be7
|
||||
|
||||
together {
|
||||
collections "**Webservice** x4" as gitlab #32CD32
|
||||
collections "**Sidekiq** x4" as sidekiq #ff8dd1
|
||||
}
|
||||
|
||||
card "**Prometheus + Grafana**" as monitor #7FFFD4
|
||||
card "**Supporting Services**" as support
|
||||
}
|
||||
|
||||
card "**Internal Load Balancer**" as ilb #9370DB
|
||||
collections "**Consul** x3" as consul #e76a9b
|
||||
|
||||
card "Gitaly Cluster" as gitaly_cluster {
|
||||
collections "**Praefect** x3" as praefect #FF8C00
|
||||
collections "**Gitaly** x3" as gitaly #FF8C00
|
||||
card "**Praefect PostgreSQL***\n//Non fault-tolerant//" as praefect_postgres #FF8C00
|
||||
|
||||
praefect -[#FF8C00]-> gitaly
|
||||
praefect -[#FF8C00]> praefect_postgres
|
||||
}
|
||||
|
||||
card "Database" as database {
|
||||
collections "**PGBouncer** x3" as pgbouncer #4EA7FF
|
||||
card "**PostgreSQL** (Primary)" as postgres_primary #4EA7FF
|
||||
collections "**PostgreSQL** (Secondary) x2" as postgres_secondary #4EA7FF
|
||||
|
||||
pgbouncer -[#4EA7FF]-> postgres_primary
|
||||
postgres_primary .[#4EA7FF]> postgres_secondary
|
||||
}
|
||||
|
||||
card "redis" as redis {
|
||||
collections "**Redis Persistent** x3" as redis_persistent #FF6347
|
||||
collections "**Redis Cache** x3" as redis_cache #FF6347
|
||||
collections "**Redis Persistent Sentinel** x3" as redis_persistent_sentinel #FF6347
|
||||
collections "**Redis Cache Sentinel** x3"as redis_cache_sentinel #FF6347
|
||||
|
||||
redis_persistent <.[#FF6347]- redis_persistent_sentinel
|
||||
redis_cache <.[#FF6347]- redis_cache_sentinel
|
||||
}
|
||||
|
||||
cloud "**Object Storage**" as object_storage #white
|
||||
|
||||
elb -[#6a9be7]-> gitlab
|
||||
elb -[#6a9be7]-> monitor
|
||||
elb -[hidden]-> support
|
||||
|
||||
gitlab -[#32CD32]> sidekiq
|
||||
gitlab -[#32CD32]--> ilb
|
||||
gitlab -[#32CD32]-> object_storage
|
||||
gitlab -[#32CD32]---> redis
|
||||
gitlab -[hidden]--> consul
|
||||
|
||||
sidekiq -[#ff8dd1]--> ilb
|
||||
sidekiq -[#ff8dd1]-> object_storage
|
||||
sidekiq -[#ff8dd1]---> redis
|
||||
sidekiq -[hidden]--> consul
|
||||
|
||||
ilb -[#9370DB]-> gitaly_cluster
|
||||
ilb -[#9370DB]-> database
|
||||
|
||||
consul .[#e76a9b]-> database
|
||||
consul .[#e76a9b]-> gitaly_cluster
|
||||
consul .[#e76a9b,norank]--> redis
|
||||
|
||||
monitor .[#7FFFD4]> consul
|
||||
monitor .[#7FFFD4]-> database
|
||||
monitor .[#7FFFD4]-> gitaly_cluster
|
||||
monitor .[#7FFFD4,norank]--> redis
|
||||
monitor .[#7FFFD4]> ilb
|
||||
monitor .[#7FFFD4,norank]u--> elb
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
### Resource usage settings
|
||||
|
||||
|
|
@ -2379,29 +2496,31 @@ The following formulas help when calculating how many pods may be deployed withi
|
|||
The [10k reference architecture example values file](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/ref/10k.yaml)
|
||||
documents how to apply the calculated configuration to the Helm Chart.
|
||||
|
||||
#### Webservice
|
||||
|
||||
Webservice pods typically need about 1 vCPU and 1.25 GB of memory _per worker_.
|
||||
Each Webservice pod will consume roughly 4 vCPUs and 5 GB of memory using
|
||||
the [recommended topology](#cluster-topology) because four worker processes
|
||||
are created by default and each pod has other small processes running.
|
||||
|
||||
For 10k users we recommend a total Puma worker count of around 80.
|
||||
With the [provided recommendations](#cluster-topology) this allows the deployment of up to 20
|
||||
Webservice pods with 4 workers per pod and 5 pods per node. Expand available resources using
|
||||
the ratio of 1 vCPU to 1.25 GB of memory _per each worker process_ for each additional
|
||||
Webservice pod.
|
||||
|
||||
For further information on resource usage, see the [Webservice resources](https://docs.gitlab.com/charts/charts/gitlab/webservice/#resources).
|
||||
|
||||
#### Sidekiq
|
||||
|
||||
Sidekiq pods should generally have 1 vCPU and 2 GB of memory.
|
||||
|
||||
[The provided starting point](#cluster-topology) allows the deployment of up to
|
||||
16 Sidekiq pods. Expand available resources using the 1vCPU to 2GB memory
|
||||
16 Sidekiq pods. Expand available resources using the 1 vCPU to 2GB memory
|
||||
ratio for each additional pod.
|
||||
|
||||
For further information on resource usage, see the [Sidekiq resources](https://docs.gitlab.com/charts/charts/gitlab/sidekiq/#resources).
|
||||
|
||||
#### Webservice
|
||||
|
||||
Webservice pods typically need about 1 vCPU and 1.25 GB of memory _per worker_.
|
||||
Each Webservice pod will consume roughly 2 vCPUs and 2.5 GB of memory using
|
||||
the [recommended topology](#cluster-topology) because two worker processes
|
||||
are created by default.
|
||||
|
||||
The [provided recommendations](#cluster-topology) allow the deployment of up to 28
|
||||
Webservice pods. Expand available resources using the ratio of 1 vCPU to 1.25 GB of memory
|
||||
_per each worker process_ for each additional Webservice pod.
|
||||
|
||||
For further information on resource usage, see the [Webservice resources](https://docs.gitlab.com/charts/charts/gitlab/webservice/#resources).
|
||||
|
||||
<div align="right">
|
||||
<a type="button" class="btn btn-default" href="#setup-components">
|
||||
Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
|
||||
|
|
|
|||
|
|
@ -156,5 +156,5 @@ often it is chosen. That is, `(storage weight) / (sum of all weights) * 100 = ch
|
|||
|
||||
## Move repositories
|
||||
|
||||
To move a repository to a different repository path, use
|
||||
the same process as [migrating existing repositories to Gitaly Cluster](gitaly/praefect.md#migrate-existing-repositories-to-gitaly-cluster).
|
||||
To move a repository to a different repository path, use the same process as
|
||||
[migrating to Gitaly Cluster](gitaly/praefect.md#migrate-to-gitaly-cluster).
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ type: reference
|
|||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53016) in GitLab 13.9.
|
||||
|
||||
Group repositories can be moved between storages. This can be useful when
|
||||
[migrating to Gitaly Cluster](../administration/gitaly/praefect.md#migrate-existing-repositories-to-gitaly-cluster),
|
||||
for example, or to migrate a Group Wiki.
|
||||
[migrating to Gitaly Cluster](../administration/gitaly/praefect.md#migrate-to-gitaly-cluster), for
|
||||
example, or to migrate a Group Wiki.
|
||||
|
||||
As group repository storage moves are processed, they transition through different states. Values
|
||||
of `state` are:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
## List issue relations
|
||||
|
||||
Get a list of a given issue's [related issues](../user/project/issues/related_issues.md),
|
||||
Get a list of a given issue's [linked issues](../user/project/issues/related_issues.md),
|
||||
sorted by the relationship creation datetime (ascending).
|
||||
Issues are filtered according to the user authorizations.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ type: reference
|
|||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31285) in GitLab 13.0.
|
||||
|
||||
Project repositories including wiki and design repositories can be moved between storages. This can be useful when
|
||||
[migrating to Gitaly Cluster](../administration/gitaly/praefect.md#migrate-existing-repositories-to-gitaly-cluster),
|
||||
[migrating to Gitaly Cluster](../administration/gitaly/praefect.md#migrate-to-gitaly-cluster),
|
||||
for example.
|
||||
|
||||
As project repository storage moves are processed, they transition through different states. Values
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ type: reference
|
|||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49228) in GitLab 13.8.
|
||||
|
||||
Snippet repositories can be moved between storages. This can be useful when
|
||||
[migrating to Gitaly Cluster](../administration/gitaly/praefect.md#migrate-existing-repositories-to-gitaly-cluster),
|
||||
for example.
|
||||
[migrating to Gitaly Cluster](../administration/gitaly/praefect.md#migrate-to-gitaly-cluster), for
|
||||
example.
|
||||
|
||||
As snippet repository storage moves are processed, they transition through different states. Values
|
||||
of `state` are:
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ Depending on the areas your merge request touches, it must be **approved** by on
|
|||
or more [maintainers](https://about.gitlab.com/handbook/engineering/workflow/code-review/#maintainer):
|
||||
|
||||
For approvals, we use the approval functionality found in the merge request
|
||||
widget. For reviewers, we use the [reviewer functionality](../user/project/merge_requests/getting_started.md#reviewer) in the sidebar.
|
||||
widget. For reviewers, we use the [reviewer functionality](../user/project/merge_requests/getting_started.md#reviewer) in the sidebar.
|
||||
Reviewers can add their approval by [approving additionally](../user/project/merge_requests/merge_request_approvals.md#adding-or-removing-an-approval).
|
||||
|
||||
Getting your merge request **merged** also requires a maintainer. If it requires
|
||||
|
|
@ -365,7 +365,7 @@ experience, refactors the existing code). Then:
|
|||
- For non-mandatory suggestions, decorate with (non-blocking) so the author knows they can
|
||||
optionally resolve within the merge request or follow-up at a later stage.
|
||||
- There's a [Chrome/Firefox add-on](https://gitlab.com/conventionalcomments/conventional-comments-button) which you can use to apply [Conventional Comment](https://conventionalcomments.org/) prefixes.
|
||||
- Ensure there are no open dependencies. Check [related issues](../user/project/issues/related_issues.md) for blockers. Clarify with the author(s)
|
||||
- Ensure there are no open dependencies. Check [linked issues](../user/project/issues/related_issues.md) for blockers. Clarify with the author(s)
|
||||
if necessary. If blocked by one or more open MRs, set an [MR dependency](../user/project/merge_requests/merge_request_dependencies.md).
|
||||
- After a round of line notes, it can be helpful to post a summary note such as
|
||||
"Looks good to me", or "Just a couple things to address."
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ description: "Learn how GitLab docs' global navigation works and how to add new
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/362) in GitLab 11.6.
|
||||
> - [Updated](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/482) in GitLab 12.1.
|
||||
> - [Per-project](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/498) navigation added in GitLab 12.2.
|
||||
> - [Unified global navigation](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/1482) added in GitLab 13.11.
|
||||
|
||||
Global navigation (the left-most pane in our three pane documentation) provides:
|
||||
|
||||
|
|
@ -19,24 +20,12 @@ Global navigation (the left-most pane in our three pane documentation) provides:
|
|||
- The ability to refine landing pages, so they don't have to do all the work of surfacing
|
||||
every page contained within the documentation.
|
||||
|
||||
## Quick start
|
||||
|
||||
To add a topic to the global nav, go to the directory that contains
|
||||
[navigation files](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/content/_data/)
|
||||
and edit the `yaml` file for your product area. You can copy an existing nav entry and
|
||||
edit it to point to your topic.
|
||||
|
||||
The files are:
|
||||
|
||||
| File | Document | Location |
|
||||
|-----------------------|--------------------------------------------------------------------|-------------------------------------------------------|
|
||||
| `charts-nav.yaml` | GitLab cloud native Helm Chart | `https://docs.gitlab.com/charts/` |
|
||||
| `default-nav.yaml` | GitLab Docs | `https://docs.gitlab.com/ee/` |
|
||||
| `omnibus-nav.yaml` | Omnibus GitLab Docs | `https://docs.gitlab.com/omnibus/` |
|
||||
| `runner-nav.yaml` | GitLab Runner Docs | `https://docs.gitlab.com/runner/` |
|
||||
|
||||
## Adding new items
|
||||
|
||||
To add a topic to the global nav, edit
|
||||
[`navigation.yaml`](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/content/_data/navigation.yaml)
|
||||
and add your item.
|
||||
|
||||
All new pages need a new navigation item. Without a navigation, the page becomes "orphaned". That
|
||||
is:
|
||||
|
||||
|
|
@ -84,12 +73,6 @@ mechanics of what is required is [documented below](#data-file) but, in principl
|
|||
- Avoid jargon or terms of art, unless ubiquitous. For example, **CI** is an acceptable
|
||||
substitution for **Continuous Integration**.
|
||||
- Navigation links must follow the rules documented in the [data file](#data-file).
|
||||
- EE badging is subject to the following:
|
||||
- Required when linking to an EE-only page.
|
||||
- Not required when linking to a page that is a mix of CE and EE-only content.
|
||||
- Required when all sub-items are EE-only. In this case, no sub-items are EE badged.
|
||||
- Not required when sub-items are a mix of CE and EE-only items. In this case, each item is
|
||||
badged appropriately.
|
||||
|
||||
## How it works
|
||||
|
||||
|
|
@ -101,14 +84,6 @@ The global nav has five levels:
|
|||
- Doc
|
||||
- Doc
|
||||
|
||||
The available sections are described on the table below:
|
||||
|
||||
| Section | Description |
|
||||
| ------------- | ------------------------------------ |
|
||||
| User | Documentation for the GitLab UI. |
|
||||
| Administrator | Documentation for the Admin Area. |
|
||||
| Contributor | Documentation for developing GitLab. |
|
||||
|
||||
The majority of the links available on the nav were added according to the UI.
|
||||
The match is not perfect, as for some UI nav items the documentation doesn't
|
||||
apply, and there are also other links to help the new users to discover the
|
||||
|
|
@ -116,7 +91,7 @@ documentation. The docs under **Administration** are ordered alphabetically
|
|||
for clarity.
|
||||
|
||||
To see the improvements planned, check the
|
||||
[global nav epic](https://gitlab.com/groups/gitlab-com/-/epics/21).
|
||||
[global nav epic](https://gitlab.com/groups/gitlab-org/-/epics/1599).
|
||||
|
||||
**Do not** [add items](#adding-new-items) to the global nav without
|
||||
the consent of one of the technical writers.
|
||||
|
|
@ -133,9 +108,9 @@ the data among the nav in containers properly [styled](#css-classes).
|
|||
|
||||
### Data file
|
||||
|
||||
The data file describes the structure of the navigation for the applicable project. All data files
|
||||
are stored at <https://gitlab.com/gitlab-org/gitlab-docs/blob/master/content/_data/> and comprise
|
||||
three components:
|
||||
The data file describes the structure of the navigation for the applicable project.
|
||||
It is stored at <https://gitlab.com/gitlab-org/gitlab-docs/blob/master/content/_data/navigation.yaml>
|
||||
and comprises of three main components:
|
||||
|
||||
- Sections
|
||||
- Categories
|
||||
|
|
@ -185,24 +160,6 @@ Example of section with two stand-alone categories:
|
|||
|
||||
For clarity, **always** add a blank line between categories.
|
||||
|
||||
If a category URL is not present in CE (it's an EE-only document), add the
|
||||
attribute `ee_only: true` below the category link. Example:
|
||||
|
||||
```yaml
|
||||
- category_title: Category title
|
||||
category_url: 'category-link'
|
||||
ee_only: true
|
||||
```
|
||||
|
||||
If the category links to an external URL, e.g., [GitLab Design System](https://design.gitlab.com),
|
||||
add the attribute `external_url: true` below the category title. Example:
|
||||
|
||||
```yaml
|
||||
- category_title: GitLab Design System
|
||||
category_url: 'https://design.gitlab.com'
|
||||
external_url: true
|
||||
```
|
||||
|
||||
#### Docs
|
||||
|
||||
Each doc represents the third, fourth, and fifth level of nav links. They must be always
|
||||
|
|
@ -225,7 +182,8 @@ Example with three doc links, one at each level:
|
|||
```
|
||||
|
||||
A category supports as many docs as necessary, but, for clarity, try to not
|
||||
overpopulate a category. Also, do not use more than three levels of docs.
|
||||
overpopulate a category. Also, do not use more than three levels of docs, it
|
||||
is not supported.
|
||||
|
||||
Example with multiple docs:
|
||||
|
||||
|
|
@ -239,15 +197,6 @@ Example with multiple docs:
|
|||
doc_url: 'doc-2-link'
|
||||
```
|
||||
|
||||
Whenever a document is only present in EE, add the attribute `ee-only: true`
|
||||
below the doc link. Example:
|
||||
|
||||
```yaml
|
||||
- doc_title: Document 2 title
|
||||
doc_url: 'doc-2-link'
|
||||
ee_only: true
|
||||
```
|
||||
|
||||
If you need to add a document in an external URL, add the attribute `external_url`
|
||||
below the doc link:
|
||||
|
||||
|
|
@ -266,12 +215,12 @@ Example:
|
|||
|
||||
```yaml
|
||||
- category_title: Operations
|
||||
category_url: 'user/project/integrations/prometheus_library/'
|
||||
category_url: 'ee/user/project/integrations/prometheus_library/'
|
||||
# until we have a link to operations, the first doc link is
|
||||
# repeated in the category link
|
||||
docs:
|
||||
- doc_title: Metrics
|
||||
doc_url: 'user/project/integrations/prometheus_library/'
|
||||
doc_url: 'ee/user/project/integrations/prometheus_library/'
|
||||
```
|
||||
|
||||
#### Syntax
|
||||
|
|
@ -282,43 +231,39 @@ and the following syntax rules.
|
|||
##### Titles
|
||||
|
||||
- Use sentence case, capitalizing feature names.
|
||||
- There's no need to wrap the titles, unless there's a special char in it. E.g.,
|
||||
- There's no need to wrap the titles, unless there's a special char in it. For example,
|
||||
in `GitLab CI/CD`, there's a `/` present, therefore, it must be wrapped in quotes.
|
||||
As convention, wrap the titles in double quotes: `category_title: "GitLab CI/CD"`.
|
||||
|
||||
##### URLs
|
||||
|
||||
URLs can be either relative or external, and the following apply:
|
||||
|
||||
- All links in the data file must end with `.html` (with the exception
|
||||
of `index.html` files), and not `.md`.
|
||||
- For `index.html` files, use the clean (canonical) URL: `path/to/`. For example, `https://docs.gitlab.com/ee/install/index.html` becomes `ee/install/`.
|
||||
- Do not start any relative link with a forward slash `/`.
|
||||
- As convention, always wrap URLs in single quotes `'url'`.
|
||||
- Always use relative paths against the home of CE and EE. Examples:
|
||||
- For `https://docs.gitlab.com/ee/README.html`, the relative URL is `README.html`.
|
||||
- For `https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.md`, the relative
|
||||
URL is `user/analytics/value_stream_analytics.html`.
|
||||
- For `README.html` files, add the complete path `path/to/README.html`.
|
||||
- For `index.html` files, use the clean (canonical) URL: `path/to/`.
|
||||
- For EE-only docs, use the same relative path, but add the attribute `ee_only: true` below
|
||||
the `doc_url` or `category_url`, as explained above. This displays
|
||||
an "information" icon on the nav to make the user aware that the feature is
|
||||
EE-only.
|
||||
- Always use the project prefix depending on which project the link you add
|
||||
lives in. To find the global nav link, from the full URL remove `https://docs.gitlab.com/`.
|
||||
- If a URL links to an external URL, like the [GitLab Design System](https://design.gitlab.com),
|
||||
add the attribute `external_url: true`, for example:
|
||||
|
||||
WARNING:
|
||||
All links present on the data file must end in `.html`, not `.md`. Do not
|
||||
start any relative link with a forward slash `/`.
|
||||
```yaml
|
||||
- category_title: GitLab Design System
|
||||
category_url: 'https://design.gitlab.com'
|
||||
external_url: true
|
||||
```
|
||||
|
||||
Examples:
|
||||
Examples of relative URLs:
|
||||
|
||||
```yaml
|
||||
- category_title: Issues
|
||||
category_url: 'user/project/issues/'
|
||||
# note that the above URL does not start with a slash and
|
||||
# does not include index.html at the end
|
||||
|
||||
docs:
|
||||
- doc_title: Container Scanning
|
||||
doc_url: 'user/application_security/container_scanning/'
|
||||
ee_only: true
|
||||
# note that the URL above ends in html and, as the
|
||||
# document is EE-only, the attribute ee_only is set to true.
|
||||
```
|
||||
| Full URL | Global nav URL |
|
||||
| -------------------------------------------------------------- | ------------------------------------- |
|
||||
| `https://docs.gitlab.com/ee/api/avatar.html` | `ee/api/avatar.html` |
|
||||
| `https://docs.gitlab.com/ee/install/index.html` | `ee/install/` |
|
||||
| `https://docs.gitlab.com/omnibus/settings/database.html` | `omnibus/settings/database.html` |
|
||||
| `https://docs.gitlab.com/charts/installation/deployment.html` | `charts/installation/deployment.html` |
|
||||
| `https://docs.gitlab.com/runner/install/docker.html` | `runner/install/docker.html` |
|
||||
|
||||
### Layout file (logic)
|
||||
|
||||
|
|
@ -326,74 +271,15 @@ The [layout](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/layouts/globa
|
|||
is fed by the [data file](#data-file), builds the global nav, and is rendered by the
|
||||
[default](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/layouts/default.html) layout.
|
||||
|
||||
There are three main considerations on the logic built for the nav:
|
||||
The global nav contains links from all [four upstream projects](index.md#architecture).
|
||||
The [global nav URL](#urls) has a different prefix depending on the documentation file you change.
|
||||
|
||||
- [Path](#path): first-level directories underneath `docs.gitlab.com/`:
|
||||
- `https://docs.gitlab.com/ce/`
|
||||
- `https://docs.gitlab.com/ee/`
|
||||
- `https://docs.gitlab.com/omnibus/`
|
||||
- `https://docs.gitlab.com/runner/`
|
||||
- `https://docs.gitlab.com/*`
|
||||
- [EE-only](#ee-only-docs): documentation only available in `/ee/`, not on `/ce/`, e.g.:
|
||||
- `https://docs.gitlab.com/ee/user/group/epics/`
|
||||
- `https://docs.gitlab.com/ee/user/application_security/security_dashboard/index.html`
|
||||
- [Default URL](#default-url): between CE and EE docs, the default is `ee`, therefore, all docs
|
||||
should link to `/ee/` unless if on `/ce/` linking internally to `ce`.
|
||||
|
||||
#### Path
|
||||
|
||||
To use relative paths in the data file, we defined the variable `dir`
|
||||
from the root's first-child directory, which defines the path to build
|
||||
all the nav links to other pages:
|
||||
|
||||
```html
|
||||
<% dir = @item.identifier.to_s[%r{(?<=/)[^/]+}] %>
|
||||
```
|
||||
|
||||
For instance, for `https://docs.gitlab.com/ee/user/index.html`,
|
||||
`dir` == `ee`, and for `https://docs.gitlab.com/omnibus/README.html`,
|
||||
`dir` == `omnibus`.
|
||||
|
||||
#### Default URL
|
||||
|
||||
The default and canonical URL for GitLab documentation is
|
||||
`https://docs.gitlab.com/ee/`, thus, all links
|
||||
in the docs site should link to `/ee/` except when linking
|
||||
among `/ce/` docs themselves.
|
||||
|
||||
Therefore, if the user is looking at `/ee/`, `/omnibus/`,
|
||||
`/runner/`, or any other highest-level dir, the nav should
|
||||
point to `/ee/` docs.
|
||||
|
||||
On the other hand, if the user is looking at `/ce/` docs,
|
||||
all the links in the CE nav should link internally to `/ce/`
|
||||
files.
|
||||
|
||||
```html
|
||||
<% if dir != 'ce' %>
|
||||
<a href="/ee/<%= sec[:section_url] %>">...</a>
|
||||
<% else %>
|
||||
<a href="/<%= dir %>/<%= sec[:section_url] %>">...</a>
|
||||
<% end %>
|
||||
...
|
||||
<% end %>
|
||||
```
|
||||
|
||||
This also allows the nav to be displayed on other
|
||||
highest-level directories (`/omnibus/`, `/runner/`, etc),
|
||||
linking them back to `/ee/`.
|
||||
|
||||
The same logic is applied to all sections (`sec[:section_url]`),
|
||||
categories (`cat[:category_url]`), and docs (`doc[:doc_url]`) URLs.
|
||||
|
||||
#### `ee-only` docs
|
||||
|
||||
Docs for features present only in GitLab EE are tagged
|
||||
in the data file by `ee-only` and an icon is displayed on the nav
|
||||
link indicating that the `ee-only` feature is not available in CE.
|
||||
|
||||
The `ee-only` attribute is available for `categories` (`<% if cat[:ee_only] %>`)
|
||||
and `docs` (`<% if doc[:ee_only] %>`), but not for `sections`.
|
||||
| Repository | Link prefix | Final URL |
|
||||
|----------------------------------------------------------------|-------------|-----------|
|
||||
| <https://gitlab.com/gitlab-org/gitlab/tree/master/doc> | `ee/` |`https://docs.gitlab.com/ee/` |
|
||||
| <https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/doc> | `omnibus/` |`https://docs.gitlab.com/omnibus/` |
|
||||
| <https://gitlab.com/gitlab-org/gitlab-runner/tree/master/docs> | `runner/` |`https://docs.gitlab.com/runner/` |
|
||||
| <https://gitlab.com/charts/gitlab/tree/master/doc> | `charts/` |`https://docs.gitlab.com/charts/` |
|
||||
|
||||
### CSS classes
|
||||
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ Follow these guidelines for punctuation:
|
|||
| Do not use tabs for indentation. Use spaces instead. You can configure your code editor to output spaces instead of tabs when pressing the tab key. | --- |
|
||||
| Use serial commas (_Oxford commas_) before the final _and_ or _or_ in a list of three or more items. (Tested in [`OxfordComma.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/OxfordComma.yml).) | _You can create new issues, merge requests, and milestones._ |
|
||||
| Always add a space before and after dashes when using it in a sentence (for replacing a comma, for example). | _You should try this - or not._ |
|
||||
| Always use lowercase after a colon. | _Related Issues: a way to create a relationship between issues._ |
|
||||
| Always use lowercase after a colon. | Linked issues: a way to create a relationship between issues._ |
|
||||
|
||||
<!-- vale gitlab.Repetition = YES -->
|
||||
|
||||
|
|
|
|||
|
|
@ -9908,6 +9908,30 @@ Status: `implemented`
|
|||
|
||||
Tiers: `premium`, `ultimate`
|
||||
|
||||
### `redis_hll_counters.epics_usage.g_project_management_epic_issue_removed_monthly`
|
||||
|
||||
Count of MAU removing issues from epics
|
||||
|
||||
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210401183230_g_project_management_epic_issue_removed_monthly.yml)
|
||||
|
||||
Group: `group::product planning`
|
||||
|
||||
Status: `implemented`
|
||||
|
||||
Tiers: `premium`, `ultimate`
|
||||
|
||||
### `redis_hll_counters.epics_usage.g_project_management_epic_issue_removed_weekly`
|
||||
|
||||
Counts of WAU removing issues from epics
|
||||
|
||||
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210401182457_g_project_management_g_project_management_epic_issue_removed_weekly.yml)
|
||||
|
||||
Group: `group::product planning`
|
||||
|
||||
Status: `implemented`
|
||||
|
||||
Tiers: `premium`, `ultimate`
|
||||
|
||||
### `redis_hll_counters.epics_usage.g_project_management_epic_reopened_monthly`
|
||||
|
||||
Counts of MAU closing epics
|
||||
|
|
|
|||
|
|
@ -394,4 +394,4 @@ end
|
|||
You can link related issues to a feature flag. In the **Linked issues** section,
|
||||
click the `+` button and input the issue reference number or the full URL of the issue.
|
||||
|
||||
This feature is similar to the [related issues](../user/project/issues/related_issues.md) feature.
|
||||
This feature is similar to the [linked issues](../user/project/issues/related_issues.md) feature.
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ info: "To determine the technical writer assigned to the Stage/Group associated
|
|||
type: reference, howto
|
||||
---
|
||||
|
||||
# Partial Clone **(FREE)**
|
||||
# Partial clone **(FREE)**
|
||||
|
||||
As Git repositories grow in size, they can become cumbersome to work with
|
||||
because of the large amount of history that must be downloaded, and the large
|
||||
amount of disk space they require.
|
||||
because of:
|
||||
|
||||
- The large amount of history that must be downloaded.
|
||||
- The large amount of disk space they require.
|
||||
|
||||
[Partial clone](https://github.com/git/git/blob/master/Documentation/technical/partial-clone.txt)
|
||||
is a performance optimization that "allows Git to function without having a
|
||||
|
|
@ -58,9 +60,10 @@ Updating files: 100% (13008/13008), done.
|
|||
Filtering content: 100% (3/3), 131.24 MiB | 4.65 MiB/s, done.
|
||||
```
|
||||
|
||||
The output is longer because Git first clones the repository excluding
|
||||
files larger than 1 megabyte, and second download any missing large files needed
|
||||
to checkout the `master` branch.
|
||||
The output is longer because Git:
|
||||
|
||||
1. Clones the repository excluding files larger than 1 megabyte.
|
||||
1. Downloads any missing large files needed to check out the default branch.
|
||||
|
||||
When changing branches, Git may need to download more missing files.
|
||||
|
||||
|
|
@ -68,9 +71,9 @@ When changing branches, Git may need to download more missing files.
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/2553) in GitLab 12.10.
|
||||
|
||||
For enormous repositories with millions of files, and long history, it may be
|
||||
helpful to exclude all files and use in combination with `sparse-checkout` to
|
||||
reduce the size of your working copy.
|
||||
For repositories with millions of files and a long history, you can exclude all files and use
|
||||
[`git sparse-checkout`](https://git-scm.com/docs/git-sparse-checkout) to reduce the size of
|
||||
your working copy.
|
||||
|
||||
```plaintext
|
||||
# Clone the repo excluding all files
|
||||
|
|
@ -108,21 +111,22 @@ For more details, see the Git documentation for
|
|||
|
||||
## Filter by file path
|
||||
|
||||
WARNING:
|
||||
Partial Clone using `sparse` filters is experimental, slow, and
|
||||
significantly increases Gitaly resource utilization when cloning and fetching.
|
||||
Deeper integration between partial clone and sparse checkout is possible through the
|
||||
`--filter=sparse:oid=<blob-ish>` filter spec. This mode of filtering uses a format similar to a
|
||||
`.gitignore` file to specify which files to include when cloning and fetching.
|
||||
|
||||
Deeper integration between Partial Clone and Sparse Checkout is being explored
|
||||
through the `--filter=sparse:oid=<blob-ish>` filter spec, but this is highly
|
||||
experimental. This mode of filtering uses a format similar to a `.gitignore`
|
||||
file to specify which files should be included when cloning and fetching.
|
||||
WARNING:
|
||||
Partial clone using `sparse` filters is still experimental. It might be slow and significantly increase
|
||||
[Gitaly](../../administration/gitaly/index.md) resource utilization when cloning and fetching.
|
||||
[Filter all blobs and use sparse-checkout](#filter-by-object-type) instead, because
|
||||
[`git-sparse-checkout`](https://git-scm.com/docs/git-sparse-checkout) simplifies
|
||||
this type of partial clone use and overcomes its limitations.
|
||||
|
||||
For more details, see the Git documentation for
|
||||
[`rev-list-options`](https://gitlab.com/gitlab-org/git/-/blob/9fadedd637b312089337d73c3ed8447e9f0aa775/Documentation/rev-list-options.txt#L735-780).
|
||||
[`rev-list-options`](https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt---filterltfilter-specgt).
|
||||
|
||||
1. **Create a filter spec.** For example, consider a monolithic repository with
|
||||
many applications, each in a different subdirectory in the root. Create a file
|
||||
`shiny-app/.filterspec` using the GitLab web interface:
|
||||
1. Create a filter spec. For example, consider a monolithic repository with many applications,
|
||||
each in a different subdirectory in the root. Create a file `shiny-app/.filterspec`:
|
||||
|
||||
```plaintext
|
||||
# Only the paths listed in the file will be downloaded when performing a
|
||||
|
|
@ -142,28 +146,14 @@ For more details, see the Git documentation for
|
|||
shared-component-b/
|
||||
```
|
||||
|
||||
1. **Create a new Git repository and fetch.** Support for `--filter=sparse:oid`
|
||||
using the clone command is incomplete, so we emulate the clone command
|
||||
by hand, using `git init` and `git fetch`. Follow
|
||||
[issue tracking support for `--filter=sparse:oid`](https://gitlab.com/gitlab-org/git/-/issues/4)
|
||||
for updates.
|
||||
1. Clone and filter by path. Support for `--filter=sparse:oid` using the
|
||||
clone command is not yet fully integrated with sparse checkout.
|
||||
|
||||
```shell
|
||||
# Create a new directory for the Git repository
|
||||
mkdir jumbo-repo && cd jumbo-repo
|
||||
|
||||
# Initialize a new Git repository
|
||||
git init
|
||||
|
||||
# Add the remote
|
||||
git remote add origin <url>
|
||||
|
||||
# Enable partial clone support for the remote
|
||||
git config --local extensions.partialClone origin
|
||||
|
||||
# Fetch the filtered set of objects using the filterspec stored on the
|
||||
# server. WARNING: this step is slow!
|
||||
git fetch --filter=sparse:oid=master:shiny-app/.gitfilterspec origin
|
||||
# Clone the filtered set of objects using the filterspec stored on the
|
||||
# server. WARNING: this step may be very slow!
|
||||
git clone --sparse --filter=sparse:oid=master:shiny-app/.gitfilterspec <url>
|
||||
|
||||
# Optional: observe there are missing objects that we have not fetched
|
||||
git rev-list --all --quiet --objects --missing=print | wc -l
|
||||
|
|
@ -175,21 +165,6 @@ For more details, see the Git documentation for
|
|||
entire repository. You many need to disable or reconfigure these
|
||||
integrations.
|
||||
|
||||
1. **Sparse checkout** must be enabled and configured to prevent objects from
|
||||
other paths being downloaded automatically when checking out branches. Follow
|
||||
[issue proposing automating sparse checkouts](https://gitlab.com/gitlab-org/git/-/issues/5) for updates.
|
||||
|
||||
```shell
|
||||
# Enable sparse checkout
|
||||
git config --local core.sparsecheckout true
|
||||
|
||||
# Configure sparse checkout
|
||||
git show master:snazzy-app/.gitfilterspec >> .git/info/sparse-checkout
|
||||
|
||||
# Checkout master
|
||||
git checkout master
|
||||
```
|
||||
|
||||
## Remove partial clone filtering
|
||||
|
||||
Git repositories with partial clone filtering can have the filtering removed. To
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 68 KiB |
|
|
@ -228,15 +228,7 @@ If you already have an open issue, you can link to it from the vulnerability.
|
|||
To link to an existing issue:
|
||||
|
||||
1. Open the vulnerability.
|
||||
1. In the **Related Issues** section, select the plus (**{plus}**) icon.
|
||||
1. In the text box that appears, type an issue number or paste an issue link.
|
||||
- Type `#` followed by a number to show an autocomplete menu.
|
||||
- You can enter multiple issues at once. Press the space bar after each issue number or link to converts them to tags.
|
||||
1. Select **Add**.
|
||||
|
||||
To remove an issue, to the right of the issue number, select **{close}**.
|
||||
|
||||

|
||||
1. [Add a linked issue](../project/issues/related_issues.md).
|
||||
|
||||
### Apply an automatic remediation for a vulnerability
|
||||
|
||||
|
|
|
|||
|
|
@ -179,17 +179,21 @@ For GitLab.com users, the KAS is available at `wss://kas.gitlab.com`.
|
|||
Replace the value of `agent-token` below with the token received from the previous step. Also, replace `kas-address` with the configured access of the Kubernetes Agent Server:
|
||||
|
||||
```shell
|
||||
docker run --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:latest generate --agent-token=your-agent-token --kas-address=wss://kas.gitlab.example.com --agent-version latest | kubectl apply -f -
|
||||
docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --agent-token=your-agent-token --kas-address=wss://kas.gitlab.example.com --agent-version stable | kubectl apply -f -
|
||||
```
|
||||
|
||||
Set `agent-version` to the latest released patch version matching your
|
||||
Set `--agent-version` to the latest released patch version matching your
|
||||
GitLab installation's major and minor versions. For example, if you have
|
||||
GitLab v13.9.0, set `--agent-version=v13.9.1`.
|
||||
|
||||
WARNING:
|
||||
Version `stable` can be used to refer to the latest stable release at the time when the command runs. It's fine for
|
||||
testing purposes but for production please make sure to specify a matching version explicitly.
|
||||
|
||||
To find out the various options the above Docker container supports, run:
|
||||
|
||||
```shell
|
||||
docker run --rm -it registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:latest generate --help
|
||||
docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --help
|
||||
```
|
||||
|
||||
#### Advanced installation
|
||||
|
|
@ -286,7 +290,8 @@ spec:
|
|||
serviceAccountName: gitlab-agent
|
||||
containers:
|
||||
- name: agent
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:latest"
|
||||
# Make sure to specify a matching version for production
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:stable"
|
||||
args:
|
||||
- --token-file=/config/token
|
||||
- --kas-address
|
||||
|
|
@ -554,7 +559,7 @@ Then in `resources.yml`:
|
|||
serviceAccountName: gitlab-agent
|
||||
containers:
|
||||
- name: agent
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:latest"
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:<version>"
|
||||
args:
|
||||
- --token-file=/config/token
|
||||
- --kas-address
|
||||
|
|
@ -584,7 +589,7 @@ Alternatively, you can mount the certificate file at a different location and in
|
|||
```yaml
|
||||
containers:
|
||||
- name: agent
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:latest"
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:<version>"
|
||||
args:
|
||||
- --ca-cert-file=/tmp/myCA.pem
|
||||
- --token-file=/config/token
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ To remove a member from a group:
|
|||
1. From the left menu, select **Members**.
|
||||
1. Next to the member you want to remove, select **Delete**.
|
||||
1. Optional. On the **Remove member** confirmation box, select the
|
||||
**Also unassign this user from related issues and merge requests** checkbox.
|
||||
**Also unassign this user from linked issues and merge requests** checkbox.
|
||||
1. Select **Remove member**.
|
||||
|
||||
## Filter and sort members in a group
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ With GitLab Enterprise Edition, you can also:
|
|||
- [Merge Request Approvals](project/merge_requests/merge_request_approvals.md).
|
||||
- [Multiple Assignees for Issues](project/issues/multiple_assignees_for_issues.md).
|
||||
- [Multiple Issue Boards](project/issue_board.md#multiple-issue-boards).
|
||||
- Create formal relationships between issues with [Related Issues](project/issues/related_issues.md).
|
||||
- Create formal relationships between issues with [linked issues](project/issues/related_issues.md).
|
||||
- Use [Burndown Charts](project/milestones/burndown_and_burnup_charts.md) to track progress during a sprint or while working on a new version of their software.
|
||||
- Leverage [Elasticsearch](../integration/elasticsearch.md) with [Advanced Search](search/advanced_search.md) for faster, more advanced code search across your entire GitLab instance.
|
||||
- [Authenticate users with Kerberos](../integration/kerberos.md).
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ The following table depicts the various user permission levels in a project.
|
|||
| Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create confidential issue | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create new issue | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| See related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| See linked issues | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| View [Releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
|
||||
| View requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
|
@ -82,7 +82,7 @@ The following table depicts the various user permission levels in a project.
|
|||
| [Set issue estimate and record time spent](project/time_tracking.md) | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Lock issue threads | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Manage issue tracker | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Manage related issues | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Manage linked issues | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Manage labels | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create code snippets | | ✓ | ✓ | ✓ | ✓ |
|
||||
| See a commit status | | ✓ | ✓ | ✓ | ✓ |
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 74 KiB |
|
|
@ -4,18 +4,23 @@ group: Ecosystem
|
|||
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
|
||||
---
|
||||
|
||||
# Mattermost Notifications Service **(FREE)**
|
||||
# Mattermost notifications service **(FREE)**
|
||||
|
||||
The Mattermost Notifications Service allows your GitLab project to send events (e.g., `issue created`) to your existing Mattermost team as notifications. This requires configurations in both Mattermost and GitLab.
|
||||
Use the Mattermost notifications service to send notifications for GitLab events
|
||||
(for example, `issue created`) to Mattermost. You must configure both [Mattermost](#configure-mattermost-to-receive-gitlab-notifications)
|
||||
and [GitLab](#configure-gitlab-to-send-notifications-to-mattermost).
|
||||
|
||||
You can also use Mattermost slash commands to control GitLab inside Mattermost. This is the separately configured [Mattermost slash commands](mattermost_slash_commands.md).
|
||||
You can also use [Mattermost slash commands](mattermost_slash_commands.md) to control
|
||||
GitLab inside Mattermost.
|
||||
|
||||
## On Mattermost
|
||||
## Configure Mattermost to receive GitLab notifications
|
||||
|
||||
To enable Mattermost integration you must create an incoming webhook integration:
|
||||
To use the Mattermost integration you must create an incoming webhook integration
|
||||
in Mattermost:
|
||||
|
||||
1. Sign in to your Mattermost instance.
|
||||
1. Visit incoming webhooks, that is something like: `https://mattermost.example.com/your_team_name/integrations/incoming_webhooks/add`.
|
||||
1. [Enable incoming webhooks](https://docs.mattermost.com/developer/webhooks-incoming.html#enabling-incoming-webhooks).
|
||||
1. [Add an incoming webhook](https://docs.mattermost.com/developer/webhooks-incoming.html#creating-integrations-using-incoming-webhooks).
|
||||
1. Choose a display name, description and channel, those can be overridden on GitLab.
|
||||
1. Save it and copy the **Webhook URL** because we need this later for GitLab.
|
||||
|
||||
|
|
@ -29,36 +34,24 @@ to enable it on:
|
|||
|
||||
Display name override is not enabled by default, you need to ask your administrator to enable it on that same section.
|
||||
|
||||
## On GitLab
|
||||
## Configure GitLab to send notifications to Mattermost
|
||||
|
||||
After you set up Mattermost, it's time to set up GitLab.
|
||||
After the Mattermost instance has an incoming webhook set up, you can set up GitLab
|
||||
to send the notifications.
|
||||
|
||||
Navigate to the [Integrations page](overview.md#accessing-integrations)
|
||||
and select the **Mattermost notifications** service to configure it.
|
||||
There, you see a checkbox with the following events that can be triggered:
|
||||
and select the **Mattermost notifications** service. Select the GitLab events
|
||||
you want to generate notifications for.
|
||||
|
||||
- Push
|
||||
- Issue
|
||||
- Confidential issue
|
||||
- Merge request
|
||||
- Note
|
||||
- Confidential note
|
||||
- Tag push
|
||||
- Pipeline
|
||||
- Wiki page
|
||||
- Deployment
|
||||
For each event you select, input the Mattermost channel you want to receive the
|
||||
notification. You do not need to add the hash sign (`#`).
|
||||
|
||||
Below each of these event checkboxes, you have an input field to enter
|
||||
which Mattermost channel you want to send that event message. Enter your preferred channel handle (the hash sign `#` is optional).
|
||||
|
||||
At the end, fill in your Mattermost details:
|
||||
Then fill in the integration configuration:
|
||||
|
||||
| Field | Description |
|
||||
| ----- | ----------- |
|
||||
| **Webhook** | The incoming webhook URL which you have to set up on Mattermost, similar to: `http://mattermost.example/hooks/5xo…` |
|
||||
| **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. |
|
||||
| **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. |
|
||||
| **Branches to be notified** | Select which types of branches to send notifications for. |
|
||||
| **Labels to be notified** | Optional labels that the issue or merge request must have in order to trigger a notification. Leave blank to get all notifications. |
|
||||
|
||||

|
||||
| **Webhook** | The incoming webhook URL on Mattermost, similar to: `http://mattermost.example/hooks/5xo…`. |
|
||||
| **Username** | (Optional) The username to show on messages sent to Mattermost. Fill this in to change the username of the bot. |
|
||||
| **Notify only broken pipelines** | If you enable the **Pipeline** event and you want to be notified about failed pipelines only. |
|
||||
| **Branches to be notified** | Select which branches to send notifications for. |
|
||||
| **Labels to be notified** | (Optional) Labels that the issue or merge request must have to trigger a notification. Leave blank to get notifications for all issues and merge requests. |
|
||||
|
|
|
|||
|
|
@ -4,18 +4,21 @@ group: Project Management
|
|||
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
|
||||
---
|
||||
|
||||
# Crosslinking Issues
|
||||
# Crosslinking issues
|
||||
|
||||
Please read through the [GitLab Issue Documentation](index.md) for an overview on GitLab Issues.
|
||||
There are several ways to mention an issue or make issues appear in each other's
|
||||
[Linked issues](related_issues.md) section.
|
||||
|
||||
## From Commit Messages
|
||||
For more information on GitLab Issues, read the [issues documentation](index.md).
|
||||
|
||||
## From commit messages
|
||||
|
||||
Every time you mention an issue in your commit message, you're creating
|
||||
a relationship between the two stages of the development workflow: the
|
||||
issue itself and the first commit related to that issue.
|
||||
|
||||
If the issue and the code you're committing are both in the same project,
|
||||
you simply add `#xxx` to the commit message, where `xxx` is the issue number.
|
||||
add `#xxx` to the commit message, where `xxx` is the issue number.
|
||||
If they are not in the same project, you can add the full URL to the issue
|
||||
(`https://gitlab.com/<username>/<projectname>/issues/<xxx>`).
|
||||
|
||||
|
|
@ -36,11 +39,10 @@ for tracking your process with [GitLab Value Stream Analytics](https://about.git
|
|||
It measures the time taken for planning the implementation of that issue,
|
||||
which is the time between creating an issue and making the first commit.
|
||||
|
||||
## From Related Issues
|
||||
## From linked issues
|
||||
|
||||
Mentioning related issues in merge requests and other issues is useful
|
||||
for your team members and collaborators to know that there are opened
|
||||
issues regarding the same topic.
|
||||
Mentioning linked issues in merge requests and other issues helps your team members and
|
||||
collaborators know that there are opened issues regarding the same topic.
|
||||
|
||||
You do that as explained above, when [mentioning an issue from a commit message](#from-commit-messages).
|
||||
|
||||
|
|
@ -50,13 +52,13 @@ display in both issues. The same is valid when mentioning issues in [merge reque
|
|||
|
||||

|
||||
|
||||
## From Merge Requests
|
||||
## From merge requests
|
||||
|
||||
Mentioning issues in merge request comments works exactly the same way as
|
||||
they do for [related issues](#from-related-issues).
|
||||
they do for [linked issues](#from-linked-issues).
|
||||
|
||||
When you mention an issue in a merge request description, it
|
||||
[links the issue and merge request together](#from-related-issues). Additionally,
|
||||
[links the issue and merge request together](#from-linked-issues). Additionally,
|
||||
you can also [set an issue to close automatically](managing_issues.md#closing-issues-automatically)
|
||||
as soon as the merge request is merged.
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ To learn how the GitLab Strategic Marketing department uses GitLab issues with [
|
|||
- [Import issues](csv_import.md)
|
||||
- [Export issues](csv_export.md)
|
||||
- [Upload designs to issues](design_management.md)
|
||||
- [Relate issues](related_issues.md)
|
||||
- [Linked issues](related_issues.md)
|
||||
- [Cross-link issues](crosslinking_issues.md)
|
||||
- [Bulk edit issues](../bulk_editing.md)
|
||||
- [Sort issue lists](sorting_issue_lists.md)
|
||||
- [Sort issue lists](sorting_issue_lists.md)
|
||||
- [Search for issues](../../search/index.md#filtering-issue-and-merge-request-lists)
|
||||
- [Epics](../../group/epics/index.md)
|
||||
- [Issue Boards](../issue_board.md)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ The numbers in the image correspond to the following features:
|
|||
- **15.** [Edit](#edit)
|
||||
- **16.** [Description](#description)
|
||||
- **17.** [Mentions](#mentions)
|
||||
- **18.** [Related Issues](#related-issues)
|
||||
- **18.** [Linked Issues](#linked-issues)
|
||||
- **19.** [Related Merge Requests](#related-merge-requests)
|
||||
- **20.** [Award emoji](#award-emoji)
|
||||
- **21.** [Show all activity](#show-all-activity)
|
||||
|
|
@ -205,10 +205,10 @@ in a different color, which allows you to quickly see which comments involve you
|
|||
Avoid mentioning `@all` in issues and merge requests, as it sends an email notification
|
||||
to all the members of that project's group. This might be interpreted as spam.
|
||||
|
||||
### Related Issues
|
||||
### Linked Issues
|
||||
|
||||
Issues that were mentioned as [related issues](related_issues.md) are listed here.
|
||||
You can also click the `+` to add more related issues.
|
||||
Issues that were mentioned as [linked issues](related_issues.md) are listed here.
|
||||
You can also click the `+` to add more linked issues.
|
||||
|
||||
### Related Merge Requests
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Linked issues **(FREE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1797) in GitLab 9.4.
|
||||
> - The simple "relates to" relationship [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212329) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.4.
|
||||
> The simple "relates to" relationship [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212329) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.4.
|
||||
|
||||
Linked issues are a bi-directional relationship between any two issues and appear in a block below
|
||||
the issue description. Issues can be across groups and projects.
|
||||
|
|
@ -52,6 +51,9 @@ them categorized so their relationships can be better understood visually.
|
|||
|
||||

|
||||
|
||||
You can also add a linked issue from a commit message or the description in another issue or MR.
|
||||
[Learn more about crosslinking issues](crosslinking_issues.md).
|
||||
|
||||
## Remove a linked issue
|
||||
|
||||
In the **Linked issues** section of an issue, click the remove button (**{close}**) on the
|
||||
|
|
|
|||
|
|
@ -83,4 +83,4 @@ the following table.
|
|||
|
||||
You may enable or disable project access token creation for all projects in a group in **Group > Settings > General > Permissions, LFS, 2FA > Allow project access token creation**.
|
||||
Even when creation is disabled, you can still use and revoke existing project access tokens.
|
||||
This setting is only available on root-level groups.
|
||||
This setting is available only on top-level groups.
|
||||
|
|
|
|||
|
|
@ -558,10 +558,6 @@ module API
|
|||
def increment_unique_values(event_name, values)
|
||||
return unless values.present?
|
||||
|
||||
feature_flag = "usage_data_#{event_name}"
|
||||
|
||||
return unless Feature.enabled?(feature_flag, default_enabled: true)
|
||||
|
||||
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event_name, values: values)
|
||||
rescue => error
|
||||
Gitlab::AppLogger.warn("Redis tracking event failed for event: #{event_name}, message: #{error.message}")
|
||||
|
|
|
|||
|
|
@ -87,6 +87,12 @@
|
|||
aggregation: daily
|
||||
feature_flag: track_epics_activity
|
||||
|
||||
- name: g_project_management_epic_issue_removed
|
||||
category: epics_usage
|
||||
redis_slot: project_management
|
||||
aggregation: daily
|
||||
feature_flag: track_epics_activity
|
||||
|
||||
- name: g_project_management_epic_closed
|
||||
category: epics_usage
|
||||
redis_slot: project_management
|
||||
|
|
|
|||
|
|
@ -1776,6 +1776,9 @@ msgstr ""
|
|||
msgid "Activity"
|
||||
msgstr ""
|
||||
|
||||
msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -5802,9 +5805,6 @@ msgstr ""
|
|||
msgid "Changing group URL can have unintended side effects."
|
||||
msgstr ""
|
||||
|
||||
msgid "Channel handle (e.g. town-square)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6438,12 +6438,24 @@ msgstr ""
|
|||
msgid "CloudLicense|Activate"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Activate subscription"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Activation code"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|I agree that my use of the GitLab Software is subject to the Subscription Agreement located at the %{linkStart}Terms of Service%{linkEnd}, unless otherwise agreed to in writing with GitLab."
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Last Sync"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Learn how to %{linkStart}activate your subscription%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Licensed to"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6453,9 +6465,6 @@ msgstr ""
|
|||
msgid "CloudLicense|Paste your activation code"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Paste your activation code below"
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Plan"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -6474,6 +6483,9 @@ msgstr ""
|
|||
msgid "CloudLicense|This instance is currently using the %{planName} plan."
|
||||
msgstr ""
|
||||
|
||||
msgid "CloudLicense|Your subscription"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cluster"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18999,6 +19011,9 @@ msgstr ""
|
|||
msgid "Mattermost URL:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mattermost notifications"
|
||||
msgstr ""
|
||||
|
||||
msgid "MattermostService|Add to Mattermost"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -21675,6 +21690,12 @@ msgstr ""
|
|||
msgid "OnCallSchedules|Try adding a rotation"
|
||||
msgstr ""
|
||||
|
||||
msgid "OnCallSchedules|View next timeframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "OnCallSchedules|View previous timeframe"
|
||||
msgstr ""
|
||||
|
||||
msgid "OnCallSchedules|Your schedule has been successfully created and all alerts from this project will now be routed to this schedule. Currently, only one schedule can be created per project. More coming soon! To add individual users to this schedule, use the add a rotation button."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -24164,42 +24185,6 @@ msgstr ""
|
|||
msgid "ProjectService|Enter new password"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a commit is created or updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a confidential issue is created, updated, or closed."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a deployment starts or finishes."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a merge request is created, updated, or merged."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a new tag is pushed to the repository."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a new, unique alert is recorded."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a pipeline status changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when a wiki page is created or updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when an issue is created, updated, or closed."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when someone adds a comment on a confidential issue."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when someone adds a comment."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Event triggered when someone pushes to the repository."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Issue URL"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -24227,6 +24212,42 @@ msgstr ""
|
|||
msgid "ProjectService|To configure this integration, you should:"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event for new comments on confidential issues."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event for new comments."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event for new tags pushed to the repository."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event for pushes to the repository."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a commit is created or updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a confidential issue is created, updated, or closed."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a deployment starts or finishes."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a merge request is created, updated, or merged."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a new, unique alert is recorded."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a pipeline status changes."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when a wiki page is created or updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectService|Trigger event when an issue is created, updated, or closed."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -27818,6 +27839,12 @@ msgstr ""
|
|||
msgid "Send message"
|
||||
msgstr ""
|
||||
|
||||
msgid "Send notifications about project events to Mattermost channels."
|
||||
msgstr ""
|
||||
|
||||
msgid "Send notifications about project events to Mattermost channels. %{docs_link}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Send report"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36852,6 +36879,9 @@ msgstr ""
|
|||
msgid "my-awesome-group"
|
||||
msgstr ""
|
||||
|
||||
msgid "my-channel"
|
||||
msgstr ""
|
||||
|
||||
msgid "n/a"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@ function install_api_client_dependencies_with_apk() {
|
|||
apk add --update openssl curl jq
|
||||
}
|
||||
|
||||
function install_api_client_dependencies_with_apt() {
|
||||
apt update && apt install jq -y
|
||||
}
|
||||
|
||||
function install_gitlab_gem() {
|
||||
gem install httparty --no-document --version 0.18.1
|
||||
gem install gitlab --no-document --version 4.17.0
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ RSpec.describe 'When a user filters Sentry errors by status', :js, :use_clean_ra
|
|||
|
||||
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
|
||||
let_it_be(:filtered_errors_by_status_response) { Gitlab::Json.parse(issues_response_body).filter { |error| error['status'] == 'ignored' }.to_json }
|
||||
|
||||
let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" }
|
||||
let(:issues_api_url_filter) { "#{sentry_api_urls.issues_url}?limit=20&query=is:ignored" }
|
||||
let(:auth_token) {{ 'Authorization' => 'Bearer access_token_123' }}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ RSpec.describe 'When a user searches for Sentry errors', :js, :use_clean_rails_m
|
|||
|
||||
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
|
||||
let_it_be(:error_search_response_body) { fixture_file('sentry/error_list_search_response.json') }
|
||||
|
||||
let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" }
|
||||
let(:issues_api_url_search) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved%20NotFound" }
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ RSpec.describe 'View error index page', :js, :use_clean_rails_memory_store_cachi
|
|||
|
||||
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
|
||||
let_it_be(:issues_response) { Gitlab::Json.parse(issues_response_body) }
|
||||
|
||||
let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" }
|
||||
|
||||
before do
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
|
|||
end
|
||||
|
||||
before do
|
||||
stub_feature_flags(new_pipelines_table: false)
|
||||
stub_application_setting(auto_devops_enabled: false)
|
||||
stub_ci_pipeline_yaml_file(YAML.dump(config))
|
||||
project.add_maintainer(user)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ RSpec.describe 'Pipelines', :js do
|
|||
sign_in(user)
|
||||
stub_feature_flags(graphql_pipeline_details: false)
|
||||
stub_feature_flags(graphql_pipeline_details_users: false)
|
||||
stub_feature_flags(new_pipelines_table: false)
|
||||
|
||||
project.add_developer(user)
|
||||
project.update!(auto_devops_attributes: { enabled: false })
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ describe('Tracking', () => {
|
|||
expect(eventSpy).toHaveBeenCalledWith('_category_', 'nested_event', {});
|
||||
});
|
||||
|
||||
it('brings in experiment data if linked to an experiment', () => {
|
||||
it('includes experiment data if linked to an experiment', () => {
|
||||
const mockExperimentData = {
|
||||
variant: 'candidate',
|
||||
experiment: 'repo_integrations_link',
|
||||
|
|
@ -326,6 +326,30 @@ describe('Tracking', () => {
|
|||
mixin.computed.tracking = { foo: 'baz', baz: 'bar' };
|
||||
expect(mixin.computed.trackingOptions()).toEqual({ foo: 'baz', baz: 'bar' });
|
||||
});
|
||||
|
||||
it('includes experiment data if linked to an experiment', () => {
|
||||
const mockExperimentData = {
|
||||
variant: 'candidate',
|
||||
experiment: 'darkMode',
|
||||
};
|
||||
getExperimentData.mockReturnValue(mockExperimentData);
|
||||
|
||||
const mixin = Tracking.mixin({ foo: 'bar', experiment: 'darkMode' });
|
||||
expect(mixin.computed.trackingOptions()).toEqual({
|
||||
foo: 'bar',
|
||||
context: {
|
||||
schema: TRACKING_CONTEXT_SCHEMA,
|
||||
data: mockExperimentData,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('does not include experiment data if experiment data does not exist', () => {
|
||||
const mixin = Tracking.mixin({ foo: 'bar', experiment: 'lightMode' });
|
||||
expect(mixin.computed.trackingOptions()).toEqual({
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('trackingCategory', () => {
|
||||
|
|
|
|||
|
|
@ -179,46 +179,23 @@ RSpec.describe API::Helpers do
|
|||
let(:value) { '9f302fea-f828-4ca9-aef4-e10bd723c0b3' }
|
||||
let(:event_name) { 'g_compliance_dashboard' }
|
||||
let(:unknown_event) { 'unknown' }
|
||||
let(:feature) { "usage_data_#{event_name}" }
|
||||
|
||||
before do
|
||||
skip_feature_flags_yaml_validation
|
||||
it 'tracks redis hll event' do
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(event_name, values: value)
|
||||
|
||||
subject.increment_unique_values(event_name, value)
|
||||
end
|
||||
|
||||
context 'with feature enabled' do
|
||||
before do
|
||||
stub_feature_flags(feature => true)
|
||||
end
|
||||
it 'logs an exception for unknown event' do
|
||||
expect(Gitlab::AppLogger).to receive(:warn).with("Redis tracking event failed for event: #{unknown_event}, message: Unknown event #{unknown_event}")
|
||||
|
||||
it 'tracks redis hll event' do
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(event_name, values: value)
|
||||
|
||||
subject.increment_unique_values(event_name, value)
|
||||
end
|
||||
|
||||
it 'logs an exception for unknown event' do
|
||||
expect(Gitlab::AppLogger).to receive(:warn).with("Redis tracking event failed for event: #{unknown_event}, message: Unknown event #{unknown_event}")
|
||||
|
||||
subject.increment_unique_values(unknown_event, value)
|
||||
end
|
||||
|
||||
it 'does not track event for nil values' do
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
|
||||
|
||||
subject.increment_unique_values(unknown_event, nil)
|
||||
end
|
||||
subject.increment_unique_values(unknown_event, value)
|
||||
end
|
||||
|
||||
context 'with feature disabled' do
|
||||
before do
|
||||
stub_feature_flags(feature => false)
|
||||
end
|
||||
it 'does not track event for nil values' do
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
|
||||
|
||||
it 'does not track event' do
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
|
||||
|
||||
subject.increment_unique_values(event_name, value)
|
||||
end
|
||||
subject.increment_unique_values(unknown_event, nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ require 'spec_helper'
|
|||
RSpec.describe Ci::ArtifactBlob do
|
||||
let_it_be(:project) { create(:project, :public) }
|
||||
let_it_be(:build) { create(:ci_build, :artifacts, project: project) }
|
||||
|
||||
let(:entry) { build.artifacts_metadata_entry('other_artifacts_0.1.2/another-subdirectory/banana_sample.gif') }
|
||||
|
||||
subject { described_class.new(entry) }
|
||||
|
|
|
|||
|
|
@ -3730,6 +3730,7 @@ RSpec.describe Ci::Build do
|
|||
|
||||
describe '.matches_tag_ids' do
|
||||
let_it_be(:build, reload: true) { create(:ci_build, project: project, user: user) }
|
||||
|
||||
let(:tag_ids) { ::ActsAsTaggableOn::Tag.named_any(tag_list).ids }
|
||||
|
||||
subject { described_class.where(id: build).matches_tag_ids(tag_ids) }
|
||||
|
|
@ -4181,6 +4182,7 @@ RSpec.describe Ci::Build do
|
|||
|
||||
describe '#artifacts_metadata_entry' do
|
||||
let_it_be(:build) { create(:ci_build, project: project) }
|
||||
|
||||
let(:path) { 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif' }
|
||||
|
||||
around do |example|
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
|
|||
include ExclusiveLeaseHelpers
|
||||
|
||||
let_it_be(:build) { create(:ci_build, :running) }
|
||||
|
||||
let(:chunk_index) { 0 }
|
||||
let(:data_store) { :redis }
|
||||
let(:raw_data) { nil }
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ RSpec.describe Ci::DailyBuildGroupReportResult do
|
|||
describe 'scopes' do
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:project) { create(:project, group: group) }
|
||||
|
||||
let(:recent_build_group_report_result) { create(:ci_daily_build_group_report_result, project: project, group: group) }
|
||||
let(:old_build_group_report_result) do
|
||||
create(:ci_daily_build_group_report_result, date: 1.week.ago, project: project)
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
subject { pipeline.legacy_detached_merge_request_pipeline? }
|
||||
|
||||
let_it_be(:merge_request) { create(:merge_request) }
|
||||
|
||||
let(:ref) { 'feature' }
|
||||
let(:target_sha) { nil }
|
||||
|
||||
|
|
@ -832,6 +833,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
let_it_be(:assignees) { create_list(:user, 2) }
|
||||
let_it_be(:milestone) { create(:milestone, project: project) }
|
||||
let_it_be(:labels) { create_list(:label, 2) }
|
||||
|
||||
let(:merge_request) do
|
||||
create(:merge_request, :simple,
|
||||
source_project: project,
|
||||
|
|
@ -1276,6 +1278,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
describe 'state machine' do
|
||||
let_it_be_with_reload(:pipeline) { create(:ci_empty_pipeline, :created) }
|
||||
|
||||
let(:current) { Time.current.change(usec: 0) }
|
||||
let(:build) { create_build('build1', queued_at: 0) }
|
||||
let(:build_b) { create_build('build2', queued_at: 0) }
|
||||
|
|
@ -2327,6 +2330,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
subject { pipeline.reload.status }
|
||||
|
||||
let_it_be(:pipeline) { create(:ci_empty_pipeline, :created) }
|
||||
|
||||
let(:build) { create(:ci_build, :created, pipeline: pipeline, name: 'test') }
|
||||
|
||||
context 'on waiting for resource' do
|
||||
|
|
@ -2721,6 +2725,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
describe '#execute_hooks' do
|
||||
let_it_be(:pipeline) { create(:ci_empty_pipeline, :created) }
|
||||
|
||||
let!(:build_a) { create_build('a', 0) }
|
||||
let!(:build_b) { create_build('b', 0) }
|
||||
|
||||
|
|
@ -3386,6 +3391,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
describe '#build_with_artifacts_in_self_and_descendants' do
|
||||
let_it_be(:pipeline) { create(:ci_pipeline) }
|
||||
|
||||
let!(:build) { create(:ci_build, name: 'test', pipeline: pipeline) }
|
||||
let(:child_pipeline) { create(:ci_pipeline, child_of: pipeline) }
|
||||
let!(:child_build) { create(:ci_build, :artifacts, name: 'test', pipeline: child_pipeline) }
|
||||
|
|
@ -3896,6 +3902,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
describe '#find_stage_by_name' do
|
||||
let_it_be(:pipeline) { create(:ci_pipeline) }
|
||||
|
||||
let(:stage_name) { 'test' }
|
||||
|
||||
let(:stage) do
|
||||
|
|
@ -4181,6 +4188,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
subject { pipeline.base_and_ancestors(same_project: same_project) }
|
||||
|
||||
let_it_be(:pipeline) { create(:ci_pipeline, :created) }
|
||||
|
||||
let(:same_project) { false }
|
||||
|
||||
context 'when pipeline is not child nor parent' do
|
||||
|
|
@ -4217,6 +4225,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
context 'when pipeline is a child of a child pipeline' do
|
||||
let_it_be(:pipeline) { create(:ci_pipeline, :created) }
|
||||
|
||||
let(:ancestor) { create(:ci_pipeline) }
|
||||
let(:parent) { create(:ci_pipeline) }
|
||||
|
||||
|
|
@ -4232,6 +4241,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
context 'when pipeline is a triggered pipeline' do
|
||||
let_it_be(:pipeline) { create(:ci_pipeline, :created) }
|
||||
|
||||
let(:upstream) { create(:ci_pipeline, project: create(:project)) }
|
||||
|
||||
before do
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ RSpec.describe Ci::Runner do
|
|||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
let_it_be(:pipeline) { create(:ci_pipeline) }
|
||||
|
||||
let(:build) { create(:ci_build, pipeline: pipeline) }
|
||||
let(:runner_project) { build.project }
|
||||
let(:runner) { create(:ci_runner, :project, projects: [runner_project], tag_list: tag_list, run_untagged: run_untagged) }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Ci::Stage, :models do
|
||||
let_it_be(:pipeline) { create(:ci_empty_pipeline) }
|
||||
|
||||
let(:stage) { create(:ci_stage_entity, pipeline: pipeline, project: pipeline.project) }
|
||||
|
||||
it_behaves_like 'having unique enum values'
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ RSpec.describe ServiceEventEntity do
|
|||
let(:event) { 'push' }
|
||||
|
||||
it 'exposes correct attributes' do
|
||||
expect(subject[:description]).to eq('Event triggered when someone pushes to the repository.')
|
||||
expect(subject[:description]).to eq('Trigger event for pushes to the repository.')
|
||||
expect(subject[:name]).to eq('push_events')
|
||||
expect(subject[:title]).to eq('push')
|
||||
expect(subject[:value]).to be(true)
|
||||
|
|
@ -29,7 +29,7 @@ RSpec.describe ServiceEventEntity do
|
|||
let(:event) { 'note' }
|
||||
|
||||
it 'exposes correct attributes' do
|
||||
expect(subject[:description]).to eq('Event triggered when someone adds a comment.')
|
||||
expect(subject[:description]).to eq('Trigger event for new comments.')
|
||||
expect(subject[:name]).to eq('note_events')
|
||||
expect(subject[:title]).to eq('note')
|
||||
expect(subject[:value]).to eq(false)
|
||||
|
|
|
|||
|
|
@ -673,7 +673,17 @@ RSpec.describe Projects::CreateService, '#execute' do
|
|||
expect(rugged.config['gitlab.fullpath']).to eq project.full_path
|
||||
end
|
||||
|
||||
it 'triggers PostCreationWorker' do
|
||||
expect(Projects::PostCreationWorker).to receive(:perform_async).with(a_kind_of(Integer))
|
||||
|
||||
create_project(user, opts)
|
||||
end
|
||||
|
||||
context 'when project has access to shared service' do
|
||||
before do
|
||||
stub_feature_flags(projects_post_creation_worker: false)
|
||||
end
|
||||
|
||||
context 'Prometheus application is shared via group cluster' do
|
||||
let(:cluster) { create(:cluster, :group, groups: [group]) }
|
||||
let(:group) do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Projects::PostCreationWorker do
|
||||
let_it_be(:user) { create :user }
|
||||
|
||||
let(:worker) { described_class.new }
|
||||
let(:project) { create(:project) }
|
||||
|
||||
subject { described_class.new.perform(project.id) }
|
||||
|
||||
it_behaves_like 'an idempotent worker' do
|
||||
let(:job_args) { [project.id] }
|
||||
|
||||
describe 'Prometheus service' do
|
||||
context 'project is nil' do
|
||||
let(:job_args) { [nil] }
|
||||
|
||||
it 'does not create prometheus service' do
|
||||
expect { subject }.not_to change { Service.count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project has access to shared service' do
|
||||
context 'Prometheus application is shared via group cluster' do
|
||||
let(:project) { create(:project, group: group) }
|
||||
let(:cluster) { create(:cluster, :group, groups: [group]) }
|
||||
let(:group) do
|
||||
create(:group).tap do |group|
|
||||
group.add_owner(user)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
create(:clusters_applications_prometheus, :installed, cluster: cluster)
|
||||
end
|
||||
|
||||
it 'creates PrometheusService record', :aggregate_failures do
|
||||
subject
|
||||
|
||||
service = project.prometheus_service
|
||||
expect(service.active).to be true
|
||||
expect(service.manual_configuration?).to be false
|
||||
expect(service.persisted?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'Prometheus application is shared via instance cluster' do
|
||||
let(:cluster) { create(:cluster, :instance) }
|
||||
|
||||
before do
|
||||
create(:clusters_applications_prometheus, :installed, cluster: cluster)
|
||||
end
|
||||
|
||||
it 'creates PrometheusService record', :aggregate_failures do
|
||||
subject
|
||||
|
||||
service = project.prometheus_service
|
||||
expect(service.active).to be true
|
||||
expect(service.manual_configuration?).to be false
|
||||
expect(service.persisted?).to be true
|
||||
end
|
||||
|
||||
it 'cleans invalid record and logs warning', :aggregate_failures do
|
||||
invalid_service_record = build(:prometheus_service, properties: { api_url: nil, manual_configuration: true }.to_json)
|
||||
|
||||
allow_next_found_instance_of(Project) do |instance|
|
||||
allow(instance).to receive(:build_prometheus_service).and_return(invalid_service_record)
|
||||
end
|
||||
|
||||
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) })).twice
|
||||
subject
|
||||
|
||||
expect(project.prometheus_service).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'shared Prometheus application is not available' do
|
||||
it 'does not persist PrometheusService record', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(project.prometheus_service).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue