Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
96dfc10639
commit
ebfc70c3df
|
@ -302,7 +302,7 @@
|
|||
|
||||
.zoekt-services:
|
||||
services:
|
||||
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:zoekt-ci-image-1.7
|
||||
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:zoekt-ci-image-1.8
|
||||
alias: zoekt-ci-image
|
||||
|
||||
.use-pg13:
|
||||
|
|
|
@ -2213,7 +2213,6 @@ Layout/LineLength:
|
|||
- 'ee/spec/views/projects/security/discover/show.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/_mirror_status.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/_namespace_user_cap_reached_alert.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_eoa_bronze_plan_banner.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_trial_status.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/credentials_inventory/personal_access_tokens/_personal_access_token.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/promotions/_promotion_link_project.html.haml_spec.rb'
|
||||
|
|
|
@ -225,7 +225,6 @@ RSpec/FactoryBot/AvoidCreate:
|
|||
- 'ee/spec/views/shared/_mirror_status.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/_mirror_update_button.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/_namespace_user_cap_reached_alert.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_eoa_bronze_plan_banner.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_trial_status.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/credentials_inventory/_expiry_date.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/credentials_inventory/gpg_keys/_gpg_key.html.haml_spec.rb'
|
||||
|
|
|
@ -1452,7 +1452,6 @@ RSpec/FeatureCategory:
|
|||
- 'ee/spec/views/shared/billings/_billing_plan.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_billing_plan_actions.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_billing_plans.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_eoa_bronze_plan_banner.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/billings/_trial_status.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/credentials_inventory/_expiry_date.html.haml_spec.rb'
|
||||
- 'ee/spec/views/shared/credentials_inventory/gpg_keys/_gpg_key.html.haml_spec.rb'
|
||||
|
|
|
@ -35,6 +35,7 @@ query getPipelineHeaderData($fullPath: ID!, $iid: ID!) {
|
|||
}
|
||||
commit {
|
||||
id
|
||||
sha
|
||||
shortId
|
||||
title
|
||||
webPath
|
||||
|
|
|
@ -231,6 +231,9 @@ export default {
|
|||
shortId() {
|
||||
return this.pipeline?.commit?.shortId || '';
|
||||
},
|
||||
commitSha() {
|
||||
return this.pipeline?.commit?.sha || '';
|
||||
},
|
||||
commitPath() {
|
||||
return this.pipeline?.commit?.webPath || '';
|
||||
},
|
||||
|
@ -462,9 +465,10 @@ export default {
|
|||
</div>
|
||||
<div class="gl-display-inline-block gl-mb-3">
|
||||
<clipboard-button
|
||||
:text="shortId"
|
||||
:text="commitSha"
|
||||
category="tertiary"
|
||||
:title="$options.i18n.clipboardTooltip"
|
||||
data-testid="commit-copy-sha"
|
||||
size="small"
|
||||
/>
|
||||
<span v-if="inProgress" data-testid="pipeline-created-time-ago">
|
||||
|
|
|
@ -18,7 +18,11 @@ export default {
|
|||
MarkdownEditor,
|
||||
},
|
||||
mixins: [InternalEvents.mixin()],
|
||||
inject: ['createMutation', 'updateMutation'],
|
||||
inject: {
|
||||
namespaceId: { default: undefined },
|
||||
createMutation: { required: true },
|
||||
updateMutation: { required: true },
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
|
@ -93,6 +97,7 @@ export default {
|
|||
.mutate({
|
||||
mutation: this.id ? this.updateMutation : this.createMutation,
|
||||
variables: {
|
||||
namespaceId: this.namespaceId,
|
||||
id: this.id,
|
||||
name: this.updateCommentTemplate.name,
|
||||
content: this.updateCommentTemplate.content,
|
||||
|
|
|
@ -6,6 +6,8 @@ import routes from './routes';
|
|||
import App from './components/app.vue';
|
||||
|
||||
export const initCommentTemplates = ({
|
||||
savedReplyType,
|
||||
path,
|
||||
fetchAllQuery,
|
||||
fetchSingleQuery,
|
||||
createMutation,
|
||||
|
@ -31,6 +33,9 @@ export const initCommentTemplates = ({
|
|||
router,
|
||||
apolloProvider,
|
||||
provide: {
|
||||
path,
|
||||
namespaceId: el.dataset.namespaceId,
|
||||
savedReplyType,
|
||||
fetchAllQuery,
|
||||
fetchSingleQuery,
|
||||
createMutation,
|
||||
|
|
|
@ -5,7 +5,6 @@ import { fetchPolicies } from '~/lib/graphql';
|
|||
import { createAlert } from '~/alert';
|
||||
import { __ } from '~/locale';
|
||||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import { TYPE_USERS_SAVED_REPLY } from '~/graphql_shared/constants';
|
||||
import CreateForm from '../components/form.vue';
|
||||
|
||||
export default {
|
||||
|
@ -21,7 +20,8 @@ export default {
|
|||
},
|
||||
variables() {
|
||||
return {
|
||||
id: convertToGraphQLId(TYPE_USERS_SAVED_REPLY, this.$route.params.id),
|
||||
id: convertToGraphQLId(this.savedReplyType, this.$route.params.id),
|
||||
path: this.path,
|
||||
};
|
||||
},
|
||||
update: (r) => r.object.savedReply,
|
||||
|
@ -40,7 +40,7 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
inject: ['fetchSingleQuery'],
|
||||
inject: ['path', 'fetchSingleQuery', 'savedReplyType'],
|
||||
data() {
|
||||
return {
|
||||
savedReply: null,
|
||||
|
|
|
@ -15,6 +15,7 @@ export default {
|
|||
update: (r) => r.object?.savedReplies?.nodes,
|
||||
variables() {
|
||||
return {
|
||||
path: this.path,
|
||||
...this.pagination,
|
||||
};
|
||||
},
|
||||
|
@ -37,7 +38,10 @@ export default {
|
|||
CreateForm,
|
||||
List,
|
||||
},
|
||||
inject: ['fetchAllQuery'],
|
||||
inject: {
|
||||
path: { default: '' },
|
||||
fetchAllQuery: { required: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
savedReplies: [],
|
||||
|
@ -72,7 +76,7 @@ export default {
|
|||
<template #header>
|
||||
<div class="gl-new-card-title-wrapper" data-testid="title">
|
||||
<h3 class="gl-new-card-title">
|
||||
{{ __('My comment templates') }}
|
||||
{{ __('Comment templates') }}
|
||||
</h3>
|
||||
<div class="gl-new-card-count">
|
||||
<gl-icon name="comment-lines" class="gl-mr-2" />
|
||||
|
|
|
@ -27,12 +27,7 @@ export class GitLabDropdownFilter {
|
|||
});
|
||||
}, 500);
|
||||
|
||||
$clearButton.on('click', (e) => {
|
||||
// Clear click
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return this.input.val('').trigger('input').focus();
|
||||
});
|
||||
$clearButton.on('click', this.clear);
|
||||
// Key events
|
||||
this.input
|
||||
.on('keydown', (e) => {
|
||||
|
@ -130,4 +125,14 @@ export class GitLabDropdownFilter {
|
|||
.find('.dropdown-menu-empty-item')
|
||||
.toggleClass('hidden', elements.is(':visible'));
|
||||
}
|
||||
|
||||
clear(e) {
|
||||
if (this.input.val() === '') return;
|
||||
if (e) {
|
||||
// Clear click
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
this.input.val('').trigger('input').focus();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@ import { runModules } from '~/run_modules';
|
|||
|
||||
const modules = import.meta.glob('../pages/**/index.js');
|
||||
|
||||
runModules(modules, '../pages/');
|
||||
runModules(modules, 'CE');
|
||||
|
|
|
@ -2,4 +2,4 @@ import { runModules } from '~/run_modules';
|
|||
|
||||
const modules = import.meta.glob('../../../../ee/app/assets/javascripts/pages/**/index.js');
|
||||
|
||||
runModules(modules, '../../../../ee/app/assets/javascripts/pages/');
|
||||
runModules(modules, 'EE');
|
||||
|
|
|
@ -2,4 +2,4 @@ import { runModules } from '~/run_modules';
|
|||
|
||||
const modules = import.meta.glob('../../../../jh/app/assets/javascripts/pages/**/index.js');
|
||||
|
||||
runModules(modules, '../../../../jh/app/assets/javascripts/pages/');
|
||||
runModules(modules, 'JH');
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { initCommentTemplates } from '~/comment_templates';
|
||||
import { TYPE_USERS_SAVED_REPLY } from '~/graphql_shared/constants';
|
||||
import fetchAllQuery from './queries/saved_replies.query.graphql';
|
||||
import fetchSingleQuery from './queries/get_saved_reply.query.graphql';
|
||||
import createMutation from './queries/create_saved_reply.mutation.graphql';
|
||||
|
@ -6,6 +7,7 @@ import deleteMutation from './queries/delete_saved_reply.mutation.graphql';
|
|||
import updateMutation from './queries/update_saved_reply.mutation.graphql';
|
||||
|
||||
initCommentTemplates({
|
||||
savedReplyType: TYPE_USERS_SAVED_REPLY,
|
||||
fetchAllQuery,
|
||||
fetchSingleQuery,
|
||||
createMutation,
|
||||
|
|
|
@ -7,7 +7,6 @@ const PERSISTENT_USER_CALLOUTS = [
|
|||
'.js-token-expiry-callout',
|
||||
'.js-registration-enabled-callout',
|
||||
'.js-new-user-signups-cap-reached',
|
||||
'.js-eoa-bronze-plan-banner',
|
||||
'.js-security-newsletter-callout',
|
||||
'.js-approaching-seat-count-threshold',
|
||||
'.js-storage-pre-enforcement-alert',
|
||||
|
|
|
@ -1,9 +1,48 @@
|
|||
export const runModules = (modules, prefix) => {
|
||||
document
|
||||
.querySelector('meta[name="controller-path"]')
|
||||
.content.split('/')
|
||||
.forEach((part, index, arr) => {
|
||||
const path = `${prefix}${[...arr.slice(0, index), part].join('/')}/index.js`;
|
||||
modules[path]?.();
|
||||
});
|
||||
const paths = [];
|
||||
const allModules = {};
|
||||
|
||||
const prefixes = {
|
||||
CE: '../pages/',
|
||||
EE: '../../../../ee/app/assets/javascripts/pages/',
|
||||
JH: '../../../../jh/app/assets/javascripts/pages/',
|
||||
};
|
||||
|
||||
const editionExcludes = {
|
||||
JH: [],
|
||||
EE: [prefixes.JH],
|
||||
CE: [prefixes.EE, prefixes.JH],
|
||||
};
|
||||
|
||||
const runWithExcludes = (edition) => {
|
||||
const prefix = prefixes[edition];
|
||||
const excludes = editionExcludes[edition];
|
||||
paths.forEach((path) => {
|
||||
const hasDuplicateEntrypoint = excludes.some(
|
||||
(editionPrefix) => `${editionPrefix}${path}` in allModules,
|
||||
);
|
||||
if (!hasDuplicateEntrypoint) allModules[`${prefix}${path}`]?.();
|
||||
});
|
||||
};
|
||||
|
||||
let pathsPopulated = false;
|
||||
|
||||
const populatePaths = () => {
|
||||
if (pathsPopulated) return;
|
||||
paths.push(
|
||||
...document
|
||||
.querySelector('meta[name="controller-path"]')
|
||||
.content.split('/')
|
||||
.map((part, index, arr) => `${[...arr.slice(0, index), part].join('/')}/index.js`),
|
||||
);
|
||||
pathsPopulated = true;
|
||||
};
|
||||
|
||||
export const runModules = (modules, edition) => {
|
||||
populatePaths();
|
||||
Object.assign(allModules, modules);
|
||||
// wait before all modules have been collected to exclude duplicates between CE and EE\JH
|
||||
// <script> runs as a macrotask, can't schedule with promises here
|
||||
requestAnimationFrame(() => {
|
||||
runWithExcludes(edition);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -434,6 +434,8 @@ function UsersSelect(currentUser, els, options = {}) {
|
|||
this.processData(inputValue, users, callback);
|
||||
}
|
||||
|
||||
deprecatedJQueryDropdown.filter.clear();
|
||||
|
||||
if (this.multiSelect) {
|
||||
return getMultiSelectDropdownTitle(selected, $(el).hasClass('is-active'));
|
||||
}
|
||||
|
@ -446,6 +448,7 @@ function UsersSelect(currentUser, els, options = {}) {
|
|||
return selected.name;
|
||||
}
|
||||
$dropdown.find('.dropdown-toggle-text').addClass('is-default');
|
||||
|
||||
return defaultLabel;
|
||||
},
|
||||
defaultLabel,
|
||||
|
|
|
@ -8,6 +8,13 @@ module ProtectedBranchAccess
|
|||
belongs_to :protected_branch
|
||||
|
||||
delegate :project, to: :protected_branch
|
||||
|
||||
# We cannot delegate to :protected_branch here (even with allow_nil: true)
|
||||
# like above because it results in
|
||||
# 'undefined method `project_group_links' for nil:NilClass' errors.
|
||||
def protected_branch_group
|
||||
protected_branch.group
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ module ProtectedRef
|
|||
|
||||
def protected_ref_accessible_to?(ref, user, project:, action:, protected_refs: nil)
|
||||
access_levels_for_ref(ref, action: action, protected_refs: protected_refs).any? do |access_level|
|
||||
access_level.check_access(user)
|
||||
access_level.check_access(user, project)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -67,15 +67,16 @@ module ProtectedRefAccess
|
|||
type == :role
|
||||
end
|
||||
|
||||
def check_access(current_user)
|
||||
def check_access(current_user, current_project = project)
|
||||
return false if current_user.nil? || no_access?
|
||||
return current_user.admin? if admin_access?
|
||||
|
||||
return false if Feature.enabled?(:check_membership_in_protected_ref_access) && !project.member?(current_user)
|
||||
return false if Feature.enabled?(:check_membership_in_protected_ref_access) &&
|
||||
(current_project && !current_project.member?(current_user))
|
||||
|
||||
yield if block_given?
|
||||
|
||||
user_can_access?(current_user)
|
||||
user_can_access?(current_user, current_project)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -88,9 +89,18 @@ module ProtectedRefAccess
|
|||
role? && access_level == Gitlab::Access::NO_ACCESS
|
||||
end
|
||||
|
||||
def user_can_access?(current_user)
|
||||
current_user.can?(:push_code, project) &&
|
||||
project.team.max_member_access(current_user.id) >= access_level
|
||||
def user_can_access?(current_user, current_project)
|
||||
# NOTE: A user could be a group member which would be inherited in
|
||||
# projects, however, the same user can have direct membership to a project
|
||||
# with a higher role. For this reason we need to check group-level rules
|
||||
# against the current project when merging an MR or pushing changes to a
|
||||
# protected branch.
|
||||
if current_project
|
||||
current_user.can?(:push_code, current_project) &&
|
||||
current_project.team.max_member_access(current_user.id) >= access_level
|
||||
elsif protected_branch_group
|
||||
protected_branch_group.max_member_access_for_user(current_user) >= access_level
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ module ProtectedRefDeployKeyAccess
|
|||
super
|
||||
end
|
||||
|
||||
def check_access(current_user)
|
||||
def check_access(current_user, current_project = project)
|
||||
super do
|
||||
break enabled_deploy_key_for_user?(current_user) if deploy_key?
|
||||
|
||||
|
|
|
@ -438,7 +438,7 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
|
||||
def tag(tag)
|
||||
if migrated? && ContainerRegistry::GitlabApiClient.supports_gitlab_api?
|
||||
if can_access_the_gitlab_api?
|
||||
page = tags_page(name: tag, page_size: 1)
|
||||
|
||||
page[:tags].first
|
||||
|
@ -452,11 +452,20 @@ class ContainerRepository < ApplicationRecord
|
|||
end
|
||||
|
||||
def tags
|
||||
return [] unless manifest && manifest['tags']
|
||||
|
||||
strong_memoize(:tags) do
|
||||
manifest['tags'].sort.map do |tag|
|
||||
ContainerRegistry::Tag.new(self, tag)
|
||||
if can_access_the_gitlab_api? && Feature.enabled?(:fetch_tags_from_registry_api, project)
|
||||
result = []
|
||||
each_tags_page do |array_of_tags|
|
||||
result << array_of_tags
|
||||
end
|
||||
|
||||
result.flatten
|
||||
else
|
||||
next [] unless manifest && manifest['tags']
|
||||
|
||||
manifest['tags'].sort.map do |tag|
|
||||
ContainerRegistry::Tag.new(self, tag)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -645,6 +654,10 @@ class ContainerRepository < ApplicationRecord
|
|||
|
||||
private
|
||||
|
||||
def can_access_the_gitlab_api?
|
||||
migrated? && ContainerRegistry::GitlabApiClient.supports_gitlab_api?
|
||||
end
|
||||
|
||||
def finish_import_as(reason)
|
||||
self.migration_skipped_reason = reason
|
||||
finish_import
|
||||
|
|
|
@ -28,7 +28,7 @@ module Users
|
|||
registration_enabled_callout: 25,
|
||||
new_user_signups_cap_reached: 26, # EE-only
|
||||
unfinished_tag_cleanup_callout: 27,
|
||||
eoa_bronze_plan_banner: 28, # EE-only
|
||||
# 28 removed in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146309
|
||||
pipeline_needs_banner: 29,
|
||||
pipeline_needs_hover_tip: 30,
|
||||
web_ide_ci_environments_guidance: 31,
|
||||
|
|
|
@ -1,11 +1 @@
|
|||
- page_title _('Comment templates')
|
||||
|
||||
#js-comment-templates-root.settings-section.gl-mt-3{ data: { base_path: profile_comment_templates_path } }
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0
|
||||
= page_title
|
||||
%p.gl-text-secondary
|
||||
= _('Comment templates can be used when creating comments inside issues, merge requests, and epics.')
|
||||
|
||||
= gl_loading_icon(size: 'lg')
|
||||
= render "shared/comment_templates/page", base_path: profile_comment_templates_path
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
- base_path = local_assigns.fetch(:base_path, '')
|
||||
- namespace_id = local_assigns.fetch(:namespace_id, nil)
|
||||
- page_title _('Comment templates')
|
||||
|
||||
#js-comment-templates-root.settings-section.gl-mt-3{ data: { base_path: base_path, namespace_id: namespace_id, } }
|
||||
.settings-sticky-header
|
||||
.settings-sticky-header-inner
|
||||
%h4.gl-my-0
|
||||
= page_title
|
||||
%p.gl-text-secondary
|
||||
= _('Comment templates can be used when creating comments inside issues, merge requests, and epics.')
|
||||
|
||||
= gl_loading_icon(size: 'lg')
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: fetch_tags_from_registry_api
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/432471
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145397
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/442576
|
||||
milestone: '16.10'
|
||||
group: group::container registry
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
|
@ -42,7 +42,7 @@ There are several other benefits to enabling Service Ping:
|
|||
In GitLab versions 14.1 and later, GitLab Free customers with a self-managed instance running
|
||||
GitLab Enterprise Edition can receive paid features by registering with GitLab and sending us
|
||||
activity data through Service Ping. Features introduced here do not remove the feature from its paid
|
||||
tier. Users can continue to access the features in a paid tier without sharing usage data.
|
||||
tier. Instances on a paid tier are subject to our [Product Usage Data policy](https://handbook.gitlab.com/handbook/legal/privacy/customer-product-usage-information/) managed by [Cloud Licensing](https://about.gitlab.com/pricing/licensing-faq/cloud-licensing/).
|
||||
|
||||
NOTE:
|
||||
Registration is not required for participation.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123408) in GitLab 16.2.
|
||||
|
||||
|
|
|
@ -33023,7 +33023,6 @@ Name of the feature that the callout is for.
|
|||
| <a id="usercalloutfeaturenameenumcluster_security_warning"></a>`CLUSTER_SECURITY_WARNING` | Callout feature name for cluster_security_warning. |
|
||||
| <a id="usercalloutfeaturenameenumcode_suggestions_ga_owner_alert"></a>`CODE_SUGGESTIONS_GA_OWNER_ALERT` | Callout feature name for code_suggestions_ga_owner_alert. |
|
||||
| <a id="usercalloutfeaturenameenumduo_chat_callout"></a>`DUO_CHAT_CALLOUT` | Callout feature name for duo_chat_callout. |
|
||||
| <a id="usercalloutfeaturenameenumeoa_bronze_plan_banner"></a>`EOA_BRONZE_PLAN_BANNER` | Callout feature name for eoa_bronze_plan_banner. |
|
||||
| <a id="usercalloutfeaturenameenumfeature_flags_new_version"></a>`FEATURE_FLAGS_NEW_VERSION` | Callout feature name for feature_flags_new_version. |
|
||||
| <a id="usercalloutfeaturenameenumgcp_signup_offer"></a>`GCP_SIGNUP_OFFER` | Callout feature name for gcp_signup_offer. |
|
||||
| <a id="usercalloutfeaturenameenumgeo_enable_hashed_storage"></a>`GEO_ENABLE_HASHED_STORAGE` | Callout feature name for geo_enable_hashed_storage. |
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36001) in GitLab 13.2.
|
||||
> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
|
||||
|
|
|
@ -8,15 +8,15 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
**Offering:** Self-managed
|
||||
**Offering:** GitLab.com
|
||||
|
||||
> - Introduced in GitLab 15.4 [with a flag](../administration/feature_flags.md) named `cube_api_proxy`. Disabled by default.
|
||||
> - `cube_api_proxy` removed and replaced with `product_analytics_internal_preview` in GitLab 15.10.
|
||||
> - `product_analytics_internal_preview` replaced with `product_analytics_dashboards` in GitLab 15.11.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, an administrator can [enable the feature flag](../administration/feature_flags.md) named `cube_api_proxy`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is not available.
|
||||
On self-managed GitLab and GitLab Dedicated, by default this feature is not available. To make it available per project or for your entire instance, an administrator can [enable the feature flag](../administration/feature_flags.md) named `cube_api_proxy`.
|
||||
On GitLab.com, this feature is available.
|
||||
This feature is not ready for production use.
|
||||
|
||||
NOTE:
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120751) in GitLab 16.1
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
This API endpoint allows you to retrieve some information about the current state
|
||||
of Sidekiq, its jobs, queues, and processes.
|
||||
|
|
|
@ -134,7 +134,7 @@ for example:
|
|||
|
||||
```yaml
|
||||
include:
|
||||
- component: gitlab.example.com/my-org/security-components/secret-detection@1.0
|
||||
- component: gitlab.example.com/my-org/security-components/secret-detection@1.0.0
|
||||
inputs:
|
||||
stage: build
|
||||
```
|
||||
|
@ -146,7 +146,7 @@ In this example:
|
|||
- `my-org/security-components` is the full path of the project containing the component.
|
||||
- `secret-detection` is the component name that is defined as either a single file `templates/secret-detection.yml`
|
||||
or as a directory `templates/secret-detection/` containing a `template.yml`.
|
||||
- `1.0` is the [version](#component-versions) of the component.
|
||||
- `1.0.0` is the [version](#component-versions) of the component.
|
||||
|
||||
When GitLab creates a new pipeline, the component's configuration is fetched and added to
|
||||
the pipeline's configuration.
|
||||
|
@ -157,7 +157,7 @@ In order of highest priority first, the component version can be:
|
|||
|
||||
- A commit SHA, for example `e3262fdd0914fa823210cdb79a8c421e2cef79d8`. Use a commit SHA
|
||||
to pin a component to a specific version that is not [published in the CI/CD catalog](#publish-a-new-release).
|
||||
- A tag, for example: `1.0`. If a tag and commit SHA exist with the same name,
|
||||
- A tag, for example: `1.0.0`. If a tag and commit SHA exist with the same name,
|
||||
the commit SHA takes precedence over the tag.
|
||||
- A branch name, for example `main`. If a branch and tag exist with the same name,
|
||||
the tag takes precedence over the branch.
|
||||
|
@ -168,6 +168,19 @@ In order of highest priority first, the component version can be:
|
|||
You can use any [version](#component-versions) supported by the component, but using a
|
||||
version published to the CI/CD catalog is recommended.
|
||||
|
||||
#### Use semantic versioning
|
||||
|
||||
When tagging and [releasing new versions](#publish-a-new-release) of components,
|
||||
you must use [semantic versioning](https://semver.org). Semantic versioning is the standard
|
||||
for communicating that a change is a major, minor, patch, or other kind of change.
|
||||
|
||||
For example:
|
||||
|
||||
- `1.0.0`
|
||||
- `2.1.3`
|
||||
- `1.0.0-alpha`
|
||||
- `3.0.0-rc1`
|
||||
|
||||
## CI/CD Catalog
|
||||
|
||||
DETAILS:
|
||||
|
@ -243,7 +256,9 @@ Prerequisites:
|
|||
To publish a new version of the component to the catalog:
|
||||
|
||||
1. Add a job to the project's `.gitlab-ci.yml` file that uses the [`release`](../yaml/index.md#release)
|
||||
keyword to create the new release. For example:
|
||||
keyword to create the new release when a tag is created.
|
||||
You should configure the tag pipeline to [test the components](#test-the-component) before
|
||||
running the release job. For example:
|
||||
|
||||
```yaml
|
||||
create-release:
|
||||
|
@ -259,11 +274,9 @@ To publish a new version of the component to the catalog:
|
|||
|
||||
1. Create a [new tag](../../user/project/repository/tags/index.md#create-a-tag) for the release,
|
||||
which should trigger a tag pipeline that contains the job responsible for creating the release.
|
||||
You should configure the tag pipeline to [test the components](#test-the-component) before
|
||||
running the release job.
|
||||
|
||||
After the release job completes successfully, the release is created and the new version
|
||||
is published to the CI/CD catalog. Tags must use semantic versioning, for example `1.0.0`.
|
||||
is published to the CI/CD catalog.
|
||||
|
||||
### Unpublish a component project
|
||||
|
||||
|
@ -280,6 +293,19 @@ To publish the component project in the catalog again, you need to [publish a ne
|
|||
|
||||
This section describes some best practices for creating high quality component projects.
|
||||
|
||||
### Manage dependencies
|
||||
|
||||
While it's possible for a component to use other components in turn, make sure to carefully select the dependencies. To manage dependencies, you should:
|
||||
|
||||
- Keep dependencies to a minimum. A small amount of duplication is usually better than having dependencies.
|
||||
- Rely on local dependencies whenever possible. For example, using [`include:local`](../../ci/yaml/index.md#includelocal) is a good way
|
||||
to ensure the same Git SHA is used across multiple files.
|
||||
- When depending on components from other projects, pin their version to a release from the catalog rather than using moving target
|
||||
versions such as `~latest` or a Git reference. Using a release or Git SHA guarantees that you are fetching the same revision
|
||||
all the time and that consumers of your component get consistent behavior.
|
||||
- Update your dependencies regularly by pinning them to newer releases. Then publish a new release of your components with updated
|
||||
dependencies.
|
||||
|
||||
### Write a clear `README.md`
|
||||
|
||||
Each component project should have clear and comprehensive documentation. To
|
||||
|
@ -473,7 +499,7 @@ For example, to create a component with `stage` configuration that can be define
|
|||
stages: [verify, deploy]
|
||||
|
||||
include:
|
||||
- component: $CI_SERVER_FQDN/gitlab-org/ruby-test@1.0
|
||||
- component: $CI_SERVER_FQDN/myorg/ruby/test@1.0.0
|
||||
inputs:
|
||||
stage: verify
|
||||
```
|
||||
|
@ -506,7 +532,7 @@ For example, use `inputs` instead of variables to configure a scanner's output f
|
|||
|
||||
```yaml
|
||||
include:
|
||||
- component: $CI_SERVER_FQDN/my-scanner@1.0
|
||||
- component: $CI_SERVER_FQDN/path/to/project/my-scanner@1.0.0
|
||||
inputs:
|
||||
scanner-output: yaml
|
||||
```
|
||||
|
@ -517,22 +543,6 @@ In other cases, CI/CD variables might still be preferred. For example:
|
|||
a component to match a user's project.
|
||||
- Ask users to store sensitive values as [masked or protected CI/CD variables in project settings](../variables/index.md#define-a-cicd-variable-in-the-ui).
|
||||
|
||||
### Use semantic versioning
|
||||
|
||||
When tagging and [releasing new versions](#publish-a-new-release) of components,
|
||||
you should use [semantic versioning](https://semver.org). Semantic versioning is the standard
|
||||
for communicating that a change is a major, minor, patch, or other kind of change.
|
||||
|
||||
You should use at least the `major.minor` format, as this is widely understood. For example,
|
||||
`2.0` or `2.1`.
|
||||
|
||||
Other examples of semantic versioning:
|
||||
|
||||
- `1.0.0`
|
||||
- `2.1.3`
|
||||
- `1.0.0-alpha`
|
||||
- `3.0.0-rc1`
|
||||
|
||||
## Convert a CI/CD template to a component
|
||||
|
||||
Any existing CI/CD template that you use in projects by using the `include:` syntax
|
||||
|
|
|
@ -275,9 +275,8 @@ and the analysis is tracked as a Snowplow event.
|
|||
The analysis can contain any of the attributes defined in the latest [iglu schema](https://gitlab.com/gitlab-org/iglu/-/blob/master/public/schemas/com.gitlab/ai_question_category/jsonschema).
|
||||
|
||||
- All possible "category" and "detailed_category" are listed [here](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/llm/fixtures/categories.xml).
|
||||
- The following are yet to be implemented:
|
||||
- The following is yet to be implemented:
|
||||
- "is_proper_sentence"
|
||||
- "asked_on_the_same_page"
|
||||
- The following are deprecated:
|
||||
- "number_of_questions_in_history"
|
||||
- "length_of_questions_in_history"
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
**Status:** Beta
|
||||
|
||||
The Geo API is used internally by GitLab components to assist in coordinating Geo actions. It is inaccessible to admins or users.
|
||||
|
|
|
@ -1505,7 +1505,7 @@ Returns an empty response with a `204` status code if successful.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378599) in GitLab 15.8.
|
||||
|
||||
|
|
|
@ -194,6 +194,14 @@ bin/rspec --tag ~quarantine
|
|||
|
||||
After the long-term quarantining MR has reached production, you should revert the fast-quarantine MR you created earlier.
|
||||
|
||||
#### Find quarantined tests by feature category
|
||||
|
||||
To find all quarantined tests for a feature category, use `ripgrep`:
|
||||
|
||||
```shell
|
||||
rg -l --multiline -w "(?s)feature_category:\s+:global_search.+quarantine:"
|
||||
```
|
||||
|
||||
### Jest
|
||||
|
||||
For Jest specs, you can use the `.skip` method along with the `eslint-disable-next-line` comment to disable the `jest/no-disabled-tests` ESLint rule and include the issue URL. Here's an example:
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
You can enable the AliCloud OAuth 2.0 OmniAuth provider and sign in to
|
||||
GitLab using your AliCloud account.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
To enable the Auth0 OmniAuth provider, you must create an Auth0 account, and an
|
||||
application.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can enable the Microsoft Azure OAuth 2.0 OmniAuth provider and sign in to
|
||||
GitLab with your Microsoft Azure credentials. You can configure the provider that uses
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can set up Bitbucket.org as an OAuth 2.0 provider to use your Bitbucket.org
|
||||
account credentials to sign in to GitLab. You can also import your projects from
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341898) in GitLab 14.5.
|
||||
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/390855) in GitLab 15.10.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can use the Facebook OmniAuth provider to authenticate users with their Facebook account.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can integrate your GitLab instance with GitHub.com and GitHub Enterprise.
|
||||
You can import projects from GitHub, or sign in to GitLab
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Import projects from GitLab.com and login to your GitLab instance with your GitLab.com account.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: "To determine the technical writer assigned to the Stage/Group associated
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/228893) in GitLab 13.4.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/258206) in GitLab 13.8
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
To enable the Google OAuth 2.0 OmniAuth provider you must register your application
|
||||
with Google. Google generates a client ID and secret key for you to use.
|
||||
|
|
|
@ -7,10 +7,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Integrate with GitLab
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
You can integrate GitLab with external applications for enhanced functionality.
|
||||
|
||||
## Project integrations
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
NOTE:
|
||||
If your provider supports the OpenID specification, you should use [`omniauth-openid-connect`](../administration/auth/oidc.md) as your authentication provider.
|
||||
|
|
|
@ -75,7 +75,7 @@ To create a new application for a group:
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
To create an application for your GitLab instance:
|
||||
|
||||
|
@ -152,7 +152,7 @@ application are also deleted.
|
|||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../administration/feature_flags.md) named `hash_oauth_secrets`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is available.
|
||||
On GitLab.com, this feature is available.
|
||||
|
||||
By default, GitLab stores OAuth application secrets in the database in hashed format. These secrets are only available to users immediately after creating OAuth applications. In
|
||||
earlier versions of GitLab, application secrets are stored as plain text in the database.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Users can sign in to GitLab by using their credentials from Twitter, GitHub, and other popular services.
|
||||
[OmniAuth](https://rubygems.org/gems/omniauth/) is the Rack framework that GitLab uses to provide this authentication.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
This document is about using GitLab as an OpenID Connect identity provider
|
||||
to sign in to other services.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can integrate your GitLab instance with [Salesforce](https://www.salesforce.com/) to enable users to sign in to your GitLab instance with their Salesforce account.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
This page describes how to set up instance-wide SAML single sign on (SSO) for
|
||||
self-managed GitLab instances.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
<!--- start_remove The following content will be removed on remove_date: '2024-05-17' -->
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
[CRIME](https://en.wikipedia.org/w/index.php?title=CRIME&oldid=692423806) is a security exploit against
|
||||
secret web cookies over connections using the HTTPS and SPDY protocols that also
|
||||
|
|
|
@ -6,10 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Responding to security incidents
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
When a security incident occurs, you should follow the processes defined by your organization. The GitLab SIRT team created this guide:
|
||||
|
||||
- For administrators and maintainers of self-managed GitLab instances and groups on GitLab.com.
|
||||
|
@ -25,10 +21,6 @@ Use the suggestions/recommendations mentioned in this guide at your own risk.
|
|||
|
||||
### Credential exposure to public internet
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
|
||||
This scenario refers to security events where sensitive authentication or authorization information has been exposed to the Internet due to misconfigurations or human errors. Such information might include:
|
||||
|
||||
- Passwords.
|
||||
|
@ -57,10 +49,6 @@ Security incidents related to credentials exposure can vary in severity from low
|
|||
|
||||
#### Event types
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
|
||||
- Review the available [audit events](../administration/audit_events.md) for your group or namespace.
|
||||
- Adversaries may attempt to create tokens, SSH keys, or user accounts to maintain persistence. Look for [audit events](../administration/audit_event_streaming/audit_event_types.md) related to these activities.
|
||||
- Focus on CI-related [audit events](../administration/audit_event_types.md#continuous-integration) to identify any modifications to CI/CD variables.
|
||||
|
@ -68,10 +56,6 @@ DETAILS:
|
|||
|
||||
### Suspected compromised user account
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
|
||||
#### Response
|
||||
|
||||
If you suspect that a user account or bot account has been compromised, you should:
|
||||
|
@ -84,10 +68,6 @@ If you suspect that a user account or bot account has been compromised, you shou
|
|||
|
||||
#### Event types
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
|
||||
Review the [audit events](../administration/audit_events.md) available to you to identify any suspicious account behavior. For example:
|
||||
|
||||
- Suspicious sign-in events.
|
||||
|
@ -104,10 +84,6 @@ Review the [audit events](../administration/audit_events.md) available to you to
|
|||
|
||||
### CI/CD-related security incidents
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
CI/CD workflows are an integral part of modern day software development and primarily used by developers and SREs to build, test and deploy code to production. Because these workflows are attached to the production environments, they often require access to sensitive secrets within the CI/CD pipelines. Security incidents related to CI/CD might vary based on your setup, but they can be broadly classified as follows:
|
||||
|
||||
- Security incidents related to exposed GitLab CI/CD job tokens.
|
||||
|
@ -141,10 +117,6 @@ When secrets stored as CI variables are not [masked](../ci/variables/index.md#ma
|
|||
|
||||
### Suspected compromised instance
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
Self-managed GitLab customers and administrators are responsible for:
|
||||
|
||||
- The security of their underlying infrastructure.
|
||||
|
@ -173,18 +145,10 @@ If you suspect that your GitLab instance has been compromised, you should:
|
|||
|
||||
#### Event types
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
|
||||
Review [system access audit events](../administration/audit_event_types.md#system-access) to determine any changes related to system settings, user permissions and user login events.
|
||||
|
||||
### Misconfigured project or group settings
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
Security incidents can occur as a result of improperly configured project or group settings, potentially leading to unauthorized access to sensitive or proprietary data. These incidents may include but are not limited to:
|
||||
|
||||
- Changes in project visibility.
|
||||
|
@ -203,10 +167,6 @@ If you suspect unauthorized modifications to project settings, consider taking t
|
|||
|
||||
#### Event types
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
|
||||
- Audit logs can be filtered based on the `target_type` field. Based on the security incident context, apply a filter to this field to narrow down the scope.
|
||||
- Look for specific audit events of [compliance management](../administration/audit_event_types.md#compliance-management) and [audit events of groups and projects](../administration/audit_event_types.md#groups-and-projects).
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
`ssh-keygen` allows users to create RSA keys with as few as 768 bits, which
|
||||
falls well below recommendations from certain standards groups (such as the US
|
||||
|
|
|
@ -143,7 +143,7 @@ enabled, 2FA is **not** required for those individually added members.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can disable 2FA for a single user or all users.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ description: Doing SRE for Gitaly instances on AWS.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
## Gitaly SRE considerations
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ info: This page is owned by the Solutions Architecture team.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
If you want to provision a single GitLab instance on AWS, you have two options:
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@ It's the offering of choice for enterprises and organizations in highly regulate
|
|||
|
||||
GitLab Dedicated allows you to select the cloud region where your data will be stored. Upon [onboarding](../../administration/dedicated/create_instance.md#step-2-create-your-gitlab-dedicated-instance), choose the cloud region where you want to deploy your Dedicated instance. Some AWS regions have limited features and as a result, we are not able to deploy production instances to those regions. See below for the [list of available AWS regions](#available-aws-regions).
|
||||
|
||||
### Advanced search
|
||||
|
||||
GitLab Dedicated uses the [advanced search functionality](../../integration/advanced_search/elasticsearch.md).
|
||||
|
||||
### Availability and scalability
|
||||
|
||||
GitLab Dedicated leverages modified versions of the GitLab [Cloud Native Hybrid reference architectures](../../administration/reference_architectures/index.md#cloud-native-hybrid) with high availability enabled. When [onboarding](../../administration/dedicated/create_instance.md#step-2-create-your-gitlab-dedicated-instance), GitLab will match you to the closest reference architecture size based on your number of users. Learn about the [current Service Level Objective](https://handbook.gitlab.com/handbook/engineering/infrastructure/team/gitlab-dedicated/slas/#current-service-level-objective).
|
||||
|
|
|
@ -126,11 +126,17 @@ To view the Value Streams Dashboard as an analytics dashboard for a project:
|
|||
|
||||
## View group dashboards
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/390542) in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `group_analytics_dashboards`. Disabled by default.
|
||||
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/416970) in GitLab 16.8.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../../administration/feature_flags.md) named `group_analytics_dashboards`. On GitLab.com, this feature is available. On GitLab Dedicated, this feature is not available.
|
||||
On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../../administration/feature_flags.md) named `group_analytics_dashboards`.
|
||||
On GitLab.com and GitLab Dedicated, this feature is available.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
NOTE:
|
||||
To set up an offline environment, you must receive an [opt-out exemption of cloud licensing](https://about.gitlab.com/pricing/licensing-faq/cloud-licensing/#offline-cloud-licensing) prior to purchase. For more details, contact your GitLab sales representative.
|
||||
|
|
|
@ -50,9 +50,7 @@ DETAILS:
|
|||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233905/) in GitLab 16.3 [with a flag](../../../administration/feature_flags.md) named `issues_completed_analytics_feature_flag`. Disabled by default.
|
||||
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/437542) in GitLab 16.8.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `issues_completed_analytics_feature_flag`. On GitLab.com and GitLab Dedicated, this feature is available.
|
||||
> - [Feature flag `issues_completed_analytics_feature_flag`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146766) removed in GitLab 16.10.
|
||||
|
||||
Enhanced issue analytics display the additional metric "Issues closed", which represents the total number of resolved issues in your group over a selected period.
|
||||
You can use this metric to improve the overall turn-around time and value delivered to your customers.
|
||||
|
|
|
@ -124,6 +124,12 @@ browser's console in the developers tools:
|
|||
atob(decodeURI("<paste_SAML_response_here>"))
|
||||
```
|
||||
|
||||
On MacOS, you can decode the clipboard data by running:
|
||||
|
||||
```plaintext
|
||||
pbpaste | base64 -D
|
||||
```
|
||||
|
||||
You should get the SAML response in XML format as output.
|
||||
|
||||
## Configuration errors
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39840) in GitLab 11.11.
|
||||
> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
**Status:** Experiment
|
||||
|
||||
> - Debian API [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42670) in GitLab 13.5.
|
||||
|
|
|
@ -54,7 +54,7 @@ To go to your comment templates:
|
|||
1. On the left sidebar, select your avatar.
|
||||
1. From the dropdown list, select **Preferences**.
|
||||
1. On the left sidebar, select **Comment templates** (**{comment-lines}**).
|
||||
1. Scroll to **My comment templates**.
|
||||
1. Scroll to **Comment templates**.
|
||||
|
||||
## Edit or delete comment templates
|
||||
|
||||
|
@ -63,6 +63,6 @@ To edit or delete a previously comment template:
|
|||
1. On the left sidebar, select your avatar.
|
||||
1. From the dropdown list, select **Preferences**.
|
||||
1. On the left sidebar, select **Comment templates** (**{comment-lines}**).
|
||||
1. Scroll to **My comment templates**, and identify the comment template you want to edit.
|
||||
1. Scroll to **Comment templates**, and identify the comment template you want to edit.
|
||||
1. To edit, select **Edit** (**{pencil}**).
|
||||
1. To delete, select **Delete** (**{remove}**), then select **Delete** again on the dialog.
|
||||
|
|
|
@ -21,7 +21,7 @@ Both types of search are the same, except when you are searching through code.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68640) in GitLab 14.3.
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@ module Backup
|
|||
def run_create_task(task)
|
||||
build_backup_information
|
||||
|
||||
destination_dir = backup_path.join(task.destination_path)
|
||||
|
||||
unless task.enabled?
|
||||
puts_time "Dumping #{task.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan)
|
||||
return
|
||||
|
@ -46,7 +44,7 @@ module Backup
|
|||
end
|
||||
|
||||
puts_time "Dumping #{task.human_name} ... ".color(:blue)
|
||||
task.target.dump(destination_dir, backup_id)
|
||||
task.backup!(backup_path, backup_id)
|
||||
puts_time "Dumping #{task.human_name} ... ".color(:blue) + "done".color(:green)
|
||||
|
||||
rescue Backup::DatabaseBackupError, Backup::FileBackupError => e
|
||||
|
@ -66,8 +64,6 @@ module Backup
|
|||
def run_restore_task(task)
|
||||
read_backup_information
|
||||
|
||||
destination_dir = backup_path.join(task.destination_path)
|
||||
|
||||
unless task.enabled?
|
||||
puts_time "Restoring #{task.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan)
|
||||
return
|
||||
|
@ -75,16 +71,17 @@ module Backup
|
|||
|
||||
puts_time "Restoring #{task.human_name} ... ".color(:blue)
|
||||
|
||||
warning = task.target.pre_restore_warning
|
||||
warning = task.pre_restore_warning
|
||||
if warning.present?
|
||||
puts_time warning.color(:red)
|
||||
Gitlab::TaskHelpers.ask_to_continue
|
||||
end
|
||||
|
||||
task.target.restore(destination_dir, backup_id)
|
||||
task.restore!(backup_path, backup_id)
|
||||
|
||||
puts_time "Restoring #{task.human_name} ... ".color(:blue) + "done".color(:green)
|
||||
|
||||
warning = task.target.post_restore_warning
|
||||
warning = task.post_restore_warning
|
||||
if warning.present?
|
||||
puts_time warning.color(:red)
|
||||
Gitlab::TaskHelpers.ask_to_continue
|
||||
|
|
|
@ -7,7 +7,7 @@ module Backup
|
|||
class Database < Target
|
||||
extend ::Gitlab::Utils::Override
|
||||
include Backup::Helper
|
||||
attr_reader :force
|
||||
attr_reader :force, :errors
|
||||
|
||||
IGNORED_ERRORS = [
|
||||
# Ignore warnings
|
||||
|
@ -19,9 +19,11 @@ module Backup
|
|||
].freeze
|
||||
IGNORED_ERRORS_REGEXP = Regexp.union(IGNORED_ERRORS).freeze
|
||||
|
||||
def initialize(progress, options:, force:)
|
||||
def initialize(progress, options:)
|
||||
super(progress, options: options)
|
||||
@force = force
|
||||
|
||||
@errors = []
|
||||
@force = options.force?
|
||||
end
|
||||
|
||||
override :dump
|
||||
|
@ -81,6 +83,8 @@ module Backup
|
|||
override :restore
|
||||
|
||||
def restore(destination_dir, _)
|
||||
@errors = []
|
||||
|
||||
base_models_for_backup.each do |database_name, _|
|
||||
backup_connection = Backup::DatabaseConnection.new(database_name)
|
||||
|
||||
|
@ -105,13 +109,14 @@ module Backup
|
|||
# hanging out from a failed upgrade
|
||||
drop_tables(database_name)
|
||||
|
||||
tracked_errors = []
|
||||
pg_env = backup_connection.database_configuration.pg_env_variables
|
||||
success = with_transient_pg_env(pg_env) do
|
||||
decompress_rd, decompress_wr = IO.pipe
|
||||
decompress_pid = spawn(decompress_cmd, out: decompress_wr, in: db_file_name)
|
||||
decompress_wr.close
|
||||
|
||||
status, @errors =
|
||||
status, tracked_errors =
|
||||
case config[:adapter]
|
||||
when "postgresql" then
|
||||
progress.print "Restoring PostgreSQL database #{database} ... "
|
||||
|
@ -123,10 +128,12 @@ module Backup
|
|||
$?.success? && status.success?
|
||||
end
|
||||
|
||||
if @errors.present?
|
||||
unless tracked_errors.empty?
|
||||
progress.print "------ BEGIN ERRORS -----\n".color(:yellow)
|
||||
progress.print @errors.join.color(:yellow)
|
||||
progress.print tracked_errors.join.color(:yellow)
|
||||
progress.print "------ END ERRORS -------\n".color(:yellow)
|
||||
|
||||
@errors += tracked_errors
|
||||
end
|
||||
|
||||
report_success(success)
|
||||
|
@ -134,38 +141,6 @@ module Backup
|
|||
end
|
||||
end
|
||||
|
||||
override :pre_restore_warning
|
||||
|
||||
def pre_restore_warning
|
||||
return if force
|
||||
|
||||
<<-MSG.strip_heredoc
|
||||
Be sure to stop Puma, Sidekiq, and any other process that
|
||||
connects to the database before proceeding. For Omnibus
|
||||
installs, see the following link for more information:
|
||||
#{help_page_url('raketasks/backup_restore.html', 'restore-for-omnibus-gitlab-installations')}
|
||||
|
||||
Before restoring the database, we will remove all existing
|
||||
tables to avoid future upgrade problems. Be aware that if you have
|
||||
custom tables in the GitLab database these tables and all data will be
|
||||
removed.
|
||||
MSG
|
||||
end
|
||||
|
||||
override :post_restore_warning
|
||||
|
||||
def post_restore_warning
|
||||
return unless @errors.present?
|
||||
|
||||
<<-MSG.strip_heredoc
|
||||
There were errors in restoring the schema. This may cause
|
||||
issues if this results in missing indexes, constraints, or
|
||||
columns. Please record the errors above and contact GitLab
|
||||
Support if you have questions:
|
||||
https://about.gitlab.com/support/
|
||||
MSG
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def base_models_for_backup
|
||||
|
@ -283,10 +258,6 @@ module Backup
|
|||
def multiple_databases?
|
||||
Gitlab::Database.database_mode == Gitlab::Database::MODE_MULTIPLE_DATABASES
|
||||
end
|
||||
|
||||
def help_page_url(path, anchor = nil)
|
||||
::Gitlab::Routing.url_helpers.help_page_url(path, anchor: anchor)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,12 +26,6 @@ module Backup
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# a string returned here will be displayed to the user before calling #restore
|
||||
def pre_restore_warning = ''
|
||||
|
||||
# a string returned here will be displayed to the user after calling #restore
|
||||
def post_restore_warning = ''
|
||||
|
||||
private
|
||||
|
||||
attr_reader :progress
|
||||
|
|
|
@ -9,14 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'artifacts.tar.gz'
|
||||
|
||||
def target
|
||||
excludes = ['tmp']
|
||||
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: excludes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: ['tmp'])
|
||||
end
|
||||
|
||||
def storage_path
|
||||
JobArtifactUploader.root
|
||||
end
|
||||
|
|
|
@ -9,12 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'builds.tar.gz'
|
||||
|
||||
def target
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options)
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Settings.gitlab_ci.builds_path
|
||||
end
|
||||
|
|
|
@ -9,14 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'ci_secure_files.tar.gz'
|
||||
|
||||
def target
|
||||
excludes = ['tmp']
|
||||
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: excludes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: ['tmp'])
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Settings.ci_secure_files.storage_path
|
||||
end
|
||||
|
|
|
@ -11,8 +11,42 @@ module Backup
|
|||
|
||||
def cleanup_path = 'db'
|
||||
|
||||
def pre_restore_warning
|
||||
return if options.force
|
||||
|
||||
<<-MSG.strip_heredoc
|
||||
Be sure to stop Puma, Sidekiq, and any other process that
|
||||
connects to the database before proceeding. For Omnibus
|
||||
installs, see the following link for more information:
|
||||
#{help_page_url('raketasks/backup_restore.html', 'restore-for-omnibus-gitlab-installations')}
|
||||
|
||||
Before restoring the database, we will remove all existing
|
||||
tables to avoid future upgrade problems. Be aware that if you have
|
||||
custom tables in the GitLab database these tables and all data will be
|
||||
removed.
|
||||
MSG
|
||||
end
|
||||
|
||||
def post_restore_warning
|
||||
return if target.errors.empty?
|
||||
|
||||
<<-MSG.strip_heredoc
|
||||
There were errors in restoring the schema. This may cause
|
||||
issues if this results in missing indexes, constraints, or
|
||||
columns. Please record the errors above and contact GitLab
|
||||
Support if you have questions:
|
||||
https://about.gitlab.com/support/
|
||||
MSG
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
::Backup::Targets::Database.new(progress, options: options, force: options.force?)
|
||||
@target ||= ::Backup::Targets::Database.new(progress, options: options)
|
||||
end
|
||||
|
||||
def help_page_url(path, anchor = nil)
|
||||
::Gitlab::Routing.url_helpers.help_page_url(path, anchor: anchor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,12 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'lfs.tar.gz'
|
||||
|
||||
def target
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options)
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Settings.lfs.storage_path
|
||||
end
|
||||
|
|
|
@ -9,14 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'packages.tar.gz'
|
||||
|
||||
def target
|
||||
excludes = ['tmp']
|
||||
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: excludes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: ['tmp'])
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Settings.packages.storage_path
|
||||
end
|
||||
|
|
|
@ -13,14 +13,13 @@ module Backup
|
|||
|
||||
def destination_path = 'pages.tar.gz'
|
||||
|
||||
def target
|
||||
excludes = [LEGACY_PAGES_TMP_PATH]
|
||||
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: excludes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(
|
||||
progress, storage_path, options: options, excludes: [LEGACY_PAGES_TMP_PATH])
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Gitlab.config.pages.path
|
||||
end
|
||||
|
|
|
@ -11,12 +11,12 @@ module Backup
|
|||
|
||||
def destination_path = 'registry.tar.gz'
|
||||
|
||||
def target
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options)
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Settings.registry.path
|
||||
end
|
||||
|
|
|
@ -19,7 +19,11 @@ module Backup
|
|||
|
||||
def destination_optional = true
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
return @target if @target
|
||||
|
||||
strategy = Backup::GitalyBackup.new(progress,
|
||||
incremental: options.incremental?,
|
||||
max_parallelism: options.max_parallelism,
|
||||
|
@ -27,7 +31,7 @@ module Backup
|
|||
server_side: server_side_callable.call
|
||||
)
|
||||
|
||||
::Backup::Targets::Repositories.new(progress,
|
||||
@target = ::Backup::Targets::Repositories.new(progress,
|
||||
strategy: strategy,
|
||||
options: options,
|
||||
storages: options.repositories_storages,
|
||||
|
|
|
@ -15,44 +15,59 @@ module Backup
|
|||
@options = options
|
||||
end
|
||||
|
||||
# Key string that identifies the task
|
||||
def id
|
||||
self.class.id
|
||||
# Initiate a backup
|
||||
#
|
||||
# @param [Pathname] backup_path a path where to store the backups
|
||||
# @param [String] backup_id
|
||||
def backup!(backup_path, backup_id)
|
||||
backup_output = backup_path.join(destination_path)
|
||||
|
||||
target.dump(backup_output, backup_id)
|
||||
end
|
||||
|
||||
def restore!(backup_path, backup_id)
|
||||
backup_output = backup_path.join(destination_path)
|
||||
|
||||
target.restore(backup_output, backup_id)
|
||||
end
|
||||
|
||||
# Key string that identifies the task
|
||||
def id = self.class.id
|
||||
|
||||
# Name of the task used for logging.
|
||||
def human_name
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Where the task should put its backup file/dir
|
||||
# Where to put the backup content
|
||||
# It can be either an archive file or a directory containing multiple data
|
||||
def destination_path
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Path to remove after a successful backup, uses #destination_path when not specified
|
||||
def cleanup_path = destination_path
|
||||
|
||||
# `true` if the destination might not exist on a successful backup
|
||||
def destination_optional = false
|
||||
|
||||
# `true` if the task can be used
|
||||
def enabled = true
|
||||
|
||||
def enabled? = enabled
|
||||
|
||||
# a string returned here will be displayed to the user before calling #restore
|
||||
def pre_restore_warning = nil
|
||||
|
||||
# a string returned here will be displayed to the user after calling #restore
|
||||
def post_restore_warning = nil
|
||||
|
||||
private
|
||||
|
||||
# The target factory method
|
||||
def target
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Path to remove after a successful backup, uses #destination_path when not specified
|
||||
def cleanup_path
|
||||
destination_path
|
||||
end
|
||||
|
||||
# `true` if the destination might not exist on a successful backup
|
||||
def destination_optional
|
||||
false
|
||||
end
|
||||
|
||||
# `true` if the task can be used
|
||||
def enabled
|
||||
true
|
||||
end
|
||||
|
||||
def enabled?
|
||||
enabled
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,14 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'terraform_state.tar.gz'
|
||||
|
||||
def target
|
||||
excludes = ['tmp']
|
||||
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: excludes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: ['tmp'])
|
||||
end
|
||||
|
||||
def storage_path
|
||||
Settings.terraform_state.storage_path
|
||||
end
|
||||
|
|
|
@ -9,14 +9,12 @@ module Backup
|
|||
|
||||
def destination_path = 'uploads.tar.gz'
|
||||
|
||||
def target
|
||||
excludes = ['tmp']
|
||||
|
||||
::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: excludes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= ::Backup::Targets::Files.new(progress, storage_path, options: options, excludes: ['tmp'])
|
||||
end
|
||||
|
||||
def storage_path
|
||||
File.join(Gitlab.config.uploads.storage_path, 'uploads')
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ module Gitlab
|
|||
|
||||
trigger_snowplow_event(event_name, category, additional_properties, kwargs) if send_snowplow_event
|
||||
|
||||
if Feature.enabled?(:internal_events_for_product_analytics)
|
||||
if Feature.enabled?(:internal_events_for_product_analytics) && send_snowplow_event
|
||||
send_application_instrumentation_event(event_name, additional_properties, kwargs)
|
||||
end
|
||||
rescue StandardError => e
|
||||
|
|
|
@ -121,7 +121,7 @@ module Gitlab
|
|||
ref, user,
|
||||
project: project,
|
||||
action: action,
|
||||
protected_refs: project.protected_branches)
|
||||
protected_refs: project.all_protected_branches)
|
||||
end
|
||||
|
||||
def protected_tag_accessible_to?(ref, action:)
|
||||
|
|
|
@ -7906,9 +7906,6 @@ msgstr ""
|
|||
msgid "BillingPlans|Dynamic Application Security Testing"
|
||||
msgstr ""
|
||||
|
||||
msgid "BillingPlans|End of availability for the Bronze Plan"
|
||||
msgstr ""
|
||||
|
||||
msgid "BillingPlans|Enterprise Agile Planning"
|
||||
msgstr ""
|
||||
|
||||
|
@ -8065,9 +8062,6 @@ msgstr ""
|
|||
msgid "BillingPlans|Vulnerability Management"
|
||||
msgstr ""
|
||||
|
||||
msgid "BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}."
|
||||
msgstr ""
|
||||
|
||||
msgid "BillingPlans|You can retain access to the %{plan} features by upgrading below."
|
||||
msgstr ""
|
||||
|
||||
|
@ -32265,9 +32259,6 @@ msgstr ""
|
|||
msgid "My awesome group"
|
||||
msgstr ""
|
||||
|
||||
msgid "My comment templates"
|
||||
msgstr ""
|
||||
|
||||
msgid "My company or team"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -65,8 +65,7 @@ RSpec.describe 'New/edit issue', :js, feature_category: :team_planning do
|
|||
click_link user2.name
|
||||
end
|
||||
|
||||
find('.js-assignee-search').click
|
||||
find('.js-dropdown-input-clear').click
|
||||
click_button user2.name
|
||||
|
||||
page.within '.dropdown-menu-user' do
|
||||
expect(page).to have_content user.name
|
||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe 'Profile > Comment templates > List users comment templates', :js
|
|||
it 'shows the user a list of their comment templates' do
|
||||
visit profile_comment_templates_path
|
||||
|
||||
expect(page).to have_content('My comment templates')
|
||||
expect(page).to have_content('Comment templates')
|
||||
expect(page).to have_content(saved_reply.name)
|
||||
expect(page).to have_content(saved_reply.content)
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe 'Profile > Comment templates > User creates comment template', :j
|
|||
|
||||
wait_for_requests
|
||||
|
||||
expect(page).to have_content('My comment templates')
|
||||
expect(page).to have_content('Comment templates')
|
||||
expect(page).to have_content('test')
|
||||
expect(page).to have_content('Test content')
|
||||
end
|
||||
|
|
|
@ -72,6 +72,7 @@ describe('Pipeline details header', () => {
|
|||
const findCommitTitle = () => wrapper.findByTestId('pipeline-commit-title');
|
||||
const findTotalJobs = () => wrapper.findByTestId('total-jobs');
|
||||
const findCommitLink = () => wrapper.findByTestId('commit-link');
|
||||
const findCommitCopyButton = () => wrapper.findByTestId('commit-copy-sha');
|
||||
const findPipelineRunningText = () => wrapper.findByTestId('pipeline-running-text').text();
|
||||
const findPipelineRefText = () => wrapper.findByTestId('pipeline-ref-text').text();
|
||||
const findRetryButton = () => wrapper.findByTestId('retry-pipeline');
|
||||
|
@ -152,6 +153,17 @@ describe('Pipeline details header', () => {
|
|||
} = pipelineHeaderSuccess;
|
||||
|
||||
expect(findCommitLink().attributes('href')).toBe(pipeline.commit.webPath);
|
||||
expect(findCommitLink().text()).toBe(pipeline.commit.shortId);
|
||||
});
|
||||
|
||||
it('copies the full commit ID', () => {
|
||||
const {
|
||||
data: {
|
||||
project: { pipeline },
|
||||
},
|
||||
} = pipelineHeaderSuccess;
|
||||
|
||||
expect(findCommitCopyButton().props('text')).toBe(pipeline.commit.sha);
|
||||
});
|
||||
|
||||
it('displays correct badges', () => {
|
||||
|
|
|
@ -76,6 +76,7 @@ describe('Comment templates form component', () => {
|
|||
id: null,
|
||||
content: 'Test content',
|
||||
name: 'Test',
|
||||
namespaceId: undefined,
|
||||
});
|
||||
expect(trackingSpy).toHaveBeenCalledWith(
|
||||
undefined,
|
||||
|
@ -167,6 +168,7 @@ describe('Comment templates form component', () => {
|
|||
id: '1',
|
||||
content: 'Test content',
|
||||
name: 'Test',
|
||||
namespaceId: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -76,11 +76,7 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
|
||||
let(:pre_restore_warning) { '' }
|
||||
let(:post_restore_warning) { '' }
|
||||
let(:target) do
|
||||
instance_double(::Backup::Targets::Target,
|
||||
pre_restore_warning: pre_restore_warning,
|
||||
post_restore_warning: post_restore_warning)
|
||||
end
|
||||
let(:target) { instance_double(::Backup::Targets::Target) }
|
||||
|
||||
let(:backup_tasks) do
|
||||
{ 'terraform_state' => terraform_state }
|
||||
|
@ -92,6 +88,9 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
allow_next_instance_of(Backup::Metadata) do |metadata|
|
||||
allow(metadata).to receive(:load_from_file).and_return(backup_information)
|
||||
end
|
||||
|
||||
allow(terraform_state).to receive(:pre_restore_warning).and_return(pre_restore_warning)
|
||||
allow(terraform_state).to receive(:post_restore_warning).and_return(post_restore_warning)
|
||||
end
|
||||
|
||||
it 'runs the provided task' do
|
||||
|
@ -953,8 +952,8 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
.tap { |task| allow(task).to receive(:target).and_return(target2) }
|
||||
end
|
||||
|
||||
let(:target1) { instance_double(Backup::Targets::Target, pre_restore_warning: nil, post_restore_warning: nil) }
|
||||
let(:target2) { instance_double(Backup::Targets::Target, pre_restore_warning: nil, post_restore_warning: nil) }
|
||||
let(:target1) { instance_double(Backup::Targets::Target) }
|
||||
let(:target2) { instance_double(Backup::Targets::Target) }
|
||||
let(:backup_tasks) do
|
||||
{ 'lfs' => lfs, 'pages' => pages }
|
||||
end
|
||||
|
|
|
@ -7,7 +7,8 @@ RSpec.describe Backup::Targets::Database, :reestablished_active_record_base, fea
|
|||
let(:progress_output) { progress.string }
|
||||
let(:backup_id) { 'some_id' }
|
||||
let(:one_database_configured?) { base_models_for_backup.one? }
|
||||
let(:backup_options) { Backup::Options.new }
|
||||
let(:force) { true }
|
||||
let(:backup_options) { Backup::Options.new(force: force) }
|
||||
let(:timeout_service) do
|
||||
instance_double(Gitlab::Database::TransactionTimeoutSettings, restore_timeouts: nil, disable_timeouts: nil)
|
||||
end
|
||||
|
@ -27,9 +28,7 @@ RSpec.describe Backup::Targets::Database, :reestablished_active_record_base, fea
|
|||
end
|
||||
|
||||
describe '#dump', :delete do
|
||||
let(:force) { true }
|
||||
|
||||
subject(:databases) { described_class.new(progress, force: force, options: backup_options) }
|
||||
subject(:databases) { described_class.new(progress, options: backup_options) }
|
||||
|
||||
it 'creates gzipped database dumps' do
|
||||
Dir.mktmpdir do |dir|
|
||||
|
@ -171,10 +170,9 @@ RSpec.describe Backup::Targets::Database, :reestablished_active_record_base, fea
|
|||
describe '#restore' do
|
||||
let(:cmd) { %W[#{Gem.ruby} -e $stdout.puts(1)] }
|
||||
let(:backup_dir) { Rails.root.join("spec/fixtures/") }
|
||||
let(:force) { true }
|
||||
let(:rake_task) { instance_double(Rake::Task, invoke: true) }
|
||||
|
||||
subject(:databases) { described_class.new(progress, force: force, options: backup_options) }
|
||||
subject(:databases) { described_class.new(progress, options: backup_options) }
|
||||
|
||||
before do
|
||||
allow(Rake::Task).to receive(:[]).with(any_args).and_return(rake_task)
|
||||
|
@ -198,10 +196,6 @@ RSpec.describe Backup::Targets::Database, :reestablished_active_record_base, fea
|
|||
|
||||
expect(progress_output).to include('Removing all tables. Press `Ctrl-C` within 5 seconds to abort')
|
||||
end
|
||||
|
||||
it 'has a pre restore warning' do
|
||||
expect(databases.pre_restore_warning).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an empty .gz file' do
|
||||
|
@ -253,7 +247,7 @@ RSpec.describe Backup::Targets::Database, :reestablished_active_record_base, fea
|
|||
let(:noise) { "must be owner of extension pg_trgm\nWARNING: no privileges could be revoked for public\n" }
|
||||
let(:cmd) { %W[#{Gem.ruby} -e $stderr.write("#{noise}#{visible_error}")] }
|
||||
|
||||
it 'filters out noise from errors and has a post restore warning' do
|
||||
it 'filters out noise from errors and store in errors attribute' do
|
||||
if one_database_configured?
|
||||
expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
|
||||
else
|
||||
|
@ -265,7 +259,7 @@ RSpec.describe Backup::Targets::Database, :reestablished_active_record_base, fea
|
|||
expect(progress_output).to include("ERRORS")
|
||||
expect(progress_output).not_to include(noise)
|
||||
expect(progress_output).to include(visible_error)
|
||||
expect(databases.post_restore_warning).not_to be_nil
|
||||
expect(databases.errors).not_to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Backup::Tasks::Database, feature_category: :backup_restore do
|
||||
let(:progress) { StringIO.new }
|
||||
let(:options) { Backup::Options.new }
|
||||
|
||||
subject(:task) { described_class.new(progress: progress, options: options) }
|
||||
|
||||
describe '#pre_restore_warning' do
|
||||
context 'when force is false' do
|
||||
let(:options) { Backup::Options.new(force: false) }
|
||||
|
||||
it 'returns a warning message' do
|
||||
expect(task.pre_restore_warning).to start_with('Be sure to stop Puma, Sidekiq, and any other process')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when force_is true' do
|
||||
let(:options) { Backup::Options.new(force: true) }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(task.pre_restore_warning).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#post_restore_warning' do
|
||||
context 'when restore finished with errors' do
|
||||
it 'returns a warning message' do
|
||||
mocked_target = instance_double(Backup::Targets::Database, errors: ['some errors'])
|
||||
allow(task).to receive(:target).and_return(mocked_target)
|
||||
|
||||
expect(task.post_restore_warning).to start_with('There were errors in restoring the schema.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when restore finished without any error' do
|
||||
it 'returns nil' do
|
||||
expect(task.post_restore_warning).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Backup::Tasks::Task, feature_category: :backup_restore do
|
||||
let(:progress) { StringIO.new }
|
||||
let(:options) { create(:backup_options) }
|
||||
|
||||
subject(:task) { described_class.new(progress: progress, options: options) }
|
||||
|
||||
context 'with unimplemented methods' do
|
||||
describe '.id' do
|
||||
it 'raises an error' do
|
||||
expect { described_class.id }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#id' do
|
||||
it 'raises an error' do
|
||||
expect { task.id }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#human_name' do
|
||||
it 'raises an error' do
|
||||
expect { task.human_name }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destination_path' do
|
||||
it 'raises an error' do
|
||||
expect { task.destination_path }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#target' do
|
||||
it 'raises an error' do
|
||||
expect { task.send(:target) }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -365,8 +365,9 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana
|
|||
let(:app_id) { 'foobar' }
|
||||
let(:url) { 'http://localhost:4000' }
|
||||
let(:sdk_client) { instance_double('GitlabSDK::Client') }
|
||||
let(:event_kwargs) { { user: user, project: project } }
|
||||
let(:event_kwargs) { { user: user, project: project, send_snowplow_event: send_snowplow_event } }
|
||||
let(:additional_properties) { {} }
|
||||
let(:send_snowplow_event) { true }
|
||||
|
||||
before do
|
||||
described_class.clear_memoization(:gitlab_sdk_client)
|
||||
|
@ -441,6 +442,12 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana
|
|||
|
||||
it_behaves_like 'does not send a Product Analytics event'
|
||||
end
|
||||
|
||||
context 'when send_snowplow_event is false' do
|
||||
let(:send_snowplow_event) { false }
|
||||
|
||||
it_behaves_like 'does not send a Product Analytics event'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when internal_events_for_product_analytics FF is disabled' do
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue