Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7d8fc3b6b6
commit
94a2edbe79
|
|
@ -1 +1 @@
|
|||
c832720d9ad3948e6cf2c371f01c85e9dd9a3a5a
|
||||
6802e80668002eb7ff70987129c290344ace02dd
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
<script>
|
||||
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
|
||||
import { GlCollapsibleListbox } from '@gitlab/ui';
|
||||
import { mapActions, mapState } from 'vuex';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
import Tracking from '~/tracking';
|
||||
import { BOARD_CARD_MOVE_TO_POSITION_OPTIONS, MOVE_TO_START } from '../constants';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
moveToStartText: s__('Boards|Move to start of list'),
|
||||
moveToEndText: s__('Boards|Move to end of list'),
|
||||
},
|
||||
BOARD_CARD_MOVE_TO_POSITION_OPTIONS,
|
||||
name: 'BoardCardMoveToPosition',
|
||||
components: {
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlCollapsibleListbox,
|
||||
},
|
||||
mixins: [Tracking.mixin()],
|
||||
props: {
|
||||
|
|
@ -96,30 +91,30 @@ export default {
|
|||
allItemsLoadedInList: !this.listHasNextPage,
|
||||
});
|
||||
},
|
||||
selectMoveAction(action) {
|
||||
if (action === MOVE_TO_START) {
|
||||
this.moveToStart();
|
||||
} else {
|
||||
this.moveToEnd();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-dropdown
|
||||
<gl-collapsible-listbox
|
||||
ref="dropdown"
|
||||
:key="itemIdentifier"
|
||||
icon="ellipsis_v"
|
||||
:text="s__('Boards|Move card')"
|
||||
:text-sr-only="true"
|
||||
class="move-to-position gl-display-block gl-mb-2 gl-ml-2 gl-mt-n3 gl-mr-n3"
|
||||
category="tertiary"
|
||||
:tabindex="index"
|
||||
class="move-to-position gl-display-block gl-mb-2 gl-ml-2 gl-mt-n3 gl-mr-n3 js-no-trigger"
|
||||
icon="ellipsis_v"
|
||||
:items="$options.BOARD_CARD_MOVE_TO_POSITION_OPTIONS"
|
||||
no-caret
|
||||
:tabindex="index"
|
||||
:text-sr-only="true"
|
||||
:toggle-text="s__('Boards|Move card')"
|
||||
@keydown.esc.native="$emit('hide')"
|
||||
>
|
||||
<div>
|
||||
<gl-dropdown-item @click.stop="moveToStart">
|
||||
{{ $options.i18n.moveToStartText }}
|
||||
</gl-dropdown-item>
|
||||
<gl-dropdown-item @click.stop="moveToEnd">
|
||||
{{ $options.i18n.moveToEndText }}
|
||||
</gl-dropdown-item>
|
||||
</div>
|
||||
</gl-dropdown>
|
||||
@select="selectMoveAction"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
|
||||
import { __ } from '~/locale';
|
||||
import { s__, __ } from '~/locale';
|
||||
import updateEpicSubscriptionMutation from '~/sidebar/queries/update_epic_subscription.mutation.graphql';
|
||||
import updateEpicTitleMutation from '~/sidebar/queries/update_epic_title.mutation.graphql';
|
||||
import destroyBoardListMutation from './graphql/board_list_destroy.mutation.graphql';
|
||||
|
|
@ -141,3 +141,16 @@ export default {
|
|||
};
|
||||
|
||||
export const DEFAULT_BOARD_LIST_ITEMS_SIZE = 10;
|
||||
|
||||
export const MOVE_TO_START = 'moveToStart';
|
||||
export const MOVE_TO_END = 'moveToEnd';
|
||||
export const BOARD_CARD_MOVE_TO_POSITION_OPTIONS = [
|
||||
{
|
||||
text: s__('Boards|Move to start of list'),
|
||||
value: MOVE_TO_START,
|
||||
},
|
||||
{
|
||||
text: s__('Boards|Move to end of list'),
|
||||
value: MOVE_TO_END,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -363,6 +363,10 @@ class Deployment < ApplicationRecord
|
|||
deployable&.user || user
|
||||
end
|
||||
|
||||
def triggered_by?(user)
|
||||
deployed_by == user
|
||||
end
|
||||
|
||||
def link_merge_requests(relation)
|
||||
# NOTE: relation.select will perform column deduplication,
|
||||
# when id == environment_id it will outputs 2 columns instead of 3
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ReadonlyAbilities
|
||||
module ArchivedAbilities
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
READONLY_ABILITIES = %i[
|
||||
ARCHIVED_ABILITIES = %i[
|
||||
admin_tag
|
||||
push_code
|
||||
push_to_delete_protected_branch
|
||||
|
|
@ -16,7 +16,7 @@ module ReadonlyAbilities
|
|||
create_incident
|
||||
].freeze
|
||||
|
||||
READONLY_FEATURES = %i[
|
||||
ARCHIVED_FEATURES = %i[
|
||||
issue
|
||||
issue_board_list
|
||||
merge_request
|
||||
|
|
@ -40,14 +40,14 @@ module ReadonlyAbilities
|
|||
].freeze
|
||||
|
||||
class_methods do
|
||||
def readonly_abilities
|
||||
READONLY_ABILITIES
|
||||
def archived_abilities
|
||||
ARCHIVED_ABILITIES
|
||||
end
|
||||
|
||||
def readonly_features
|
||||
READONLY_FEATURES
|
||||
def archived_features
|
||||
ARCHIVED_FEATURES
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ReadonlyAbilities::ClassMethods.prepend_mod_with('ReadonlyAbilities::ClassMethods')
|
||||
ArchivedAbilities::ClassMethods.prepend_mod_with('ArchivedAbilities::ClassMethods')
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class ProjectPolicy < BasePolicy
|
||||
include CrudPolicyHelpers
|
||||
include ReadonlyAbilities
|
||||
include ArchivedAbilities
|
||||
|
||||
desc "Project has public builds enabled"
|
||||
condition(:public_builds, scope: :subject, score: 0) { project.public_builds? }
|
||||
|
|
@ -552,15 +552,15 @@ class ProjectPolicy < BasePolicy
|
|||
rule { can?(:push_code) }.enable :admin_tag
|
||||
|
||||
rule { archived }.policy do
|
||||
prevent(*readonly_abilities)
|
||||
prevent(*archived_abilities)
|
||||
|
||||
readonly_features.each do |feature|
|
||||
archived_features.each do |feature|
|
||||
prevent(*create_update_admin(feature))
|
||||
end
|
||||
end
|
||||
|
||||
rule { archived & ~pending_delete }.policy do
|
||||
readonly_features.each do |feature|
|
||||
archived_features.each do |feature|
|
||||
prevent(:"destroy_#{feature}")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/368279
|
|||
milestone: '15.3'
|
||||
type: development
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
announcement_milestone: "15.5" # (required) The milestone when this feature was first announced as deprecated.
|
||||
announcement_date: "2022-10-22" # (required) The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
|
||||
removal_milestone: "15.7" # (required) The milestone when this feature is planned to be removed
|
||||
removal_date: # (required) The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
|
||||
removal_date: "2022-12-22" # (required) The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
|
||||
breaking_change: true # (required) If this deprecation is a breaking change, set this value to true
|
||||
reporter: DarrenEastman # (required) GitLab username of the person reporting the deprecation
|
||||
stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: alerts_service_data
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16607
|
||||
milestone: '12.3'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53534
|
||||
removed_in_milestone: '13.9'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: analytics_devops_adoption_segment_selections
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45748
|
||||
milestone: '13.6'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62594
|
||||
removed_in_milestone: '14.0'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: analytics_repository_file_commits
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17277
|
||||
milestone: '12.4'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23590
|
||||
removed_in_milestone: '12.8'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: analytics_repository_file_edits
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17277
|
||||
milestone: '12.4'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24222
|
||||
removed_in_milestone: '12.8'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: analytics_repository_files
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23590
|
||||
removed_in_milestone: '12.8'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: audit_events_archived
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44655
|
||||
milestone: '13.6'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53880
|
||||
removed_in_milestone: '13.11'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: audit_events_part_5fc467ac26
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36298
|
||||
milestone: '13.3'
|
||||
removed_by_url: TODO
|
||||
removed_in_milestone: TODO
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: backup_labels
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54856
|
||||
removed_in_milestone: '13.10'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: ci_build_trace_section_names
|
||||
gitlab_schema: gitlab_ci
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67618
|
||||
milestone: '14.2'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73841
|
||||
removed_in_milestone: '14.5'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: ci_build_trace_sections
|
||||
gitlab_schema: gitlab_ci
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_in_milestone: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73841
|
||||
removed_by_url: '14.5'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: ci_daily_report_results
|
||||
gitlab_schema: gitlab_ci
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36102
|
||||
removed_in_milestone: '13.2'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: ci_test_case_failures
|
||||
gitlab_schema: gitlab_ci
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67180
|
||||
removed_in_milestone: '14.2'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: ci_test_cases
|
||||
gitlab_schema: gitlab_ci
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45027
|
||||
milestone: '13.6'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67180
|
||||
removed_in_milestone: '14.2'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: clusters_applications_fluentd
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28844
|
||||
milestone: '12.10'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63758
|
||||
removed_in_milestone: '14.1'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: forked_project_links
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20771
|
||||
removed_in_milestone: '12.9'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: issue_milestones
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25198
|
||||
removed_in_milestone: '12.8'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: merge_request_milestones
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22043
|
||||
milestone: '12.7'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25198
|
||||
removed_in_milestone: '12.8'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: namespace_onboarding_actions
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48018
|
||||
milestone: '13.7'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53488
|
||||
removed_in_milestone: '13.9'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: services
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64562
|
||||
removed_in_milestone: '14.1'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: terraform_state_registry
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36594
|
||||
milestone: '13.3'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43341
|
||||
removed_in_milestone: '13.5'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: tmp_fingerprint_sha256_migration
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21579
|
||||
milestone: '12.7'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21579
|
||||
removed_in_milestone: '12.7'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: vulnerability_export_registry
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36620
|
||||
milestone: '13.3'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38299
|
||||
removed_in_milestone: '13.3'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: vulnerability_export_verification_status
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36620
|
||||
milestone: '13.3'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38299
|
||||
removed_in_milestone: '13.3'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: vulnerability_finding_fingerprints
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: TODO
|
||||
milestone: TODO
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57840
|
||||
removed_in_milestone: '13.11'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: web_hook_logs_archived
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60184
|
||||
milestone: '13.12'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63649
|
||||
removed_in_milestone: '14.0'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: web_hook_logs_part_0c5294f417
|
||||
gitlab_schema: gitlab_main
|
||||
feature_categories: []
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55938
|
||||
milestone: '13.10'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60184
|
||||
removed_in_milestone: '13.12'
|
||||
|
|
@ -411,7 +411,7 @@ the following are true:
|
|||
If all the above are true and the users are still not getting access,
|
||||
[run a manual group sync](#sync-all-groups) in the rails console and
|
||||
[look through the output](#example-console-output-after-a-group-sync) to see what happens when
|
||||
GitLab syncs the `admin_group`.
|
||||
GitLab syncs the `admin_group`.
|
||||
|
||||
#### Sync now button stuck in the UI
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
|
|||
`127.0.0.1/32` to the `postgresql['md5_auth_cidr_addresses']` setting, to allow Rails to connect through
|
||||
`127.0.0.1`. For more information, see [omnibus-5258](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5258).
|
||||
|
||||
Depending on your network configuration, the suggested addresses may
|
||||
Depending on your network configuration, the suggested addresses may
|
||||
be incorrect. If your **primary** site and **secondary** sites connect over a local
|
||||
area network, or a virtual network connecting availability zones like
|
||||
[Amazon's VPC](https://aws.amazon.com/vpc/) or [Google's VPC](https://cloud.google.com/vpc/),
|
||||
|
|
@ -509,7 +509,7 @@ data before running `pg_basebackup`.
|
|||
(for example, you know the network path is secure, or you are using a site-to-site
|
||||
VPN). It is **not** safe over the public Internet!
|
||||
- You can read more details about each `sslmode` in the
|
||||
[PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-ssl.html#LIBPQ-SSL-PROTECTION).
|
||||
[PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-ssl.html#LIBPQ-SSL-PROTECTION).
|
||||
The instructions above are carefully written to ensure protection against
|
||||
both passive eavesdroppers and active "man-in-the-middle" attackers.
|
||||
- Change the `--slot-name` to the name of the replication slot
|
||||
|
|
|
|||
|
|
@ -585,6 +585,38 @@ you can pull from the Container Registry, but you cannot push.
|
|||
1. Configure your registry to [use the S3 bucket for storage](#use-object-storage).
|
||||
1. For the changes to take effect, set the Registry back to `read-write` mode and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
|
||||
|
||||
#### Moving to Azure Object Storage
|
||||
|
||||
When moving from an existing file system or another object storage provider to Azure Object Storage, you must configure the registry to use the standard root directory.
|
||||
This configuration is done by setting [`trimlegacyrootprefix: true]`](https://gitlab.com/gitlab-org/container-registry/-/blob/a3f64464c3ec1c5a599c0a2daa99ebcbc0100b9a/docs-gitlab/README.md#azure-storage-driver) in the Azure storage driver section of the registry configuration.
|
||||
Without this configuration, the Azure storage driver uses `//` instead of `/` as the first section of the root path, rendering the migrated images inaccessible.
|
||||
|
||||
**Omnibus GitLab installations**
|
||||
|
||||
```ruby
|
||||
registry['storage'] = {
|
||||
'azure' => {
|
||||
'accountname' => 'accountname',
|
||||
'accesskey' => 'base64encodedaccountkey',
|
||||
'container' => 'containername',
|
||||
'rootdirectory' => '/azure/virtual/container',
|
||||
'trimlegacyrootprefix' => 'true'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Installations from source**
|
||||
|
||||
```yaml
|
||||
storage:
|
||||
azure:
|
||||
accountname: accountname
|
||||
accountkey: base64encodedaccountkey
|
||||
container: containername
|
||||
rootdirectory: /azure/virtual/container
|
||||
trimlegacyrootprefix: true
|
||||
```
|
||||
|
||||
### Disable redirect for storage driver
|
||||
|
||||
By default, users accessing a registry configured with a remote backend are redirected to the default backend for the storage driver. For example, registries can be configured using the `s3` storage driver, which redirects requests to a remote S3 bucket to alleviate load on the GitLab server.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ In GitLab 14.8 and earlier, projects in personal namespaces have an `access_leve
|
|||
|
||||
The `group_saml_identity` attribute is only visible to a group owner for [SSO enabled groups](../user/group/saml_sso/index.md).
|
||||
|
||||
The `email` attribute is only visible for users with public emails.
|
||||
The `email` attribute is only visible to group owners when the user was provisioned by the group.
|
||||
Users are provisioned by the group when the account was created via [SCIM](../user/group/saml_sso/scim_setup.md) or by first sign-in with [SAML SSO for GitLab.com groups](../user/group/saml_sso/index.md).
|
||||
|
||||
## List all members of a group or project
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ build:
|
|||
script: ls -al
|
||||
```
|
||||
|
||||
This YAML setting configures a custom clone path. This path makes it possible to re-use worktrees
|
||||
This YAML setting configures a custom clone path. This path makes it possible to re-use worktrees
|
||||
between the parent project and forks because we use the same clone path for all forks.
|
||||
|
||||
Why use `$CI_CONCURRENT_ID`? The main reason is to ensure that worktrees used are not conflicting
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ See also:
|
|||
|
||||
- [Exposing Global IDs](#exposing-global-ids).
|
||||
- [Mutation arguments](#object-identifier-arguments).
|
||||
- [Deprecating Global IDs](#deprecate-global-ids).
|
||||
- [Deprecating Global IDs](#deprecate-global-ids).
|
||||
|
||||
We have a custom scalar type (`Types::GlobalIDType`) which should be used as the
|
||||
type of input and output arguments when the value is a `GlobalID`. The benefits
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ It's recommended to create two separate migration script files.
|
|||
desired limit using `create_or_update_plan_limit` migration helper, such as:
|
||||
|
||||
```ruby
|
||||
class InsertProjectHooksPlanLimits < Gitlab::Database::Migration[2.0]
|
||||
class InsertProjectHooksPlanLimits < Gitlab::Database::Migration[2.1]
|
||||
def up
|
||||
create_or_update_plan_limit('project_hooks', 'default', 0)
|
||||
create_or_update_plan_limit('project_hooks', 'free', 10)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ Settings are not cascading by default. To define a cascading setting, take the f
|
|||
`application_settings`.
|
||||
|
||||
```ruby
|
||||
class AddDelayedProjectRemovalCascadingSetting < Gitlab::Database::Migration[2.0]
|
||||
class AddDelayedProjectRemovalCascadingSetting < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::CascadingNamespaceSettings
|
||||
|
||||
enable_lock_retries!
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ In the example above, you'd be still able to update records in the `emails` tabl
|
|||
Migration file for adding `NOT VALID` foreign key:
|
||||
|
||||
```ruby
|
||||
class AddNotValidForeignKeyToEmailsUser < Gitlab::Database::Migration[2.0]
|
||||
class AddNotValidForeignKeyToEmailsUser < Gitlab::Database::Migration[2.1]
|
||||
def up
|
||||
add_concurrent_foreign_key :emails, :users, column: :user_id, on_delete: :cascade, validate: false
|
||||
end
|
||||
|
|
@ -100,7 +100,7 @@ In case the data volume is higher (>1000 records), it's better to create a backg
|
|||
Example for cleaning up records in the `emails` table in a database migration:
|
||||
|
||||
```ruby
|
||||
class RemoveRecordsWithoutUserFromEmailsTable < Gitlab::Database::Migration[2.0]
|
||||
class RemoveRecordsWithoutUserFromEmailsTable < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
class Email < ActiveRecord::Base
|
||||
|
|
@ -133,7 +133,7 @@ Migration file for validating the foreign key:
|
|||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ValidateForeignKeyOnEmailUsers < Gitlab::Database::Migration[2.0]
|
||||
class ValidateForeignKeyOnEmailUsers < Gitlab::Database::Migration[2.1]
|
||||
def up
|
||||
validate_foreign_key :emails, :user_id
|
||||
end
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ A Rails migration example:
|
|||
```ruby
|
||||
# in db/post_migrate/
|
||||
|
||||
class AddIndexToPartitionedTable < Gitlab::Database::Migration[2.0]
|
||||
class AddIndexToPartitionedTable < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ to write a migration that removes a column:
|
|||
In this case, a **transactional migration** can be used. Something as simple as:
|
||||
|
||||
```ruby
|
||||
class RemoveUsersUpdatedAtColumn < Gitlab::Database::Migration[2.0]
|
||||
class RemoveUsersUpdatedAtColumn < Gitlab::Database::Migration[2.1]
|
||||
def up
|
||||
remove_column :users, :updated_at
|
||||
end
|
||||
|
|
@ -103,7 +103,7 @@ If the `down` method requires adding back any dropped indexes or constraints, th
|
|||
be done within a transactional migration, then the migration would look like this:
|
||||
|
||||
```ruby
|
||||
class RemoveUsersUpdatedAtColumn < Gitlab::Database::Migration[2.0]
|
||||
class RemoveUsersUpdatedAtColumn < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -158,7 +158,7 @@ renaming. For example
|
|||
|
||||
```ruby
|
||||
# A regular migration in db/migrate
|
||||
class RenameUsersUpdatedAtToUpdatedAtTimestamp < Gitlab::Database::Migration[2.0]
|
||||
class RenameUsersUpdatedAtToUpdatedAtTimestamp < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -186,7 +186,7 @@ We can perform this cleanup using
|
|||
|
||||
```ruby
|
||||
# A post-deployment migration in db/post_migrate
|
||||
class CleanupUsersUpdatedAtRename < Gitlab::Database::Migration[2.0]
|
||||
class CleanupUsersUpdatedAtRename < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -233,7 +233,7 @@ as follows:
|
|||
|
||||
```ruby
|
||||
# A regular migration in db/migrate
|
||||
class ChangeUsersUsernameStringToText < Gitlab::Database::Migration[2.0]
|
||||
class ChangeUsersUsernameStringToText < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -252,7 +252,7 @@ Next we need to clean up our changes using a post-deployment migration:
|
|||
|
||||
```ruby
|
||||
# A post-deployment migration in db/post_migrate
|
||||
class ChangeUsersUsernameStringToTextCleanup < Gitlab::Database::Migration[2.0]
|
||||
class ChangeUsersUsernameStringToTextCleanup < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ Next we need a post-deployment migration that schedules the migration for
|
|||
existing data.
|
||||
|
||||
```ruby
|
||||
class ScheduleExtractIntegrationsUrl < Gitlab::Database::Migration[2.0]
|
||||
class ScheduleExtractIntegrationsUrl < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
MIGRATION = 'ExtractIntegrationsUrl'
|
||||
|
|
@ -263,7 +263,7 @@ jobs and manually run on any un-migrated rows. Such a migration would look like
|
|||
this:
|
||||
|
||||
```ruby
|
||||
class ConsumeRemainingExtractIntegrationsUrlJobs < Gitlab::Database::Migration[2.0]
|
||||
class ConsumeRemainingExtractIntegrationsUrlJobs < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ In the second (filtered) example, we know exactly 100 will be updated with each
|
|||
1. In the post-deployment migration, enqueue the batched background migration:
|
||||
|
||||
```ruby
|
||||
class BackfillNamespaceType < Gitlab::Database::Migration[2.0]
|
||||
class BackfillNamespaceType < Gitlab::Database::Migration[2.1]
|
||||
MIGRATION = 'BackfillNamespaceType'
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ background migration.
|
|||
1. Create a post-deployment migration that queues the migration for existing data:
|
||||
|
||||
```ruby
|
||||
class QueueBackfillRoutesNamespaceId < Gitlab::Database::Migration[2.0]
|
||||
class QueueBackfillRoutesNamespaceId < Gitlab::Database::Migration[2.1]
|
||||
MIGRATION = 'BackfillRouteNamespaceId'
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
|
||||
|
|
@ -403,7 +403,7 @@ background migration.
|
|||
that checks that the batched background migration is completed. For example:
|
||||
|
||||
```ruby
|
||||
class FinalizeBackfillRouteNamespaceId < Gitlab::Database::Migration[2.0]
|
||||
class FinalizeBackfillRouteNamespaceId < Gitlab::Database::Migration[2.1]
|
||||
MIGRATION = 'BackfillRouteNamespaceId'
|
||||
disable_ddl_transaction!
|
||||
|
||||
|
|
@ -452,7 +452,7 @@ the batching column.
|
|||
Database post-migration:
|
||||
|
||||
```ruby
|
||||
class ProjectsWithIssuesMigration < Gitlab::Database::Migration[2.0]
|
||||
class ProjectsWithIssuesMigration < Gitlab::Database::Migration[2.1]
|
||||
MIGRATION = 'BatchProjectsWithIssues'
|
||||
INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 5000
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ To replace a foreign key:
|
|||
foreign key before removing the old one.
|
||||
|
||||
```ruby
|
||||
class ReplaceFkOnPackagesPackagesProjectId < Gitlab::Database::Migration[2.0]
|
||||
class ReplaceFkOnPackagesPackagesProjectId < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
NEW_CONSTRAINT_NAME = 'fk_new'
|
||||
|
|
@ -69,7 +69,7 @@ To replace a foreign key:
|
|||
1. [Validate the new foreign key](add_foreign_key_to_existing_column.md#validate-the-foreign-key)
|
||||
|
||||
```ruby
|
||||
class ValidateFkNew < Gitlab::Database::Migration[2.0]
|
||||
class ValidateFkNew < Gitlab::Database::Migration[2.1]
|
||||
NEW_CONSTRAINT_NAME = 'fk_new'
|
||||
|
||||
# foreign key added in <link to MR or path to migration adding new FK>
|
||||
|
|
@ -86,7 +86,7 @@ To replace a foreign key:
|
|||
1. Remove the old foreign key:
|
||||
|
||||
```ruby
|
||||
class RemoveFkOld < Gitlab::Database::Migration[2.0]
|
||||
class RemoveFkOld < Gitlab::Database::Migration[2.1]
|
||||
OLD_CONSTRAINT_NAME = 'fk_old'
|
||||
|
||||
# new foreign key added in <link to MR or path to migration adding new FK>
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ trigger needs to be configured only once. If the model already has at least one
|
|||
`loose_foreign_key` definition, then this step can be skipped:
|
||||
|
||||
```ruby
|
||||
class TrackProjectRecordChanges < Gitlab::Database::Migration[2.0]
|
||||
class TrackProjectRecordChanges < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
|
||||
|
||||
enable_lock_retries!
|
||||
|
|
@ -227,7 +227,7 @@ trigger. If the foreign key is deleted earlier, there is a good chance of
|
|||
introducing data inconsistency which needs manual cleanup:
|
||||
|
||||
```ruby
|
||||
class RemoveProjectsCiPipelineFk < Gitlab::Database::Migration[2.0]
|
||||
class RemoveProjectsCiPipelineFk < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -258,7 +258,7 @@ records in the database.
|
|||
Migration for removing the trigger:
|
||||
|
||||
```ruby
|
||||
class UnTrackProjectRecordChanges < Gitlab::Database::Migration[2.0]
|
||||
class UnTrackProjectRecordChanges < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
|
||||
|
||||
enable_lock_retries!
|
||||
|
|
@ -278,7 +278,7 @@ table however, there is still a chance for having leftover pending records in th
|
|||
must be removed with an inline data migration.
|
||||
|
||||
```ruby
|
||||
class RemoveLeftoverProjectDeletions < Gitlab::Database::Migration[2.0]
|
||||
class RemoveLeftoverProjectDeletions < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Example migration adding a concurrent index that is treated as change of the str
|
|||
that is executed on all configured databases.
|
||||
|
||||
```ruby
|
||||
class AddUserIdAndStateIndexToMergeRequestReviewers < Gitlab::Database::Migration[2.0]
|
||||
class AddUserIdAndStateIndexToMergeRequestReviewers < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_on_merge_request_reviewers_user_id_and_state'
|
||||
|
|
@ -84,7 +84,7 @@ end
|
|||
1. Create the table in a schema migration:
|
||||
|
||||
```ruby
|
||||
class CreateSshSignatures < Gitlab::Database::Migration[2.0]
|
||||
class CreateSshSignatures < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
create_table :ssh_signatures do |t|
|
||||
t.timestamps_with_timezone null: false
|
||||
|
|
@ -125,7 +125,7 @@ Example migration updating `archived` column of `projects` that is executed
|
|||
only for the database containing `gitlab_main` schema.
|
||||
|
||||
```ruby
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.0]
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
|
@ -157,7 +157,7 @@ databases. For example, running migration in context of `ci:` and reading featur
|
|||
from `main:`, as no established connection to another database is present.
|
||||
|
||||
```ruby
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.0]
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
|
@ -195,7 +195,7 @@ that is marked in `lib/gitlab/database/gitlab_schemas.yml` as `gitlab_shared`.
|
|||
This migration is executed across all configured databases.
|
||||
|
||||
```ruby
|
||||
class DeleteAllLooseForeignKeyRecords < Gitlab::Database::Migration[2.0]
|
||||
class DeleteAllLooseForeignKeyRecords < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -217,7 +217,7 @@ This migration since it configures restriction on `gitlab_ci` is executed only
|
|||
in context of database containing `gitlab_ci` schema.
|
||||
|
||||
```ruby
|
||||
class DeleteCiBuildsLooseForeignKeyRecords < Gitlab::Database::Migration[2.0]
|
||||
class DeleteCiBuildsLooseForeignKeyRecords < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_ci
|
||||
|
|
@ -279,7 +279,7 @@ as part of the migration run and prevent the migration from being completed.
|
|||
### Exception 1: migration running in DDL mode does DML select
|
||||
|
||||
```ruby
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.0]
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
# Missing:
|
||||
|
|
@ -310,7 +310,7 @@ running in **DDL** mode, but the executed payload appears to be reading data fro
|
|||
### Exception 2: migration running in DML mode changes the structure
|
||||
|
||||
```ruby
|
||||
class AddUserIdAndStateIndexToMergeRequestReviewers < Gitlab::Database::Migration[2.0]
|
||||
class AddUserIdAndStateIndexToMergeRequestReviewers < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
# restrict_gitlab_migration if defined indicates DML, it should be removed
|
||||
|
|
@ -341,7 +341,7 @@ but the executed payload appears to be doing structure changes (DDL).
|
|||
### Exception 3: migration running in DML mode accesses data from a table in another schema
|
||||
|
||||
```ruby
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.0]
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
# Since it modifies `projects` it should use `gitlab_main`
|
||||
|
|
@ -372,7 +372,7 @@ data in `gitlab_main`.
|
|||
### Exception 4: mixing DDL and DML mode
|
||||
|
||||
```ruby
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.0]
|
||||
class UpdateProjectsArchivedState < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
# This migration is invalid regardless of specification
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ For example, consider a migration that creates a table with two `NOT NULL` colum
|
|||
`db/migrate/20200401000001_create_db_guides.rb`:
|
||||
|
||||
```ruby
|
||||
class CreateDbGuides < Gitlab::Database::Migration[2.0]
|
||||
class CreateDbGuides < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
create_table :db_guides do |t|
|
||||
t.bigint :stars, default: 0, null: false
|
||||
|
|
@ -44,7 +44,7 @@ For example, consider a migration that adds a new `NOT NULL` column `active` to
|
|||
`db/migrate/20200501000001_add_active_to_db_guides.rb`:
|
||||
|
||||
```ruby
|
||||
class AddExtendedTitleToSprints < Gitlab::Database::Migration[2.0]
|
||||
class AddExtendedTitleToSprints < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
add_column :db_guides, :active, :boolean, default: true, null: false
|
||||
end
|
||||
|
|
@ -116,7 +116,7 @@ with `validate: false` in a post-deployment migration,
|
|||
`db/post_migrate/20200501000001_add_not_null_constraint_to_epics_description.rb`:
|
||||
|
||||
```ruby
|
||||
class AddNotNullConstraintToEpicsDescription < Gitlab::Database::Migration[2.0]
|
||||
class AddNotNullConstraintToEpicsDescription < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -147,7 +147,7 @@ so we add a post-deployment migration for the 13.0 milestone (current),
|
|||
`db/post_migrate/20200501000002_cleanup_epics_with_null_description.rb`:
|
||||
|
||||
```ruby
|
||||
class CleanupEpicsWithNullDescription < Gitlab::Database::Migration[2.0]
|
||||
class CleanupEpicsWithNullDescription < Gitlab::Database::Migration[2.1]
|
||||
# With BATCH_SIZE=1000 and epics.count=29500 on GitLab.com
|
||||
# - 30 iterations will be run
|
||||
# - each requires on average ~150ms
|
||||
|
|
@ -185,7 +185,7 @@ migration helper in a final post-deployment migration,
|
|||
`db/post_migrate/20200601000001_validate_not_null_constraint_on_epics_description.rb`:
|
||||
|
||||
```ruby
|
||||
class ValidateNotNullConstraintOnEpicsDescription < Gitlab::Database::Migration[2.0]
|
||||
class ValidateNotNullConstraintOnEpicsDescription < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ could result in loading unexpected code or associations which may cause unintend
|
|||
side effects or failures during upgrades.
|
||||
|
||||
```ruby
|
||||
class SomeMigration < Gitlab::Database::Migration[2.0]
|
||||
class SomeMigration < Gitlab::Database::Migration[2.1]
|
||||
class Services < MigrationRecord
|
||||
self.table_name = 'services'
|
||||
self.inheritance_column = :_type_disabled
|
||||
|
|
@ -47,7 +47,7 @@ This ensures that the migration loads the columns for the migration in isolation
|
|||
and the helper disables STI by default.
|
||||
|
||||
```ruby
|
||||
class EnqueueSomeBackgroundMigration < Gitlab::Database::Migration[2.0]
|
||||
class EnqueueSomeBackgroundMigration < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ For example, consider a migration that creates a table with two text columns,
|
|||
`db/migrate/20200401000001_create_db_guides.rb`:
|
||||
|
||||
```ruby
|
||||
class CreateDbGuides < Gitlab::Database::Migration[2.0]
|
||||
class CreateDbGuides < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
create_table :db_guides do |t|
|
||||
t.bigint :stars, default: 0, null: false
|
||||
|
|
@ -74,7 +74,7 @@ For example, consider a migration that adds a new text column `extended_title` t
|
|||
`db/migrate/20200501000001_add_extended_title_to_sprints.rb`:
|
||||
|
||||
```ruby
|
||||
class AddExtendedTitleToSprints < Gitlab::Database::Migration[2.0]
|
||||
class AddExtendedTitleToSprints < Gitlab::Database::Migration[2.1]
|
||||
|
||||
# rubocop:disable Migration/AddLimitToTextColumns
|
||||
# limit is added in 20200501000002_add_text_limit_to_sprints_extended_title
|
||||
|
|
@ -89,7 +89,7 @@ A second migration should follow the first one with a limit added to `extended_t
|
|||
`db/migrate/20200501000002_add_text_limit_to_sprints_extended_title.rb`:
|
||||
|
||||
```ruby
|
||||
class AddTextLimitToSprintsExtendedTitle < Gitlab::Database::Migration[2.0]
|
||||
class AddTextLimitToSprintsExtendedTitle < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -165,7 +165,7 @@ in a post-deployment migration,
|
|||
`db/post_migrate/20200501000001_add_text_limit_migration.rb`:
|
||||
|
||||
```ruby
|
||||
class AddTextLimitMigration < Gitlab::Database::Migration[2.0]
|
||||
class AddTextLimitMigration < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -196,7 +196,7 @@ to add a background migration for the 13.0 milestone (current),
|
|||
`db/post_migrate/20200501000002_schedule_cap_title_length_on_issues.rb`:
|
||||
|
||||
```ruby
|
||||
class ScheduleCapTitleLengthOnIssues < Gitlab::Database::Migration[2.0]
|
||||
class ScheduleCapTitleLengthOnIssues < Gitlab::Database::Migration[2.1]
|
||||
# Info on how many records will be affected on GitLab.com
|
||||
# time each batch needs to run on average, etc ...
|
||||
BATCH_SIZE = 5000
|
||||
|
|
@ -236,7 +236,7 @@ helper in a final post-deployment migration,
|
|||
`db/post_migrate/20200601000001_validate_text_limit_migration.rb`:
|
||||
|
||||
```ruby
|
||||
class ValidateTextLimitMigration < Gitlab::Database::Migration[2.0]
|
||||
class ValidateTextLimitMigration < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
@ -255,7 +255,7 @@ Increasing text limits on existing database columns can be safely achieved by fi
|
|||
and then dropping the previous limit:
|
||||
|
||||
```ruby
|
||||
class ChangeMaintainerNoteLimitInCiRunner < Gitlab::Database::Migration[2.0]
|
||||
class ChangeMaintainerNoteLimitInCiRunner < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ An example migration of partitioning the `audit_events` table by its
|
|||
`created_at` column would look like:
|
||||
|
||||
```ruby
|
||||
class PartitionAuditEvents < Gitlab::Database::Migration[2.0]
|
||||
class PartitionAuditEvents < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers
|
||||
|
||||
def up
|
||||
|
|
@ -200,7 +200,7 @@ into the partitioned copy.
|
|||
Continuing the above example, the migration would look like:
|
||||
|
||||
```ruby
|
||||
class BackfillPartitionAuditEvents < Gitlab::Database::Migration[2.0]
|
||||
class BackfillPartitionAuditEvents < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers
|
||||
|
||||
def up
|
||||
|
|
@ -233,7 +233,7 @@ failed jobs.
|
|||
Once again, continuing the example, this migration would look like:
|
||||
|
||||
```ruby
|
||||
class CleanupPartitionedAuditEventsBackfill < Gitlab::Database::Migration[2.0]
|
||||
class CleanupPartitionedAuditEventsBackfill < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers
|
||||
|
||||
def up
|
||||
|
|
@ -273,7 +273,7 @@ Include the partitioning key in the following constraints:
|
|||
Add the partitioning key column. For example, in a rails migration:
|
||||
|
||||
```ruby
|
||||
class AddPartitionNumberForPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class AddPartitionNumberForPartitioning < Gitlab::Database::Migration[2.1]
|
||||
enable_lock_retries!
|
||||
|
||||
TABLE_NAME = :table_name
|
||||
|
|
@ -291,7 +291,7 @@ end
|
|||
Add indexes including the partitioning key column. For example, in a rails migration:
|
||||
|
||||
```ruby
|
||||
class PrepareIndexesForPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class PrepareIndexesForPartitioning < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :table_name
|
||||
|
|
@ -312,7 +312,7 @@ end
|
|||
Swap the primary key including the partitioning key column. For example, in a rails migration:
|
||||
|
||||
```ruby
|
||||
class PreparePrimaryKeyForPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class PreparePrimaryKeyForPartitioning < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :table_name
|
||||
|
|
@ -347,7 +347,7 @@ end
|
|||
Enforce unique indexes including the partitioning key column. For example, in a rails migration:
|
||||
|
||||
```ruby
|
||||
class PrepareUniqueContraintForPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class PrepareUniqueContraintForPartitioning < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :table_name
|
||||
|
|
@ -373,7 +373,7 @@ end
|
|||
Enforce foreign keys including the partitioning key column. For example, in a rails migration:
|
||||
|
||||
```ruby
|
||||
class PrepareForeignKeyForPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class PrepareForeignKeyForPartitioning < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
SOURCE_TABLE_NAME = :source_table_name
|
||||
|
|
@ -410,7 +410,7 @@ partition by using the following helpers provided by the database team.
|
|||
For example, using list partitioning in Rails post migrations:
|
||||
|
||||
```ruby
|
||||
class PrepareTableConstraintsForListPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class PrepareTableConstraintsForListPartitioning < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
|
@ -441,7 +441,7 @@ end
|
|||
```
|
||||
|
||||
```ruby
|
||||
class ConvertTableToListPartitioning < Gitlab::Database::Migration[2.0]
|
||||
class ConvertTableToListPartitioning < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ export default {
|
|||
|
||||
Refer to [Vuex documentation](https://vuex.vuejs.org/guide/testing.html) regarding testing Actions, Getters and Mutations.
|
||||
|
||||
#### Testing components that need a store
|
||||
#### Testing components that need a store
|
||||
|
||||
Smaller components might use `store` properties to access the data. To write unit tests for those
|
||||
components, we need to include the store and provide the correct state:
|
||||
|
|
|
|||
|
|
@ -442,13 +442,27 @@ def default_min_key_size(name)
|
|||
end
|
||||
```
|
||||
|
||||
## Nightly Omnibus FIPS builds
|
||||
## Omnibus FIPS packages
|
||||
|
||||
The Distribution team has created [nightly FIPS Omnibus builds](https://packages.gitlab.com/gitlab/nightly-fips-builds). These
|
||||
GitLab builds are compiled to use the system OpenSSL instead of the Omnibus-embedded version of OpenSSL.
|
||||
GitLab has a dedicated repository
|
||||
([`gitlab/gitlab-fips`](https://packages.gitlab.com/gitlab/gitlab-fips))
|
||||
for builds of the Omnibus GitLab which are built with FIPS compliance.
|
||||
These GitLab builds are compiled to use the system OpenSSL, instead of
|
||||
the Omnibus-embedded version of OpenSSL. These packages are built for:
|
||||
|
||||
- RHEL 8 (and compatible)
|
||||
- AmazonLinux 2
|
||||
- Ubuntu
|
||||
|
||||
These are [consumed by the GitLab Environment Toolkit](#install-gitlab-with-fips-compliance) (GET).
|
||||
|
||||
See [the section on how FIPS builds are created](#how-fips-builds-are-created).
|
||||
|
||||
### Nightly Omnibus FIPS builds
|
||||
|
||||
The Distribution team has created [nightly FIPS Omnibus builds](https://packages.gitlab.com/gitlab/nightly-fips-builds),
|
||||
which can be used for *testing* purposes. These should never be used for production environments.
|
||||
|
||||
## Runner
|
||||
|
||||
See the [documentation on installing a FIPS-compliant GitLab Runner](https://docs.gitlab.com/runner/install/#fips-compliant-gitlab-runner).
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ of migration helpers.
|
|||
In this example, we use version 2.0 of the migration class:
|
||||
|
||||
```ruby
|
||||
class TestMigration < Gitlab::Database::Migration[2.0]
|
||||
class TestMigration < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
end
|
||||
end
|
||||
|
|
@ -600,7 +600,7 @@ by calling the method `disable_ddl_transaction!` in the body of your migration
|
|||
class like so:
|
||||
|
||||
```ruby
|
||||
class MyMigration < Gitlab::Database::Migration[2.0]
|
||||
class MyMigration < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_name'
|
||||
|
|
@ -657,7 +657,7 @@ by calling the method `disable_ddl_transaction!` in the body of your migration
|
|||
class like so:
|
||||
|
||||
```ruby
|
||||
class MyMigration < Gitlab::Database::Migration[2.0]
|
||||
class MyMigration < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_name'
|
||||
|
|
@ -700,7 +700,7 @@ The easiest way to test for existence of an index by name is to use the
|
|||
be used with a name option. For example:
|
||||
|
||||
```ruby
|
||||
class MyMigration < Gitlab::Database::Migration[2.0]
|
||||
class MyMigration < Gitlab::Database::Migration[2.1]
|
||||
INDEX_NAME = 'index_name'
|
||||
|
||||
def up
|
||||
|
|
@ -735,7 +735,7 @@ Here's an example where we add a new column with a foreign key
|
|||
constraint. Note it includes `index: true` to create an index for it.
|
||||
|
||||
```ruby
|
||||
class Migration < Gitlab::Database::Migration[2.0]
|
||||
class Migration < Gitlab::Database::Migration[2.1]
|
||||
|
||||
def change
|
||||
add_reference :model, :other_model, index: true, foreign_key: { on_delete: :cascade }
|
||||
|
|
@ -791,7 +791,7 @@ expensive and disruptive operation for larger tables, but in reality it's not.
|
|||
Take the following migration as an example:
|
||||
|
||||
```ruby
|
||||
class DefaultRequestAccessGroups < Gitlab::Database::Migration[2.0]
|
||||
class DefaultRequestAccessGroups < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
change_column_default(:namespaces, :request_access_enabled, from: false, to: true)
|
||||
end
|
||||
|
|
@ -985,7 +985,7 @@ Re-add a sequence:
|
|||
A Rails migration example:
|
||||
|
||||
```ruby
|
||||
class DropSequenceTest < Gitlab::Database::Migration[2.0]
|
||||
class DropSequenceTest < Gitlab::Database::Migration[2.1]
|
||||
def up
|
||||
drop_sequence(:ci_pipelines_config, :pipeline_id, :ci_pipelines_config_pipeline_id_seq)
|
||||
end
|
||||
|
|
@ -1016,7 +1016,7 @@ Under the hood, it works like this:
|
|||
- Add the primary key using the index defined beforehand.
|
||||
|
||||
```ruby
|
||||
class SwapPrimaryKey < Gitlab::Database::Migration[2.0]
|
||||
class SwapPrimaryKey < Gitlab::Database::Migration[2.1]
|
||||
TABLE_NAME = :table_name
|
||||
PRIMARY_KEY = :table_name_pkey
|
||||
OLD_INDEX_NAME = :old_index_name
|
||||
|
|
@ -1107,7 +1107,7 @@ The Rails 5 natively supports `JSONB` (binary JSON) column type.
|
|||
Example migration adding this column:
|
||||
|
||||
```ruby
|
||||
class AddOptionsToBuildMetadata < Gitlab::Database::Migration[2.0]
|
||||
class AddOptionsToBuildMetadata < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
add_column :ci_builds_metadata, :config_options, :jsonb
|
||||
end
|
||||
|
|
@ -1139,7 +1139,7 @@ Do not store `attr_encrypted` attributes as `:text` in the database; use
|
|||
efficient:
|
||||
|
||||
```ruby
|
||||
class AddSecretToSomething < Gitlab::Database::Migration[2.0]
|
||||
class AddSecretToSomething < Gitlab::Database::Migration[2.1]
|
||||
def change
|
||||
add_column :something, :encrypted_secret, :binary
|
||||
add_column :something, :encrypted_secret_iv, :binary
|
||||
|
|
@ -1197,7 +1197,7 @@ If you need more complex logic, you can define and use models local to a
|
|||
migration. For example:
|
||||
|
||||
```ruby
|
||||
class MyMigration < Gitlab::Database::Migration[2.0]
|
||||
class MyMigration < Gitlab::Database::Migration[2.1]
|
||||
class Project < MigrationRecord
|
||||
self.table_name = 'projects'
|
||||
end
|
||||
|
|
@ -1296,7 +1296,7 @@ in a previous migration.
|
|||
It is important not to leave out the `User.reset_column_information` command, to ensure that the old schema is dropped from the cache and ActiveRecord loads the updated schema information.
|
||||
|
||||
```ruby
|
||||
class AddAndSeedMyColumn < Gitlab::Database::Migration[2.0]
|
||||
class AddAndSeedMyColumn < Gitlab::Database::Migration[2.1]
|
||||
class User < MigrationRecord
|
||||
self.table_name = 'users'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ After you add or change an existing common metric, you must [re-run the import s
|
|||
Or, you can create a database migration:
|
||||
|
||||
```ruby
|
||||
class ImportCommonMetrics < Gitlab::Database::Migration[2.0]
|
||||
class ImportCommonMetrics < Gitlab::Database::Migration[2.1]
|
||||
def up
|
||||
::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
|
||||
end
|
||||
|
|
|
|||
|
|
@ -131,12 +131,12 @@ To remove a worker class, follow these steps over two minor releases:
|
|||
|
||||
1. Remove any code that enqueues the jobs.
|
||||
|
||||
For example, if there is a UI component or an API endpoint that a user can interact with that results in the worker instance getting enqueued, make sure those surface areas are either removed or updated in a way that the worker instance is no longer enqueued.
|
||||
For example, if there is a UI component or an API endpoint that a user can interact with that results in the worker instance getting enqueued, make sure those surface areas are either removed or updated in a way that the worker instance is no longer enqueued.
|
||||
|
||||
This ensures that instances related to the worker class are no longer being enqueued.
|
||||
|
||||
1. Ensure both the frontend and backend code no longer relies on any of the work that used to be done by the worker.
|
||||
1. In the relevant worker classes, replace the contents of the `perform` method with a no-op, while keeping any arguments in tact.
|
||||
1. In the relevant worker classes, replace the contents of the `perform` method with a no-op, while keeping any arguments in tact.
|
||||
|
||||
For example, if you're working with the following `ExampleWorker`:
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ To remove a worker class, follow these steps over two minor releases:
|
|||
end
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
Implementing the no-op might look like this:
|
||||
|
||||
```ruby
|
||||
|
|
@ -190,7 +190,7 @@ When renaming queues, use the `sidekiq_queue_migrate` helper migration method
|
|||
in a **post-deployment migration**:
|
||||
|
||||
```ruby
|
||||
class MigrateTheRenamedSidekiqQueue < Gitlab::Database::Migration[2.0]
|
||||
class MigrateTheRenamedSidekiqQueue < Gitlab::Database::Migration[2.1]
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
disable_ddl_transaction!
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ transaction. Transactions for migrations can be disabled using the following
|
|||
pattern:
|
||||
|
||||
```ruby
|
||||
class MigrationName < Gitlab::Database::Migration[2.0]
|
||||
class MigrationName < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
end
|
||||
```
|
||||
|
|
@ -111,7 +111,7 @@ end
|
|||
For example:
|
||||
|
||||
```ruby
|
||||
class AddUsersLowerUsernameEmailIndexes < Gitlab::Database::Migration[2.0]
|
||||
class AddUsersLowerUsernameEmailIndexes < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ it's reset to a pristine test after each test.
|
|||
inconsistent state, so that following tests might not know about certain columns.
|
||||
- [Example 2](https://gitlab.com/gitlab-org/gitlab/-/issues/368500): A test modifies data that is
|
||||
used by a following test.
|
||||
- [Example 3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/103434#note_1172316521): A test for a database query passes in a fresh database, but in a
|
||||
- [Example 3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/103434#note_1172316521): A test for a database query passes in a fresh database, but in a
|
||||
CI/CD pipeline where the database is used to process previous test sequences, the test fails. This likely
|
||||
means that the query itself needs to be updated to work in a non-clean database.
|
||||
|
||||
|
|
|
|||
|
|
@ -981,3 +981,98 @@ Truncate the filenames on the filesystem. You must manually rename the files in
|
|||
#### Re-run the backup task
|
||||
|
||||
After following all the previous steps, re-run the backup task.
|
||||
|
||||
### Restoring database backup fails when `pg_stat_statements` was previously enabled
|
||||
|
||||
The GitLab backup of the PostgreSQL database includes all SQL statements required to enable extensions that were
|
||||
previously enabled in the database.
|
||||
|
||||
The `pg_stat_statements` extension can only be enabled or disabled by a PostgreSQL user with `superuser` role.
|
||||
As the restore process uses a database user with limited permissions, it can't execute the following SQL statements:
|
||||
|
||||
```sql
|
||||
DROP EXTENSION IF EXISTS pg_stat_statements;
|
||||
CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public;
|
||||
```
|
||||
|
||||
When trying to restore the backup in a PostgreSQL instance that doesn't have the `pg_stats_statements` extension,
|
||||
the following error message is displayed:
|
||||
|
||||
```plaintext
|
||||
ERROR: permission denied to create extension "pg_stat_statements"
|
||||
HINT: Must be superuser to create this extension.
|
||||
ERROR: extension "pg_stat_statements" does not exist
|
||||
```
|
||||
|
||||
When trying to restore in an instance that has the `pg_stats_statements` extension enabled, the cleaning up step
|
||||
fails with an error message similar to the following:
|
||||
|
||||
```plaintext
|
||||
rake aborted!
|
||||
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR: must be owner of view pg_stat_statements
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:42:in `block (4 levels) in <top (required)>'
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `each'
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `block (3 levels) in <top (required)>'
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rake:71:in `block (3 levels) in <top (required)>'
|
||||
/opt/gitlab/embedded/bin/bundle:23:in `load'
|
||||
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
|
||||
Caused by:
|
||||
PG::InsufficientPrivilege: ERROR: must be owner of view pg_stat_statements
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:42:in `block (4 levels) in <top (required)>'
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `each'
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `block (3 levels) in <top (required)>'
|
||||
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rake:71:in `block (3 levels) in <top (required)>'
|
||||
/opt/gitlab/embedded/bin/bundle:23:in `load'
|
||||
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
|
||||
Tasks: TOP => gitlab:db:drop_tables
|
||||
(See full trace by running task with --trace)
|
||||
```
|
||||
|
||||
#### Prevent the dump file to include `pg_stat_statements`
|
||||
|
||||
To prevent the inclusion of the extension in the PostgreSQL dump file that is part of the backup bundle,
|
||||
enable the extension in any schema except the `public` schema:
|
||||
|
||||
```sql
|
||||
CREATE SCHEMA adm;
|
||||
CREATE EXTENSION pg_stat_statements SCHEMA adm;
|
||||
```
|
||||
|
||||
If the extension was previously enabled in the `public` schema, move it to a new one:
|
||||
|
||||
```sql
|
||||
CREATE SCHEMA adm;
|
||||
ALTER EXTENSION pg_stat_statements SET SCHEMA adm;
|
||||
```
|
||||
|
||||
To query the `pg_stat_statements` data after changing the schema, prefix the view name with the new schema:
|
||||
|
||||
```sql
|
||||
SELECT * FROM adm.pg_stat_statements limit 0;
|
||||
```
|
||||
|
||||
To make it compatible with third-party monitoring solutions that expect it to be enabled in the `public` schema,
|
||||
you need to include it in the `search_path`:
|
||||
|
||||
```sql
|
||||
set search_path to public,adm;
|
||||
```
|
||||
|
||||
#### Fix an existing dump file to remove references to `pg_stat_statements`
|
||||
|
||||
To fix an existing backup file, do the following changes:
|
||||
|
||||
1. Extract from the backup the following file: `db/database.sql.gz`.
|
||||
1. Decompress the file or use an editor that is capable of handling it compressed.
|
||||
1. Remove the following lines, or similar ones:
|
||||
|
||||
```sql
|
||||
CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public;
|
||||
```
|
||||
|
||||
```sql
|
||||
COMMENT ON EXTENSION pg_stat_statements IS 'track planning and execution statistics of all SQL statements executed';
|
||||
```
|
||||
|
||||
1. Save the changes and recompress the file.
|
||||
1. Update the backup file with the modified `db/database.sql.gz`.
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ The `merge_status` field in the [merge request API](https://docs.gitlab.com/ee/a
|
|||
|
||||
### File Type variable expansion in `.gitlab-ci.yml`
|
||||
|
||||
Planned removal: GitLab <span class="removal-milestone">15.7</span> ()
|
||||
Planned removal: GitLab <span class="removal-milestone">15.7</span> (2022-12-22)
|
||||
|
||||
WARNING:
|
||||
This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_guidelines/).
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ With this new visualization, software leaders can track metrics improvements, un
|
|||
Deployment frequency is calculated based on the deployments record, which is created for typical push-based deployments.
|
||||
These deployment records are not created for pull-based deployments, for example when Container Images are connected to GitLab with an agent.
|
||||
|
||||
To track DORA metrics in these cases, you can [create a deployment record](../../api/deployments.md#create-a-deployment) using the Deployments API. See also the documentation page for [Track deployments of an external deployment tool](../../ci/environments/external_deployment_tools.md).
|
||||
To track DORA metrics in these cases, you can [create a deployment record](../../api/deployments.md#create-a-deployment) using the Deployments API. See also the documentation page for [Track deployments of an external deployment tool](../../ci/environments/external_deployment_tools.md).
|
||||
|
||||
### Supported DORA metrics in GitLab
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ time due to changes to the application.
|
|||
To run a DAST authenticated scan:
|
||||
|
||||
- Read the [prerequisite](#prerequisites) conditions for authentication.
|
||||
- [Update your target website](#update-the-target-website) to a landing page of an authenticated user.
|
||||
- [Update your target website](#update-the-target-website) to a landing page of an authenticated user.
|
||||
- If your login form has the username, password and submit button on a single page, use the [CI/CD variables](#available-cicd-variables) to configure [single-step](#configuration-for-a-single-step-login-form) login form authentication.
|
||||
- If your login form has the username and password fields on different pages, use the [CI/CD variables](#available-cicd-variables) to configure [multi-step](#configuration-for-a-multi-step-login-form) login form authentication.
|
||||
- Make sure the user isn't [logged out](#excluding-logout-urls) during the scan.
|
||||
|
|
@ -47,7 +47,7 @@ To run a DAST authenticated scan:
|
|||
- You know the [selectors](#finding-an-elements-selector) of the username and password HTML fields that DAST will use to input the respective values.
|
||||
- You know the element's [selector](#finding-an-elements-selector) that will submit the login form when selected.
|
||||
- You have thought about how you can [verify](#verifying-authentication-is-successful) whether or not authentication was successful.
|
||||
- You have checked the [known limitations](#known-limitations) to ensure DAST can authenticate to your application.
|
||||
- You have checked the [known limitations](#known-limitations) to ensure DAST can authenticate to your application.
|
||||
|
||||
### Available CI/CD variables
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ dast:
|
|||
A single-step login form has all login form elements on a single page.
|
||||
Configuration requires the CI/CD variables `DAST_AUTH_URL`, `DAST_USERNAME`, `DAST_USERNAME_FIELD`, `DAST_PASSWORD`, `DAST_PASSWORD_FIELD`, and `DAST_SUBMIT_FIELD` to be defined for the DAST job.
|
||||
|
||||
It is recommended to set up the URL and selectors of fields in the job definition YAML, for example:
|
||||
It is recommended to set up the URL and selectors of fields in the job definition YAML, for example:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
|
|
@ -149,7 +149,7 @@ Check the [known limitations](#known-limitations) of DAST authentication to dete
|
|||
|
||||
### Clicking to navigate to the login form
|
||||
|
||||
Define `DAST_BROWSER_PATH_TO_LOGIN_FORM` to provide a path of elements to click on from the `DAST_AUTH_URL` so that DAST can access the
|
||||
Define `DAST_BROWSER_PATH_TO_LOGIN_FORM` to provide a path of elements to click on from the `DAST_AUTH_URL` so that DAST can access the
|
||||
login form. This is useful for applications that show the login form in a pop-up (modal) window or when the login form does not
|
||||
have a unique URL.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ whitepaper.
|
|||
|
||||
GitLab provides the following DAST analyzers, one or more of which may be useful depending on the kind of application you're testing.
|
||||
|
||||
For scanning websites, use one of:
|
||||
For scanning websites, use one of:
|
||||
|
||||
- The [DAST proxy-based analyzer](proxy-based.md) for scanning traditional applications serving simple HTML. The proxy-based analyzer can be run automatically or on-demand.
|
||||
- The [DAST browser-based analyzer](browser_based.md) for scanning applications that make heavy use of JavaScript. This includes single page web applications.
|
||||
|
|
|
|||
|
|
@ -1498,11 +1498,11 @@ Note that if the `Authorization` header or any other header needs to get updated
|
|||
|
||||
The variable `DAST_API_REQUEST_HEADERS` lets you specify a comma-separated (`,`) list of headers. These headers are included on each request that the scanner performs. Each header entry in the list consists of a name followed by a colon (`:`) and then by its value. Whitespace before the key or value is ignored. For example, to declare a header name `Cache-Control` with the value `max-age=604800`, the header entry is `Cache-Control: max-age=604800`. To use two headers, `Cache-Control: max-age=604800` and `Age: 100`, set `DAST_API_REQUEST_HEADERS` variable to `Cache-Control: max-age=604800, Age: 100`.
|
||||
|
||||
The order in which the different headers are provided into the variable `DAST_API_REQUEST_HEADERS` does not affect the result. Setting `DAST_API_REQUEST_HEADERS` to `Cache-Control: max-age=604800, Age: 100` produces the same result as setting it to `Age: 100, Cache-Control: max-age=604800`.
|
||||
The order in which the different headers are provided into the variable `DAST_API_REQUEST_HEADERS` does not affect the result. Setting `DAST_API_REQUEST_HEADERS` to `Cache-Control: max-age=604800, Age: 100` produces the same result as setting it to `Age: 100, Cache-Control: max-age=604800`.
|
||||
|
||||
### Base64
|
||||
|
||||
The `DAST_API_REQUEST_HEADERS_BASE64` variable accepts the same list of headers as `DAST_API_REQUEST_HEADERS`, with the only difference that the entire value of the variable must be Base64-encoded. For example, to set `DAST_API_REQUEST_HEADERS_BASE64` variable to `Authorization: QmVhcmVyIFRPS0VO, Cache-control: bm8tY2FjaGU=`, ensure you convert the list to its Base64 equivalent: `QXV0aG9yaXphdGlvbjogUW1WaGNtVnlJRlJQUzBWTywgQ2FjaGUtY29udHJvbDogYm04dFkyRmphR1U9`, and the Base64-encoded value must be used. This is useful when storing secret header values in a [masked variable](../../../ci/variables/index.md#mask-a-cicd-variable), which has character set restrictions.
|
||||
The `DAST_API_REQUEST_HEADERS_BASE64` variable accepts the same list of headers as `DAST_API_REQUEST_HEADERS`, with the only difference that the entire value of the variable must be Base64-encoded. For example, to set `DAST_API_REQUEST_HEADERS_BASE64` variable to `Authorization: QmVhcmVyIFRPS0VO, Cache-control: bm8tY2FjaGU=`, ensure you convert the list to its Base64 equivalent: `QXV0aG9yaXphdGlvbjogUW1WaGNtVnlJRlJQUzBWTywgQ2FjaGUtY29udHJvbDogYm04dFkyRmphR1U9`, and the Base64-encoded value must be used. This is useful when storing secret header values in a [masked variable](../../../ci/variables/index.md#mask-a-cicd-variable), which has character set restrictions.
|
||||
|
||||
WARNING:
|
||||
Base64 is used to support the [masked variable](../../../ci/variables/index.md#mask-a-cicd-variable) feature. Base64 encoding is not by itself a security measure, because sensitive values can be easily decoded.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ module Gitlab
|
|||
def from_markdown_image(markdown_node)
|
||||
url = markdown_node.url
|
||||
|
||||
return unless url
|
||||
return unless github_url?(url, media: true)
|
||||
return unless whitelisted_type?(url, media: true)
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ module Gitlab
|
|||
def from_markdown_link(markdown_node)
|
||||
url = markdown_node.url
|
||||
|
||||
return unless url
|
||||
return unless github_url?(url, docs: true)
|
||||
return unless whitelisted_type?(url, docs: true)
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ module Gitlab
|
|||
def from_inline_html(markdown_node)
|
||||
img = Nokogiri::HTML.parse(markdown_node.string_content).xpath('//img')[0]
|
||||
|
||||
return unless img
|
||||
return if img.nil? || img[:src].blank?
|
||||
return unless github_url?(img[:src], media: true)
|
||||
return unless whitelisted_type?(img[:src], media: true)
|
||||
|
||||
|
|
|
|||
|
|
@ -149,18 +149,6 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def all_repos
|
||||
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
|
||||
Gitlab.config.repositories.storages.each_value do |repository_storage|
|
||||
IO.popen(%W(find #{repository_storage.legacy_disk_path} -mindepth 2 -type d -name *.git)) do |find|
|
||||
find.each_line do |path|
|
||||
yield path.chomp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def repository_storage_paths_args
|
||||
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
|
||||
Gitlab.config.repositories.storages.values.map { |rs| rs.legacy_disk_path }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ RSpec.describe 'Migrations Validation' do
|
|||
# The range describes the timestamps that given migration helper can be used
|
||||
let(:all_migration_classes) do
|
||||
{
|
||||
2022_12_01_02_15_00.. => Gitlab::Database::Migration[2.1],
|
||||
2022_01_26_21_06_58.. => Gitlab::Database::Migration[2.0],
|
||||
2021_09_01_15_33_24..2022_04_25_12_06_03 => Gitlab::Database::Migration[1.0],
|
||||
2021_05_31_05_39_16..2021_09_01_15_33_24 => ActiveRecord::Migration[6.1],
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import Vue, { nextTick } from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
|
||||
import { GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui';
|
||||
|
||||
import BoardCardMoveToPosition from '~/boards/components/board_card_move_to_position.vue';
|
||||
import { mockList, mockIssue2, mockIssue, mockIssue3, mockIssue4 } from 'jest/boards/mock_data';
|
||||
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
|
||||
import { BOARD_CARD_MOVE_TO_POSITION_OPTIONS } from '~/boards/constants';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const dropdownOptions = [
|
||||
BoardCardMoveToPosition.i18n.moveToStartText,
|
||||
BoardCardMoveToPosition.i18n.moveToEndText,
|
||||
BOARD_CARD_MOVE_TO_POSITION_OPTIONS[0].text,
|
||||
BOARD_CARD_MOVE_TO_POSITION_OPTIONS[1].text,
|
||||
];
|
||||
|
||||
describe('Board Card Move to position', () => {
|
||||
|
|
@ -53,8 +54,7 @@ describe('Board Card Move to position', () => {
|
|||
...propsData,
|
||||
},
|
||||
stubs: {
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlCollapsibleListbox,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -68,8 +68,8 @@ describe('Board Card Move to position', () => {
|
|||
wrapper.destroy();
|
||||
});
|
||||
|
||||
const findMoveToPositionDropdown = () => wrapper.findComponent(GlDropdown);
|
||||
const findDropdownItems = () => findMoveToPositionDropdown().findAllComponents(GlDropdownItem);
|
||||
const findMoveToPositionDropdown = () => wrapper.findComponent(GlCollapsibleListbox);
|
||||
const findDropdownItems = () => findMoveToPositionDropdown().findAllComponents(GlListboxItem);
|
||||
const findDropdownItemAtIndex = (index) => findDropdownItems().at(index);
|
||||
|
||||
describe('Dropdown', () => {
|
||||
|
|
@ -80,7 +80,6 @@ describe('Board Card Move to position', () => {
|
|||
});
|
||||
|
||||
it('is opened on the click of vertical ellipsis and has 2 dropdown items when number of list items < 10', () => {
|
||||
findMoveToPositionDropdown().vm.$emit('click');
|
||||
expect(findDropdownItems()).toHaveLength(dropdownOptions.length);
|
||||
});
|
||||
});
|
||||
|
|
@ -97,18 +96,17 @@ describe('Board Card Move to position', () => {
|
|||
});
|
||||
|
||||
it.each`
|
||||
dropdownIndex | dropdownLabel | trackLabel | positionInList
|
||||
${0} | ${BoardCardMoveToPosition.i18n.moveToStartText} | ${'move_to_start'} | ${0}
|
||||
${1} | ${BoardCardMoveToPosition.i18n.moveToEndText} | ${'move_to_end'} | ${-1}
|
||||
dropdownIndex | dropdownLabel | trackLabel | positionInList
|
||||
${0} | ${BOARD_CARD_MOVE_TO_POSITION_OPTIONS[0].text} | ${'move_to_start'} | ${0}
|
||||
${1} | ${BOARD_CARD_MOVE_TO_POSITION_OPTIONS[1].text} | ${'move_to_end'} | ${-1}
|
||||
`(
|
||||
'on click of dropdown index $dropdownIndex with label $dropdownLabel should call moveItem action with tracking label $trackLabel',
|
||||
async ({ dropdownIndex, dropdownLabel, trackLabel, positionInList }) => {
|
||||
await findMoveToPositionDropdown().vm.$emit('click');
|
||||
|
||||
await findMoveToPositionDropdown().vm.$emit(
|
||||
'select',
|
||||
BOARD_CARD_MOVE_TO_POSITION_OPTIONS[dropdownIndex].value,
|
||||
);
|
||||
expect(findDropdownItemAtIndex(dropdownIndex).text()).toBe(dropdownLabel);
|
||||
await findDropdownItemAtIndex(dropdownIndex).vm.$emit('click', {
|
||||
stopPropagation: () => {},
|
||||
});
|
||||
|
||||
await nextTick();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Jwt::Asymmetric do
|
||||
RSpec.describe Atlassian::JiraConnect::Jwt::Asymmetric, feature_category: :integrations do
|
||||
describe '#valid?' do
|
||||
let_it_be(:private_key) { OpenSSL::PKey::RSA.generate 3072 }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Jwt::Symmetric do
|
||||
RSpec.describe Atlassian::JiraConnect::Jwt::Symmetric, feature_category: :integrations do
|
||||
let(:shared_secret) { 'secret' }
|
||||
|
||||
describe '#iss_claim' do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::AuthorEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::AuthorEntity, feature_category: :integrations do
|
||||
subject { described_class.represent(user).as_json }
|
||||
|
||||
context 'when object is a User model' do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::BaseEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::BaseEntity, feature_category: :integrations do
|
||||
let(:update_sequence_id) { nil }
|
||||
|
||||
subject do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::BranchEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::BranchEntity, feature_category: :integrations do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:branch) { project.repository.find_branch('improve/awesome') }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::BuildEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::BuildEntity, feature_category: :integrations do
|
||||
let_it_be(:user) { create_default(:user) }
|
||||
let_it_be(:project) { create_default(:project) }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::DeploymentEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::DeploymentEntity, feature_category: :integrations do
|
||||
let_it_be(:user) { create_default(:user) }
|
||||
let_it_be(:project) { create_default(:project, :repository) }
|
||||
let_it_be(:environment) { create(:environment, name: 'prod', project: project) }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::FeatureFlagEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::FeatureFlagEntity, feature_category: :integrations do
|
||||
let_it_be(:user) { create_default(:user) }
|
||||
let_it_be(:project) { create_default(:project) }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::PullRequestEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::PullRequestEntity, feature_category: :integrations do
|
||||
let_it_be(:project) { create_default(:project, :repository) }
|
||||
let_it_be(:merge_requests) { create_list(:merge_request, 2, :unique_branches) }
|
||||
let_it_be(:notes) { create_list(:note, 2, system: false, noteable: merge_requests.first) }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::RepositoryEntity do
|
||||
RSpec.describe Atlassian::JiraConnect::Serializers::RepositoryEntity, feature_category: :integrations do
|
||||
let(:update_sequence_id) { nil }
|
||||
|
||||
subject do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'fast_spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect do
|
||||
RSpec.describe Atlassian::JiraConnect, feature_category: :integrations do
|
||||
describe '.app_name' do
|
||||
subject { described_class.app_name }
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ RSpec.describe Gitlab::GithubImport::Markdown::Attachment do
|
|||
|
||||
it { expect(described_class.from_markdown(markdown_node)).to eq nil }
|
||||
end
|
||||
|
||||
context 'when URL is blank' do
|
||||
let(:url) { nil }
|
||||
|
||||
it { expect(described_class.from_markdown(markdown_node)).to eq nil }
|
||||
end
|
||||
end
|
||||
|
||||
context "when it's an image attachment" do
|
||||
|
|
@ -63,6 +69,12 @@ RSpec.describe Gitlab::GithubImport::Markdown::Attachment do
|
|||
|
||||
it { expect(described_class.from_markdown(markdown_node)).to eq nil }
|
||||
end
|
||||
|
||||
context 'when URL is blank' do
|
||||
let(:url) { nil }
|
||||
|
||||
it { expect(described_class.from_markdown(markdown_node)).to eq nil }
|
||||
end
|
||||
end
|
||||
|
||||
context "when it's an inline html node" do
|
||||
|
|
@ -80,6 +92,12 @@ RSpec.describe Gitlab::GithubImport::Markdown::Attachment do
|
|||
expect(attachment.name).to eq name
|
||||
expect(attachment.url).to eq url
|
||||
end
|
||||
|
||||
context 'when image src is not present' do
|
||||
let(:img) { "<img width=\"248\" alt=\"#{name}\">" }
|
||||
|
||||
it { expect(described_class.from_markdown(markdown_node)).to eq nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ RSpec.describe SystemCheck::BaseCheck do
|
|||
|
||||
it 'responds to Gitlab::TaskHelpers methods' do
|
||||
expect(subject).to respond_to :ask_to_continue, :os_name, :prompt, :run_and_match, :run_command,
|
||||
:run_command!, :uid_for, :gid_for, :gitlab_user, :gitlab_user?, :warn_user_is_not_gitlab, :all_repos,
|
||||
:run_command!, :uid_for, :gid_for, :gitlab_user, :gitlab_user?, :warn_user_is_not_gitlab,
|
||||
:repository_storage_paths_args, :user_home, :checkout_or_clone_version, :clone_repo, :checkout_version
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -925,6 +925,21 @@ RSpec.describe Deployment do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#triggered_by?' do
|
||||
subject { deployment.triggered_by?(user) }
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let(:deployment) { create(:deployment, user: user) }
|
||||
|
||||
it { is_expected.to eq(true) }
|
||||
|
||||
context 'when deployment triggerer is different' do
|
||||
let(:deployment) { create(:deployment) }
|
||||
|
||||
it { is_expected.to eq(false) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.find_successful_deployment!' do
|
||||
it 'returns a successful deployment' do
|
||||
deploy = create(:deployment, :success)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ArchivedAbilities, feature_category: :projects do
|
||||
let(:test_class) do
|
||||
Class.new do
|
||||
include ArchivedAbilities
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const('TestClass', test_class)
|
||||
end
|
||||
|
||||
describe '.archived_abilities' do
|
||||
it 'returns an array of abilites to be prevented when archived' do
|
||||
expect(TestClass.archived_abilities).to include(*described_class::ARCHIVED_ABILITIES)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.archived_features' do
|
||||
it 'returns an array of features to be prevented when archived' do
|
||||
expect(TestClass.archived_features).to include(*described_class::ARCHIVED_FEATURES)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ReadonlyAbilities do
|
||||
let(:test_class) do
|
||||
Class.new do
|
||||
include ReadonlyAbilities
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const('TestClass', test_class)
|
||||
end
|
||||
|
||||
describe '.readonly_abilities' do
|
||||
it 'returns an array of abilites to be prevented when readonly' do
|
||||
expect(TestClass.readonly_abilities).to include(*described_class::READONLY_ABILITIES)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.readonly_features' do
|
||||
it 'returns an array of features to be prevented when readonly' do
|
||||
expect(TestClass.readonly_features).to include(*described_class::READONLY_FEATURES)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,8 +11,12 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
let_it_be(:inherited_reporter) { create(:user) }
|
||||
let_it_be(:inherited_developer) { create(:user) }
|
||||
|
||||
let!(:project) { create(:project, :repository, namespace: user.namespace) }
|
||||
let(:guest) { create(:user) { |u| project.add_guest(u) } }
|
||||
let_it_be_with_reload(:project) { create(:project, :repository, namespace: user.namespace) }
|
||||
let_it_be_with_reload(:public_project) { create(:project, :public, :repository) }
|
||||
let_it_be_with_reload(:private_project) { create(:project, :private, :repository, group: group) }
|
||||
let_it_be_with_reload(:public_project_private_repo) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||
|
||||
let_it_be(:guest) { create(:user) { |u| project.add_guest(u) } }
|
||||
let(:file_path) { 'files%2Fruby%2Fpopen%2Erb' }
|
||||
let(:file_name) { 'popen.rb' }
|
||||
let(:last_commit_id) { '570e7b2abdd848b95f2f578043fc23bd6f6fd24d' }
|
||||
|
|
@ -183,8 +187,9 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
|
||||
context 'when unauthenticated' do
|
||||
context 'and project is public' do
|
||||
let(:project) { public_project }
|
||||
|
||||
it_behaves_like 'repository files' do
|
||||
let(:project) { create(:project, :public, :repository) }
|
||||
let(:current_user) { nil }
|
||||
end
|
||||
end
|
||||
|
|
@ -361,7 +366,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
context 'when unauthenticated' do
|
||||
context 'and project is public' do
|
||||
it_behaves_like 'repository files' do
|
||||
let(:project) { create(:project, :public, :repository) }
|
||||
let(:project) { public_project }
|
||||
let(:current_user) { nil }
|
||||
let(:api_user) { nil }
|
||||
end
|
||||
|
|
@ -406,7 +411,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
context 'when authenticated' do
|
||||
context 'and user is an inherited member from the group' do
|
||||
context 'when project is public with private repository' do
|
||||
let_it_be(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||
let(:project) { public_project_private_repo }
|
||||
|
||||
context 'and user is a guest' do
|
||||
it_behaves_like 'returns non-executable file attributes as json' do
|
||||
|
|
@ -428,7 +433,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
end
|
||||
|
||||
context 'when project is private' do
|
||||
let_it_be(:project) { create(:project, :private, :repository, group: group) }
|
||||
let(:project) { private_project }
|
||||
|
||||
context 'and user is a guest' do
|
||||
it_behaves_like '403 response' do
|
||||
|
|
@ -655,7 +660,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
context 'when unauthenticated' do
|
||||
context 'and project is public' do
|
||||
it_behaves_like 'repository blame files' do
|
||||
let(:project) { create(:project, :public, :repository) }
|
||||
let(:project) { public_project }
|
||||
let(:current_user) { nil }
|
||||
end
|
||||
end
|
||||
|
|
@ -836,7 +841,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
context 'when unauthenticated' do
|
||||
context 'and project is public' do
|
||||
it_behaves_like 'repository raw files' do
|
||||
let(:project) { create(:project, :public, :repository) }
|
||||
let(:project) { public_project }
|
||||
let(:current_user) { nil }
|
||||
end
|
||||
end
|
||||
|
|
@ -878,7 +883,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
end
|
||||
|
||||
describe 'POST /projects/:id/repository/files/:file_path' do
|
||||
let!(:file_path) { 'new_subfolder%2Fnewfile%2Erb' }
|
||||
let(:file_path) { FFaker::Guid.guid }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
|
|
@ -996,14 +1001,13 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
|
||||
it_behaves_like 'creates a new file in the project repo' do
|
||||
let(:current_user) { user }
|
||||
let(:file_path) { 'newfile%2Erb' }
|
||||
let(:file_path) { FFaker::Guid.guid }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when specifying an author' do
|
||||
it 'creates a new file with the specified author' do
|
||||
params.merge!(author_email: author_email, author_name: author_name)
|
||||
|
||||
post api(route('new_file_with_author%2Etxt'), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
|
|
@ -1020,7 +1024,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
context 'when authenticated' do
|
||||
context 'and user is an inherited member from the group' do
|
||||
context 'when project is public with private repository' do
|
||||
let_it_be(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||
let(:project) { public_project_private_repo }
|
||||
|
||||
context 'and user is a guest' do
|
||||
it_behaves_like '403 response' do
|
||||
|
|
@ -1042,7 +1046,7 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
end
|
||||
|
||||
context 'when project is private' do
|
||||
let_it_be(:project) { create(:project, :private, :repository, group: group) }
|
||||
let(:project) { private_project }
|
||||
|
||||
context 'and user is a guest' do
|
||||
it_behaves_like '403 response' do
|
||||
|
|
@ -1218,65 +1222,77 @@ RSpec.describe API::Files, feature_category: :source_code_management do
|
|||
}
|
||||
end
|
||||
|
||||
it 'returns 400 when file path is invalid' do
|
||||
delete api(route(invalid_file_path), user), params: params
|
||||
describe 'when files are deleted' do
|
||||
let(:file_path) { FFaker::Guid.guid }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to eq(invalid_file_message)
|
||||
end
|
||||
|
||||
it_behaves_like 'when path is absolute' do
|
||||
subject { delete api(route(absolute_path), user), params: params }
|
||||
end
|
||||
|
||||
it 'deletes existing file in project repo' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:no_content)
|
||||
end
|
||||
|
||||
context 'when no params given' do
|
||||
it 'returns a 400 bad request' do
|
||||
delete api(route(file_path), user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the commit message is empty' do
|
||||
before do
|
||||
params[:commit_message] = ''
|
||||
create_file_in_repo(project, 'master', 'master', file_path, 'Test file')
|
||||
end
|
||||
|
||||
it 'returns a 400 bad request' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when fails to delete file' do
|
||||
before do
|
||||
allow_next_instance_of(Repository) do |instance|
|
||||
allow(instance).to receive(:delete_file).and_raise(Gitlab::Git::CommitError, 'Cannot delete file')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns a 400 bad request' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when specifying an author' do
|
||||
it 'removes a file with the specified author' do
|
||||
params.merge!(author_email: author_email, author_name: author_name)
|
||||
|
||||
it 'deletes existing file in project repo' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:no_content)
|
||||
end
|
||||
|
||||
context 'when specifying an author' do
|
||||
before do
|
||||
params.merge!(author_email: author_email, author_name: author_name)
|
||||
end
|
||||
|
||||
it 'removes a file with the specified author' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:no_content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when files are not deleted' do
|
||||
it_behaves_like 'when path is absolute' do
|
||||
subject { delete api(route(absolute_path), user), params: params }
|
||||
end
|
||||
|
||||
it 'returns 400 when file path is invalid' do
|
||||
delete api(route(invalid_file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to eq(invalid_file_message)
|
||||
end
|
||||
|
||||
context 'when no params given' do
|
||||
it 'returns a 400 bad request' do
|
||||
delete api(route(file_path), user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the commit message is empty' do
|
||||
before do
|
||||
params[:commit_message] = ''
|
||||
end
|
||||
|
||||
it 'returns a 400 bad request' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when fails to delete file' do
|
||||
before do
|
||||
allow_next_instance_of(Repository) do |instance|
|
||||
allow(instance).to receive(:delete_file).and_raise(Gitlab::Git::CommitError, 'Cannot delete file')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns a 400 bad request' do
|
||||
delete api(route(file_path), user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
RSpec.shared_examples 'archived project policies' do
|
||||
let(:feature_write_abilities) do
|
||||
described_class.readonly_features.flat_map do |feature|
|
||||
described_class.archived_features.flat_map do |feature|
|
||||
described_class.create_update_admin_destroy(feature)
|
||||
end + additional_maintainer_permissions
|
||||
end
|
||||
|
||||
let(:other_write_abilities) do
|
||||
described_class.readonly_abilities
|
||||
described_class.archived_abilities
|
||||
end
|
||||
|
||||
context 'when the project is archived' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue