Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-12-10 12:10:18 +00:00
parent 240609275d
commit e838c62efb
48 changed files with 513 additions and 394 deletions

View File

@ -1,16 +0,0 @@
import Vue from 'vue';
import DeleteLabelModal from '~/vue_shared/components/delete_label_modal.vue';
const mountDeleteLabelModal = (optionalProps) =>
new Vue({
render(h) {
return h(DeleteLabelModal, {
props: {
selector: '.js-delete-label-modal-button',
...optionalProps,
},
});
},
}).$mount();
export default (optionalProps = {}) => mountDeleteLabelModal(optionalProps);

View File

@ -0,0 +1,135 @@
import $ from 'jquery';
import Vue from 'vue';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import Translate from '~/vue_shared/translate';
import DeleteLabelModal from './components/delete_label_modal.vue';
import PromoteLabelModal from './components/promote_label_modal.vue';
import eventHub from './event_hub';
import GroupLabelSubscription from './group_label_subscription';
import LabelManager from './label_manager';
import ProjectLabelSubscription from './project_label_subscription';
export function initDeleteLabelModal(optionalProps = {}) {
new Vue({
render(h) {
return h(DeleteLabelModal, {
props: {
selector: '.js-delete-label-modal-button',
...optionalProps,
},
});
},
}).$mount();
}
export function initLabels() {
if ($('.prioritized-labels').length) {
new LabelManager(); // eslint-disable-line no-new
}
$('.label-subscription').each((i, el) => {
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
new GroupLabelSubscription($el); // eslint-disable-line no-new
} else {
new ProjectLabelSubscription($el); // eslint-disable-line no-new
}
});
}
export function initLabelIndex() {
Vue.use(Translate);
initLabels();
initDeleteLabelModal();
const onRequestFinished = ({ labelUrl, successful }) => {
const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
if (!successful) {
button.removeAttribute('disabled');
}
};
const onRequestStarted = (labelUrl) => {
const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
button.setAttribute('disabled', '');
eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished);
};
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button');
return new Vue({
el: '#js-promote-label-modal',
data() {
return {
modalProps: {
labelTitle: '',
labelColor: '',
labelTextColor: '',
url: '',
groupName: '',
},
};
},
mounted() {
eventHub.$on('promoteLabelModal.props', this.setModalProps);
eventHub.$emit('promoteLabelModal.mounted');
promoteLabelButtons.forEach((button) => {
button.removeAttribute('disabled');
button.addEventListener('click', () => {
this.$root.$emit(BV_SHOW_MODAL, 'promote-label-modal');
eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted);
this.setModalProps({
labelTitle: button.dataset.labelTitle,
labelColor: button.dataset.labelColor,
labelTextColor: button.dataset.labelTextColor,
url: button.dataset.url,
groupName: button.dataset.groupName,
});
});
});
},
beforeDestroy() {
eventHub.$off('promoteLabelModal.props', this.setModalProps);
},
methods: {
setModalProps(modalProps) {
this.modalProps = modalProps;
},
},
render(createElement) {
return createElement(PromoteLabelModal, {
props: this.modalProps,
});
},
});
}
export function initAdminLabels() {
const pagination = document.querySelector('.labels .gl-pagination');
const emptyState = document.querySelector('.labels .nothing-here-block.hidden');
function removeLabelSuccessCallback() {
this.closest('li').classList.add('gl-display-none!');
const labelsCount = document.querySelectorAll(
'ul.manage-labels-list li:not(.gl-display-none\\!)',
).length;
// display the empty state if there are no more labels
if (labelsCount < 1 && !pagination && emptyState) {
emptyState.classList.remove('hidden');
}
}
document.querySelectorAll('.js-remove-label').forEach((row) => {
row.addEventListener('ajax:success', removeLabelSuccessCallback);
});
}

View File

@ -1,19 +0,0 @@
import $ from 'jquery';
import GroupLabelSubscription from './group_label_subscription';
import LabelManager from './label_manager';
import ProjectLabelSubscription from './project_label_subscription';
export default () => {
if ($('.prioritized-labels').length) {
new LabelManager(); // eslint-disable-line no-new
}
$('.label-subscription').each((i, el) => {
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
new GroupLabelSubscription($el); // eslint-disable-line no-new
} else {
new ProjectLabelSubscription($el); // eslint-disable-line no-new
}
});
};

View File

@ -9,7 +9,7 @@ import { isScopedLabel } from '~/lib/utils/common_utils';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { sprintf, __ } from '~/locale';
import CreateLabelDropdown from './create_label';
import CreateLabelDropdown from './create_label_dropdown';
export default class LabelsSelect {
constructor(els, options = {}) {

View File

@ -1,23 +1,3 @@
function initLabels() {
const pagination = document.querySelector('.labels .gl-pagination');
const emptyState = document.querySelector('.labels .nothing-here-block.hidden');
import { initAdminLabels } from '~/labels';
function removeLabelSuccessCallback() {
this.closest('li').classList.add('gl-display-none!');
const labelsCount = document.querySelectorAll(
'ul.manage-labels-list li:not(.gl-display-none\\!)',
).length;
// display the empty state if there are no more labels
if (labelsCount < 1 && !pagination && emptyState) {
emptyState.classList.remove('hidden');
}
}
document.querySelectorAll('.js-remove-label').forEach((row) => {
row.addEventListener('ajax:success', removeLabelSuccessCallback);
});
}
initLabels();
initAdminLabels();

View File

@ -1,5 +1,4 @@
import initDeleteLabelModal from '~/labels/delete_label_modal';
import initLabels from '~/labels/init_labels';
import { initDeleteLabelModal, initLabels } from '~/labels';
initLabels();
initDeleteLabelModal();

View File

@ -1,83 +1,3 @@
import Vue from 'vue';
import initDeleteLabelModal from '~/labels/delete_label_modal';
import initLabels from '~/labels/init_labels';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import Translate from '~/vue_shared/translate';
import PromoteLabelModal from '../components/promote_label_modal.vue';
import eventHub from '../event_hub';
import { initLabelIndex } from '~/labels';
Vue.use(Translate);
const initLabelIndex = () => {
initLabels();
initDeleteLabelModal();
const onRequestFinished = ({ labelUrl, successful }) => {
const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
if (!successful) {
button.removeAttribute('disabled');
}
};
const onRequestStarted = (labelUrl) => {
const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
button.setAttribute('disabled', '');
eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished);
};
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button');
return new Vue({
el: '#js-promote-label-modal',
data() {
return {
modalProps: {
labelTitle: '',
labelColor: '',
labelTextColor: '',
url: '',
groupName: '',
},
};
},
mounted() {
eventHub.$on('promoteLabelModal.props', this.setModalProps);
eventHub.$emit('promoteLabelModal.mounted');
promoteLabelButtons.forEach((button) => {
button.removeAttribute('disabled');
button.addEventListener('click', () => {
this.$root.$emit(BV_SHOW_MODAL, 'promote-label-modal');
eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted);
this.setModalProps({
labelTitle: button.dataset.labelTitle,
labelColor: button.dataset.labelColor,
labelTextColor: button.dataset.labelTextColor,
url: button.dataset.url,
groupName: button.dataset.groupName,
});
});
});
},
beforeDestroy() {
eventHub.$off('promoteLabelModal.props', this.setModalProps);
},
methods: {
setModalProps(modalProps) {
this.modalProps = modalProps;
},
},
render(createElement) {
return createElement(PromoteLabelModal, {
props: this.modalProps,
});
},
});
};
initLabelIndex();

View File

@ -195,12 +195,12 @@ export default {
>
<template #header>
<dropdown-header
v-if="!isStandalone"
ref="header"
v-model="searchKey"
:search-key="searchKey"
:labels-create-title="labelsCreateTitle"
:labels-list-title="labelsListTitle"
:show-dropdown-contents-create-view="showDropdownContentsCreateView"
:is-standalone="isStandalone"
@toggleDropdownContentsCreateView="toggleDropdownContent"
@closeDropdown="$emit('closeDropdown')"
@input="debouncedSearchKeyUpdate"

View File

@ -6,9 +6,6 @@ export default {
GlButton,
GlSearchBoxByType,
},
model: {
prop: 'searchKey',
},
props: {
labelsCreateTitle: {
type: String,
@ -31,6 +28,11 @@ export default {
type: String,
required: true,
},
isStandalone: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
dropdownTitle() {
@ -47,7 +49,11 @@ export default {
<template>
<div data-testid="dropdown-header">
<div class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!">
<div
v-if="!isStandalone"
class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!"
data-testid="dropdown-header-title"
>
<gl-button
v-if="showDropdownContentsCreateView"
:aria-label="__('Go back')"

View File

@ -286,7 +286,7 @@ export default {
<template>
<div
class="labels-select-wrapper position-relative"
class="labels-select-wrapper gl-relative"
:class="{
'is-standalone': isDropdownVariantStandalone(variant),
'is-embedded': isDropdownVariantEmbedded(variant),

View File

@ -83,8 +83,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:ci_environments_status,
:destroy,
:rebase,
:discussions,
:description_diff
:discussions
]
def index

View File

@ -26,7 +26,6 @@ module Git
enqueue_detect_repository_languages
execute_related_hooks
perform_housekeeping
stop_environments
unlock_artifacts
@ -71,13 +70,6 @@ module Git
BranchHooksService.new(project, current_user, params).execute
end
def perform_housekeeping
housekeeping = Repositories::HousekeepingService.new(project)
housekeeping.increment!
housekeeping.execute if housekeeping.needed?
rescue Repositories::HousekeepingService::LeaseTaken
end
def removing_branch?
Gitlab::Git.blank_ref?(newrev)
end

View File

@ -9,6 +9,8 @@ module Git
process_changes_by_action(:branch, changes.branch_changes)
process_changes_by_action(:tag, changes.tag_changes)
perform_housekeeping
end
private
@ -83,5 +85,12 @@ module Git
MergeRequests::PushedBranchesService.new(project: project, current_user: current_user, params: { changes: changes }).execute
end
def perform_housekeeping
housekeeping = Repositories::HousekeepingService.new(project)
housekeeping.increment!
housekeeping.execute if housekeeping.needed?
rescue Repositories::HousekeepingService::LeaseTaken
end
end
end

View File

@ -1,2 +1,2 @@
- if project.archived
%span.badge.badge-warning.badge-pill.gl-badge.md= _('archived')
= gl_badge_tag _('archived'), variant: :warning, size: :md

View File

@ -42,7 +42,7 @@
%ul.content-list.all-branches
- @branches.each do |branch|
= render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any?
- if Feature.enabled?(:branches_pagination_without_count, @project, default_enabled: :yaml)
- if Feature.enabled?(:branch_list_keyset_pagination, @project, default_enabled: :yaml)
= render('kaminari/gitlab/without_count', previous_path: @prev_path, next_path: @next_path)
- else
= paginate @branches, theme: 'gitlab'

View File

@ -23,7 +23,7 @@
= form.label :enabled, class: 'form-check-label' do
%strong= s_('CICD|Default to Auto DevOps pipeline')
- if auto_devops_enabled
%span.badge.badge-info.js-instance-default-badge= badge_for_auto_devops_scope(@project)
= gl_badge_tag badge_for_auto_devops_scope(@project), { variant: :info }, { class: 'js-instance-default-badge'}
.form-text.text-muted
= s_('CICD|The Auto DevOps pipeline runs if no alternative CI configuration file is found.')
= link_to _('Learn more.'), help_page_path('topics/autodevops/index.md'), target: '_blank'

View File

@ -1,8 +0,0 @@
---
name: branches_pagination_without_count
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50759
rollout_issue_url:
milestone: '13.9'
type: development
group: group::source code
default_enabled: false

View File

@ -0,0 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.testing.users_expanding_testing_license_compliance_report_monthly
description: Count of expanding the license compliance widget
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- users_expanding_testing_license_compliance_report
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.testing.users_visiting_testing_license_compliance_full_report_monthly
description: Count of visiting the license compliance full report
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- users_visiting_testing_license_compliance_full_report
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.testing.users_visiting_testing_manage_license_compliance_monthly
description: Count of visiting the manage license compliance page
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 28d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- users_visiting_testing_manage_license_compliance
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.testing.users_expanding_testing_license_compliance_report_weekly
description: Count of expanding the license compliance widget
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- users_expanding_testing_license_compliance_report
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.testing.users_visiting_testing_license_compliance_full_report_weekly
description: Count of visiting the license compliance full report
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- users_visiting_testing_license_compliance_full_report
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,25 @@
---
data_category: optional
key_path: redis_hll_counters.testing.users_visiting_testing_manage_license_compliance_weekly
description: Count of visiting the manage license compliance page
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 7d
data_source: redis_hll
instrumentation_class: RedisHLLMetric
options:
events:
- users_visiting_testing_manage_license_compliance
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -56,7 +56,7 @@ In `config/gitlab.yml`:
## Storing LFS objects in remote object storage
You can store LFS objects in remote object storage. This allows you
to offload reads and writes to the local disk, and free up disk space significantly.
to reduce reads and writes to the local disk, and free up disk space significantly.
GitLab is tightly integrated with `Fog`, so you can refer to its [documentation](http://fog.io/about/provider_documentation.html)
to check which storage services can be integrated with GitLab.
You can also use external object storage in a private local network. For example,
@ -98,32 +98,6 @@ See [the available connection settings for different providers](../object_storag
Here is a configuration example with S3.
### Manual uploading to an object storage
There are two ways to manually do the same thing as automatic uploading (described above).
**Option 1: Rake task**
```shell
gitlab-rake gitlab:lfs:migrate
```
**Option 2: Rails console**
Log into the Rails console:
```shell
sudo gitlab-rails console
```
Upload LFS files manually
```ruby
LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object|
lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists?
end
```
### S3 for Omnibus installations
On Omnibus GitLab installations, the settings are prefixed by `lfs_object_store_`:
@ -146,32 +120,10 @@ On Omnibus GitLab installations, the settings are prefixed by `lfs_object_store_
```
1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
1. Migrate any existing local LFS objects to the object storage:
```shell
gitlab-rake gitlab:lfs:migrate
```
This migrates existing LFS objects to object storage. New LFS objects
1. [Migrate any existing local LFS objects to the object storage](#migrating-to-object-storage).
New LFS objects
are forwarded to object storage unless
`gitlab_rails['lfs_object_store_background_upload']` and `gitlab_rails['lfs_object_store_direct_upload']` is set to `false`.
1. Optional. Verify all files migrated properly.
From [PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database)
(`sudo gitlab-psql -d gitlabhq_production`) verify `objectstg` below (where `file_store=2`) has count of all artifacts:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM lfs_objects;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify no files on disk in `artifacts` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/shared/lfs-objects -type f | grep -v tmp/cache | wc -l
```
### S3 for installations from source
@ -199,31 +151,68 @@ For source installations the settings are nested under `lfs:` and then
```
1. Save the file, and then [restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
1. Migrate any existing local LFS objects to the object storage:
1. [Migrate any existing local LFS objects to the object storage](#migrating-to-object-storage).
New LFS objects
are forwarded to object storage unless
`background_upload` and `direct_upload` is set to `false`.
```shell
sudo -u git -H bundle exec rake gitlab:lfs:migrate RAILS_ENV=production
```
### Migrating to object storage
This migrates existing LFS objects to object storage. New LFS objects
are forwarded to object storage unless `background_upload` and `direct_upload` is set to
`false`.
1. Optional. Verify all files migrated properly.
From PostgreSQL console (`sudo -u git -H psql -d gitlabhq_production`) verify `objectstg` below (where `file_store=2`) has count of all artifacts:
**Option 1: Rake task**
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM lfs_objects;
After [configuring the object storage](#storing-lfs-objects-in-remote-object-storage), use the following task to
migrate existing LFS objects from the local storage to the remote storage.
The processing is done in a background worker and requires **no downtime**.
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
For Omnibus GitLab:
Verify no files on disk in `artifacts` folder:
```shell
sudo gitlab-rake "gitlab:lfs:migrate"
```
```shell
sudo find /var/opt/gitlab/gitlab-rails/shared/lfs-objects -type f | grep -v tmp/cache | wc -l
```
For installations from source:
```shell
RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:lfs:migrate
```
You can optionally track progress and verify that all packages migrated successfully using the
[PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database):
- `sudo gitlab-rails dbconsole` for Omnibus GitLab instances.
- `sudo -u git -H psql -d gitlabhq_production` for source-installed instances.
Verify `objectstg` below (where `store=2`) has count of all LFS objects:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM lfs_objects;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify that there are no files on disk in the `objects` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/shared/lfs-objects -type f | grep -v tmp | wc -l
```
**Option 2: Rails console**
Log into the Rails console:
```shell
sudo gitlab-rails console
```
Upload LFS files manually
```ruby
LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object|
lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists?
end
```
### Migrating back to local storage

View File

@ -42,6 +42,28 @@ gitlab-rake "gitlab:uploads:migrate:all"
sudo RAILS_ENV=production -u git -H bundle exec rake gitlab:uploads:migrate:all
```
You can optionally track progress and verify that all packages migrated successfully using the
[PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database):
- `sudo gitlab-rails dbconsole` for Omnibus GitLab instances.
- `sudo -u git -H psql -d gitlabhq_production` for source-installed instances.
Verify `objectstg` below (where `store=2`) has count of all artifacts:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM uploads;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify that there are no files on disk in the `uploads` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/uploads -type f | grep -v tmp | wc -l
```
### Individual Rake tasks
If you already ran the [all-in-one Rake task](#all-in-one-rake-task), there is no need to run these

View File

@ -130,6 +130,28 @@ For GitLab 13.8 and earlier versions, you can use a workaround for the Rake task
end
```
You can optionally track progress and verify that all packages migrated successfully using the
[PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database):
- `sudo gitlab-rails dbconsole` for Omnibus GitLab instances.
- `sudo -u git -H psql -d gitlabhq_production` for source-installed instances.
Verify `objectstg` below (where `store=2`) has count of all states:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM terraform_states;
total | filesystem | objectstg
------+------------+-----------
15 | 0 | 15
```
Verify that there are no files on disk in the `terraform_state` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/shared/terraform_state -type f | wc -l
```
### S3-compatible connection settings
See [the available connection settings for different providers](object_storage.md#connection-settings).
@ -162,11 +184,7 @@ See [the available connection settings for different providers](object_storage.m
```
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
1. Migrate any existing local states to the object storage (GitLab 13.9 and later):
```shell
gitlab-rake gitlab:terraform_states:migrate
```
1. [Migrate any existing local states to the object storage](#migrate-to-object-storage)
**In installations from source:**
@ -187,8 +205,4 @@ See [the available connection settings for different providers](object_storage.m
```
1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
1. Migrate any existing local states to the object storage (GitLab 13.9 and later):
```shell
sudo -u git -H bundle exec rake gitlab:terraform_states:migrate RAILS_ENV=production
```
1. [Migrate any existing local states to the object storage](#migrate-to-object-storage)

View File

@ -106,24 +106,7 @@ _The uploads are stored by default in
```
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
1. Migrate any existing local uploads to the object storage using [`gitlab:uploads:migrate` Rake task](raketasks/uploads/migrate.md).
1. Optional: Verify all files migrated properly.
From [PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database)
(`sudo gitlab-psql -d gitlabhq_production`) verify `objectstg` below (where `store=2`) has count of all artifacts:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM uploads;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify no files on disk in `artifacts` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/uploads -type f | grep -v tmp | wc -l
```
1. Migrate any existing local uploads to the object storage using [`gitlab:uploads:migrate:all` Rake task](raketasks/uploads/migrate.md).
**In installations from source:**
@ -147,22 +130,6 @@ _The uploads are stored by default in
1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
1. Migrate any existing local uploads to the object storage using [`gitlab:uploads:migrate:all` Rake task](raketasks/uploads/migrate.md).
1. Optional: Verify all files migrated properly.
From PostgreSQL console (`sudo -u git -H psql -d gitlabhq_production`) verify `objectstg` below (where `file_store=2`) has count of all artifacts:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM uploads;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify no files on disk in `artifacts` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/uploads -type f | grep -v tmp | wc -l
```
#### OpenStack example
@ -189,23 +156,6 @@ _The uploads are stored by default in
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
1. Migrate any existing local uploads to the object storage using [`gitlab:uploads:migrate:all` Rake task](raketasks/uploads/migrate.md).
1. Optional: Verify all files migrated properly.
From [PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database)
(`sudo gitlab-psql -d gitlabhq_production`) verify `objectstg` below (where `store=2`) has count of all artifacts:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM uploads;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify no files on disk in `artifacts` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/uploads -type f | grep -v tmp | wc -l
```
---
@ -237,19 +187,3 @@ _The uploads are stored by default in
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
1. Migrate any existing local uploads to the object storage using [`gitlab:uploads:migrate:all` Rake task](raketasks/uploads/migrate.md).
1. Optional: Verify all files migrated properly.
From PostgreSQL console (`sudo -u git -H psql -d gitlabhq_production`) verify `objectstg` below (where `file_store=2`) has count of all artifacts:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM uploads;
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409
```
Verify no files on disk in `artifacts` folder:
```shell
sudo find /var/opt/gitlab/gitlab-rails/uploads -type f | grep -v tmp | wc -l
```

View File

@ -48,20 +48,9 @@ To make sure you can easily run the most recent stable release, we are working
hard to keep the update process simple and reliable.
If you are unable to follow our monthly release cycle, there are a couple of
cases you need to consider.
It is considered safe to jump between patch versions and minor versions within
one major version. For example, it is safe to:
- Upgrade the *minor* version. For example:
- `13.7.5` -> `13.10.5`
- `12.3.4` -> `12.10.11`
- Upgrade the *patch* version. For example:
- `13.0.4` -> `13.0.12`
- `12.10.1` -> `12.10.8`
cases you need to consider. Follow the
[upgrade paths guide](../update/index.md#upgrade-paths) to safely upgrade
between versions.
NOTE:
Version specific changes in Omnibus GitLab Linux packages can be found in [the Omnibus GitLab documentation](../update/package/index.md#version-specific-changes).

View File

@ -45,7 +45,6 @@ module Gitlab
end
def overwrite_headers(message, signed_email)
message.content_disposition = signed_email.content_disposition
message.content_transfer_encoding = signed_email.content_transfer_encoding
message.content_type = signed_email.content_type
end

View File

@ -355,6 +355,19 @@
category: testing
aggregation: weekly
feature_flag: users_expanding_widgets_usage_data
- name: users_expanding_testing_license_compliance_report
redis_slot: testing
category: testing
aggregation: weekly
feature_flag: users_expanding_widgets_usage_data
- name: users_visiting_testing_license_compliance_full_report
redis_slot: testing
category: testing
aggregation: weekly
- name: users_visiting_testing_manage_license_compliance
redis_slot: testing
category: testing
aggregation: weekly
# Container Security - Network Policies
- name: clusters_using_network_policies_ui
redis_slot: network_policies

View File

@ -6785,7 +6785,7 @@ msgstr ""
msgid "Checkout"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage per pack"
msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
msgstr ""
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"

View File

@ -28,7 +28,7 @@ describe('Blob viewer', () => {
loadFixtures('blob/show_readme.html');
$('#modal-upload-blob').remove();
mock.onGet(/blob\/master\/README\.md/).reply(200, {
mock.onGet(/blob\/.+\/README\.md/).reply(200, {
html: '<div>testing</div>',
});

View File

@ -34,7 +34,7 @@ RSpec.describe Projects::BlobController, '(JavaScript fixtures)', type: :control
get(:show, params: {
namespace_id: project.namespace,
project_id: project,
id: 'master/README.md'
id: "#{project.default_branch}/README.md"
})
expect(response).to be_successful

View File

@ -3,7 +3,7 @@ import { mount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
import { TEST_HOST } from 'helpers/test_constants';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import DeleteLabelModal from '~/vue_shared/components/delete_label_modal.vue';
import DeleteLabelModal from '~/labels/components/delete_label_modal.vue';
const MOCK_MODAL_DATA = {
labelName: 'label 1',
@ -11,7 +11,7 @@ const MOCK_MODAL_DATA = {
destroyPath: `${TEST_HOST}/1`,
};
describe('vue_shared/components/delete_label_modal', () => {
describe('~/labels/components/delete_label_modal', () => {
let wrapper;
const createComponent = () => {

View File

@ -2,8 +2,8 @@ import Vue from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import mountComponent from 'helpers/vue_mount_component_helper';
import axios from '~/lib/utils/axios_utils';
import promoteLabelModal from '~/pages/projects/labels/components/promote_label_modal.vue';
import eventHub from '~/pages/projects/labels/event_hub';
import promoteLabelModal from '~/labels/components/promote_label_modal.vue';
import eventHub from '~/labels/event_hub';
describe('Promote label modal', () => {
let vm;

View File

@ -1,5 +1,5 @@
import { TEST_HOST } from 'helpers/test_constants';
import initDeleteLabelModal from '~/labels/delete_label_modal';
import { initDeleteLabelModal } from '~/labels';
describe('DeleteLabelModal', () => {
const buttons = [

View File

@ -124,19 +124,7 @@ describe('DropdownContent', () => {
expect(wrapper.emitted('setLabels')).toEqual([[[updatedLabel]]]);
});
it('does not render header on standalone variant', () => {
createComponent({ props: { variant: DropdownVariant.Standalone } });
expect(findDropdownHeader().exists()).toBe(false);
});
it('renders header on embedded variant', () => {
createComponent({ props: { variant: DropdownVariant.Embedded } });
expect(findDropdownHeader().exists()).toBe(true);
});
it('renders header on sidebar variant', () => {
it('renders header', () => {
createComponent();
expect(findDropdownHeader().exists()).toBe(true);

View File

@ -9,6 +9,7 @@ describe('DropdownHeader', () => {
const createComponent = ({
showDropdownContentsCreateView = false,
labelsFetchInProgress = false,
isStandalone = false,
} = {}) => {
wrapper = extendedWrapper(
shallowMount(DropdownHeader, {
@ -18,6 +19,7 @@ describe('DropdownHeader', () => {
labelsCreateTitle: 'Create label',
labelsListTitle: 'Select label',
searchKey: '',
isStandalone,
},
stubs: {
GlSearchBoxByType,
@ -32,6 +34,7 @@ describe('DropdownHeader', () => {
const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
const findGoBackButton = () => wrapper.findByTestId('go-back-button');
const findDropdownTitle = () => wrapper.findByTestId('dropdown-header-title');
beforeEach(() => {
createComponent();
@ -72,4 +75,18 @@ describe('DropdownHeader', () => {
},
);
});
describe('Standalone variant', () => {
beforeEach(() => {
createComponent({ isStandalone: true });
});
it('renders search input', () => {
expect(findSearchInput().exists()).toBe(true);
});
it('does not render title', async () => {
expect(findDropdownTitle().exists()).toBe(false);
});
});
});

View File

@ -75,9 +75,9 @@ describe('LabelsSelectRoot', () => {
wrapper.destroy();
});
it('renders component with classes `labels-select-wrapper position-relative`', () => {
it('renders component with classes `labels-select-wrapper gl-relative`', () => {
createComponent();
expect(wrapper.classes()).toEqual(['labels-select-wrapper', 'position-relative']);
expect(wrapper.classes()).toEqual(['labels-select-wrapper', 'gl-relative']);
});
it.each`

View File

@ -50,6 +50,7 @@ RSpec.describe Gitlab::Email::Hook::SmimeSignatureInterceptor do
expect(mail.header['To'].value).to eq('test@example.com')
expect(mail.header['From'].value).to eq('info@example.com')
expect(mail.header['Content-Type'].value).to match('multipart/signed').and match('protocol="application/x-pkcs7-signature"')
expect(mail.header.include?('Content-Disposition')).to eq(false)
# verify signature and obtain pkcs7 encoded content
p7enc = Gitlab::Email::Smime::Signer.verify_signature(

View File

@ -82,7 +82,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
end.new(time_frame: 'all')
end
it 'calculates a correct result' do
it 'calculates a correct result', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348139' do
expect(subject.value).to be_within(Gitlab::Database::PostgresHll::BatchDistinctCounter::ERROR_RATE).percent_of(3)
end

View File

@ -69,7 +69,7 @@ RSpec.describe 'Query current user todos' do
QUERY
end
it 'avoids N+1 queries', :request_store do
it 'avoids N+1 queries', :request_store, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338671' do
control = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
project2 = create(:project)

View File

@ -554,44 +554,6 @@ RSpec.describe Git::BranchPushService, services: true do
end
end
describe "housekeeping", :clean_gitlab_redis_cache, :clean_gitlab_redis_queues, :clean_gitlab_redis_shared_state do
let(:housekeeping) { Repositories::HousekeepingService.new(project) }
before do
allow(Repositories::HousekeepingService).to receive(:new).and_return(housekeeping)
end
it 'does not perform housekeeping when not needed' do
expect(housekeeping).not_to receive(:execute)
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end
context 'when housekeeping is needed' do
before do
allow(housekeeping).to receive(:needed?).and_return(true)
end
it 'performs housekeeping' do
expect(housekeeping).to receive(:execute)
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end
it 'does not raise an exception' do
allow(housekeeping).to receive(:try_obtain_lease).and_return(false)
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end
end
it 'increments the push counter' do
expect(housekeeping).to receive(:increment!)
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end
end
describe "CI environments" do
context 'create branch' do
let(:oldrev) { blankrev }

View File

@ -161,6 +161,50 @@ RSpec.describe Git::ProcessRefChangesService do
end
end
end
describe "housekeeping", :clean_gitlab_redis_cache, :clean_gitlab_redis_queues, :clean_gitlab_redis_shared_state do
let(:housekeeping) { Repositories::HousekeepingService.new(project) }
before do
allow(Repositories::HousekeepingService).to receive(:new).and_return(housekeeping)
allow(push_service_class)
.to receive(:new)
.with(project, project.owner, hash_including(execute_project_hooks: true, create_push_event: true))
.exactly(changes.count).times
.and_return(service)
end
it 'does not perform housekeeping when not needed' do
expect(housekeeping).not_to receive(:execute)
subject.execute
end
context 'when housekeeping is needed' do
before do
allow(housekeeping).to receive(:needed?).and_return(true)
end
it 'performs housekeeping' do
expect(housekeeping).to receive(:execute)
subject.execute
end
it 'does not raise an exception' do
allow(housekeeping).to receive(:try_obtain_lease).and_return(false)
subject.execute
end
end
it 'increments the push counter' do
expect(housekeeping).to receive(:increment!)
subject.execute
end
end
end
context 'branch changes' do