Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
9724bdc4c0
commit
e28ed4a6b2
|
@ -37,10 +37,22 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
from: this.paramsFrom,
|
||||
to: this.paramsTo,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$refs.form.submit();
|
||||
},
|
||||
onSwapRevision() {
|
||||
[this.from, this.to] = [this.to, this.from]; // swaps 'from' and 'to'
|
||||
},
|
||||
onSelectRevision({ direction, revision }) {
|
||||
this[direction] = revision; // direction is either 'from' or 'to'
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -57,18 +69,29 @@ export default {
|
|||
:refs-project-path="refsProjectPath"
|
||||
revision-text="Source"
|
||||
params-name="to"
|
||||
:params-branch="paramsTo"
|
||||
:params-branch="to"
|
||||
data-testid="sourceRevisionDropdown"
|
||||
@selectRevision="onSelectRevision"
|
||||
/>
|
||||
<div class="compare-ellipsis gl-display-inline" data-testid="ellipsis">...</div>
|
||||
<revision-dropdown
|
||||
:refs-project-path="refsProjectPath"
|
||||
revision-text="Target"
|
||||
params-name="from"
|
||||
:params-branch="paramsFrom"
|
||||
:params-branch="from"
|
||||
data-testid="targetRevisionDropdown"
|
||||
@selectRevision="onSelectRevision"
|
||||
/>
|
||||
<gl-button category="primary" variant="success" class="gl-ml-3" @click="onSubmit">
|
||||
{{ s__('CompareRevisions|Compare') }}
|
||||
</gl-button>
|
||||
<gl-button
|
||||
data-testid="swapRevisionsButton"
|
||||
class="btn btn-default gl-button gl-ml-3"
|
||||
@click="onSwapRevision"
|
||||
>
|
||||
{{ s__('CompareRevisions|Swap revisions') }}
|
||||
</gl-button>
|
||||
<gl-button
|
||||
v-if="projectMergeRequestPath"
|
||||
:href="projectMergeRequestPath"
|
||||
|
|
|
@ -55,6 +55,11 @@ export default {
|
|||
return this.filteredTags.length;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
paramsBranch(newBranch) {
|
||||
this.setSelectedRevision(newBranch);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchBranchesAndTags();
|
||||
},
|
||||
|
@ -83,10 +88,14 @@ export default {
|
|||
return this.paramsBranch || s__('CompareRevisions|Select branch/tag');
|
||||
},
|
||||
onClick(revision) {
|
||||
this.selectedRevision = revision;
|
||||
this.setSelectedRevision(revision);
|
||||
},
|
||||
onSearchEnter() {
|
||||
this.selectedRevision = this.searchTerm;
|
||||
this.setSelectedRevision(this.searchTerm);
|
||||
},
|
||||
setSelectedRevision(revision) {
|
||||
this.selectedRevision = revision || s__('CompareRevisions|Select branch/tag');
|
||||
this.$emit('selectRevision', { direction: this.paramsName, revision });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
%code= subkey.fingerprint
|
||||
.float-right
|
||||
%span.key-created-at
|
||||
= s_('Profiles|Created %{time_ago}'.html_safe) % { time_ago:time_ago_with_tooltip(key.created_at)}
|
||||
= s_('Profiles|Created %{time_ago}'.html_safe) % { time_ago: time_ago_with_tooltip(key.created_at) }
|
||||
= link_to profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.') }, method: :delete, class: "gl-button btn btn-danger gl-ml-3" do
|
||||
%span.sr-only= _('Remove')
|
||||
= sprite_icon('remove')
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Re-add swap revisions feature (legacy)
|
||||
merge_request: 57802
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
redirect_to: 'avoiding_downtime_in_migrations.md'
|
||||
---
|
||||
|
||||
This document was moved to [another location](avoiding_downtime_in_migrations.md).
|
||||
|
||||
<!-- This redirect file can be deleted after <2021-07-01>. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
|
|
@ -7892,6 +7892,9 @@ msgstr ""
|
|||
msgid "CompareRevisions|Select target project"
|
||||
msgstr ""
|
||||
|
||||
msgid "CompareRevisions|Swap revisions"
|
||||
msgstr ""
|
||||
|
||||
msgid "CompareRevisions|Tags"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ module QA
|
|||
# Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect
|
||||
# scenario with other tests that aren't considered orchestrated.
|
||||
# It also runs on staging using nfs-file07 as non-cluster storage and nfs-file22 as cluster/praefect storage
|
||||
context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/974', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284645', type: :investigating } do
|
||||
context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1755', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284645', type: :investigating } do
|
||||
let(:source_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } }
|
||||
let(:destination_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } }
|
||||
let(:project) do
|
||||
|
|
|
@ -8,7 +8,7 @@ jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
|
|||
const projectCompareIndexPath = 'some/path';
|
||||
const refsProjectPath = 'some/refs/path';
|
||||
const paramsFrom = 'master';
|
||||
const paramsTo = 'master';
|
||||
const paramsTo = 'some-other-branch';
|
||||
|
||||
describe('CompareApp component', () => {
|
||||
let wrapper;
|
||||
|
@ -36,6 +36,9 @@ describe('CompareApp component', () => {
|
|||
createComponent();
|
||||
});
|
||||
|
||||
const findSourceDropdown = () => wrapper.find('[data-testid="sourceRevisionDropdown"]');
|
||||
const findTargetDropdown = () => wrapper.find('[data-testid="targetRevisionDropdown"]');
|
||||
|
||||
it('renders component with prop', () => {
|
||||
expect(wrapper.props()).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -62,12 +65,31 @@ describe('CompareApp component', () => {
|
|||
expect(wrapper.find('[data-testid="ellipsis"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('render Source and Target BranchDropdown components', () => {
|
||||
const branchDropdowns = wrapper.findAll(RevisionDropdown);
|
||||
describe('Source and Target BranchDropdown components', () => {
|
||||
const findAllBranchDropdowns = () => wrapper.findAll(RevisionDropdown);
|
||||
|
||||
expect(branchDropdowns.length).toBe(2);
|
||||
expect(branchDropdowns.at(0).props('revisionText')).toBe('Source');
|
||||
expect(branchDropdowns.at(1).props('revisionText')).toBe('Target');
|
||||
it('renders the components with the correct props', () => {
|
||||
expect(findAllBranchDropdowns().length).toBe(2);
|
||||
expect(findSourceDropdown().props('revisionText')).toBe('Source');
|
||||
expect(findTargetDropdown().props('revisionText')).toBe('Target');
|
||||
});
|
||||
|
||||
it('sets the revision when the "selectRevision" event is emitted', async () => {
|
||||
findSourceDropdown().vm.$emit('selectRevision', {
|
||||
direction: 'to',
|
||||
revision: 'some-source-revision',
|
||||
});
|
||||
|
||||
findTargetDropdown().vm.$emit('selectRevision', {
|
||||
direction: 'from',
|
||||
revision: 'some-target-revision',
|
||||
});
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(findTargetDropdown().props('paramsBranch')).toBe('some-target-revision');
|
||||
expect(findSourceDropdown().props('paramsBranch')).toBe('some-source-revision');
|
||||
});
|
||||
});
|
||||
|
||||
describe('compare button', () => {
|
||||
|
@ -87,6 +109,27 @@ describe('CompareApp component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('swap revisions button', () => {
|
||||
const findSwapRevisionsButton = () => wrapper.find('[data-testid="swapRevisionsButton"]');
|
||||
|
||||
it('renders the swap revisions button', () => {
|
||||
expect(findSwapRevisionsButton().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('has the correct text', () => {
|
||||
expect(findSwapRevisionsButton().text()).toBe('Swap revisions');
|
||||
});
|
||||
|
||||
it('swaps revisions when clicked', async () => {
|
||||
findSwapRevisionsButton().vm.$emit('click');
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(findTargetDropdown().props('paramsBranch')).toBe(paramsTo);
|
||||
expect(findSourceDropdown().props('paramsBranch')).toBe(paramsFrom);
|
||||
});
|
||||
});
|
||||
|
||||
describe('merge request buttons', () => {
|
||||
const findProjectMrButton = () => wrapper.find('[data-testid="projectMrButton"]');
|
||||
const findCreateMrButton = () => wrapper.find('[data-testid="createMrButton"]');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { GlDropdown } from '@gitlab/ui';
|
||||
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import AxiosMockAdapter from 'axios-mock-adapter';
|
||||
import createFlash from '~/flash';
|
||||
|
@ -29,6 +29,7 @@ describe('RevisionDropdown component', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
axiosMock = new AxiosMockAdapter(axios);
|
||||
createComponent();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -39,7 +40,6 @@ describe('RevisionDropdown component', () => {
|
|||
const findGlDropdown = () => wrapper.find(GlDropdown);
|
||||
|
||||
it('sets hidden input', () => {
|
||||
createComponent();
|
||||
expect(wrapper.find('input[type="hidden"]').attributes('value')).toBe(
|
||||
defaultProps.paramsBranch,
|
||||
);
|
||||
|
@ -68,8 +68,6 @@ describe('RevisionDropdown component', () => {
|
|||
Tags: undefined,
|
||||
});
|
||||
|
||||
createComponent();
|
||||
|
||||
await axios.waitForAll();
|
||||
|
||||
expect(wrapper.vm.branches).toEqual([]);
|
||||
|
@ -79,15 +77,12 @@ describe('RevisionDropdown component', () => {
|
|||
it('shows flash message on error', async () => {
|
||||
axiosMock.onGet('some/invalid/path').replyOnce(404);
|
||||
|
||||
createComponent();
|
||||
|
||||
await wrapper.vm.fetchBranchesAndTags();
|
||||
expect(createFlash).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('GlDropdown component', () => {
|
||||
it('renders props', () => {
|
||||
createComponent();
|
||||
expect(wrapper.props()).toEqual(expect.objectContaining(defaultProps));
|
||||
});
|
||||
|
||||
|
@ -99,8 +94,22 @@ describe('RevisionDropdown component', () => {
|
|||
});
|
||||
|
||||
it('display params branch text', () => {
|
||||
createComponent();
|
||||
expect(findGlDropdown().props('text')).toBe(defaultProps.paramsBranch);
|
||||
});
|
||||
|
||||
it('emits a "selectRevision" event when a revision is selected', async () => {
|
||||
const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem);
|
||||
const findFirstGlDropdownItem = () => findGlDropdownItems().at(0);
|
||||
|
||||
wrapper.setData({ branches: ['some-branch'] });
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
findFirstGlDropdownItem().vm.$emit('click');
|
||||
|
||||
expect(wrapper.emitted()).toEqual({
|
||||
selectRevision: [[{ direction: 'from', revision: 'some-branch' }]],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -123,6 +123,16 @@ RSpec.describe Tooling::KubernetesClient do
|
|||
|
||||
it_behaves_like 'a kubectl command to delete resources by older than given creation time'
|
||||
end
|
||||
|
||||
context 'with no resources found' do
|
||||
let(:resource_names) { [] }
|
||||
|
||||
it 'does not call #delete_by_exact_names' do
|
||||
expect(subject).not_to receive(:delete_by_exact_names)
|
||||
|
||||
subject.cleanup_by_created_at(resource_type: resource_type, created_before: two_days_ago)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#raw_resource_names' do
|
||||
|
|
|
@ -22,6 +22,8 @@ module Tooling
|
|||
|
||||
def cleanup_by_created_at(resource_type:, created_before:, wait: true)
|
||||
resource_names = resource_names_created_before(resource_type: resource_type, created_before: created_before)
|
||||
return if resource_names.empty?
|
||||
|
||||
delete_by_exact_names(resource_type: resource_type, resource_names: resource_names, wait: wait)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue