Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-03-06 18:10:52 +00:00
parent 96dfc10639
commit ebfc70c3df
107 changed files with 747 additions and 356 deletions

View File

@ -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:

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -35,6 +35,7 @@ query getPipelineHeaderData($fullPath: ID!, $iid: ID!) {
}
commit {
id
sha
shortId
title
webPath

View File

@ -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">

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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" />

View File

@ -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();
}
}

View File

@ -3,4 +3,4 @@ import { runModules } from '~/run_modules';
const modules = import.meta.glob('../pages/**/index.js');
runModules(modules, '../pages/');
runModules(modules, 'CE');

View File

@ -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');

View File

@ -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');

View File

@ -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,

View File

@ -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',

View File

@ -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);
});
};

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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. |

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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.

View File

@ -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:

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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' -->

View File

@ -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

View File

@ -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).

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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).

View File

@ -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:

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:)

View File

@ -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 ""

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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', () => {

View File

@ -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,
});
});
});

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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