Commit a7df1d87 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent e3e30055
export const breakpoints = {
lg: 1200,
md: 992,
sm: 768,
xs: 0,
};
const BreakpointInstance = {
windowWidth: () => window.innerWidth,
getBreakpointSize() {
const windowWidth = this.windowWidth();
const breakpoint = Object.keys(breakpoints).find(key => windowWidth > breakpoints[key]);
return breakpoint;
},
isDesktop() {
return ['lg', 'md'].includes(this.getBreakpointSize());
},
};
export default BreakpointInstance;
......@@ -23,6 +23,7 @@ module Ci
container_scanning: 'gl-container-scanning-report.json',
dast: 'gl-dast-report.json',
license_management: 'gl-license-management-report.json',
license_scanning: 'gl-license-management-report.json',
performance: 'performance.json',
metrics: 'metrics.txt'
}.freeze
......@@ -46,6 +47,7 @@ module Ci
container_scanning: :raw,
dast: :raw,
license_management: :raw,
license_scanning: :raw,
performance: :raw
}.freeze
......@@ -104,6 +106,7 @@ module Ci
dast: 8, ## EE-specific
codequality: 9, ## EE-specific
license_management: 10, ## EE-specific
license_scanning: 101, ## EE-specific till 13.0
performance: 11, ## EE-specific
metrics: 12 ## EE-specific
}
......
......@@ -3,7 +3,7 @@
module Clusters
module Applications
class Runner < ApplicationRecord
VERSION = '0.11.0'
VERSION = '0.12.0'
self.table_name = 'clusters_applications_runners'
......
= render 'shared/projects/list', projects: @projects, ci: true, user: current_user
= render 'shared/projects/list', projects: @projects, pipeline_status: Feature.enabled?(:dashboard_pipeline_status, default_enabled: true), user: current_user
- is_explore_page = defined?(explore_page) && explore_page
= render 'shared/projects/list', projects: projects, user: current_user, explore_page: is_explore_page
= render 'shared/projects/list', projects: projects, user: current_user, explore_page: is_explore_page, pipeline_status: Feature.enabled?(:dashboard_pipeline_status, default_enabled: true)
......@@ -6,7 +6,6 @@
- merge_requests = true unless local_assigns[:merge_requests] == false
- issues = true unless local_assigns[:issues] == false
- pipeline_status = true unless local_assigns[:pipeline_status] == false
- ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true
- user = local_assigns[:user]
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
......@@ -40,7 +39,7 @@
- projects.each_with_index do |project, i|
- css_class = (i >= projects_limit) || project.pending_delete? ? 'hide' : nil
= render "shared/projects/project", project: project, skip_namespace: skip_namespace,
avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar,
avatar: avatar, stars: stars, css_class: css_class, use_creator_avatar: use_creator_avatar,
forks: forks, show_last_commit_as_description: show_last_commit_as_description, user: user, merge_requests: merge_requests,
issues: issues, pipeline_status: pipeline_status, compact_mode: compact_mode
= paginate_collection(projects, remote: remote) unless skip_pagination
......
---
title: Update GitLab Runner Helm Chart to 0.12.0
merge_request: 22566
author:
type: other
......@@ -119,4 +119,16 @@ at GitLab so far:
## Limitations
- [`danger local` does not work on GitLab](https://github.com/danger/danger/issues/458)
- Danger output is not added to a merge request comment if working on a fork.
- Danger output is not added to a merge request comment if working on
a fork. This happens because the secret variable from the canonical
project is not shared to forks.
To work around this, you can add an [environment
variable](../ci/variables/README.md) called
`DANGER_GITLAB_API_TOKEN` with a personal API token to your
fork. That way the danger comments will be made from CI using that
API token instead.
Making the variable
[masked](../ci/variables/README.md#masked-variables) will make sure
it doesn't show up in the job logs. The variable cannot be
[protected](../ci/variables/README.md#protected-environment-variables),
as it needs to be present for all feature branches.
......@@ -11,7 +11,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS = %i[junit codequality sast dependency_scanning container_scanning dast performance license_management metrics].freeze
ALLOWED_KEYS = %i[junit codequality sast dependency_scanning container_scanning dast performance license_management license_scanning metrics].freeze
attributes ALLOWED_KEYS
......@@ -28,6 +28,7 @@ module Gitlab
validates :dast, array_of_strings_or_string: true
validates :performance, array_of_strings_or_string: true
validates :license_management, array_of_strings_or_string: true
validates :license_scanning, array_of_strings_or_string: true
validates :metrics, array_of_strings_or_string: true
end
end
......
......@@ -211,6 +211,18 @@ module Gitlab
end
# rubocop:enable Gitlab/RailsLogger
def validate_foreign_key(source, column, name: nil)
fk_name = name || concurrent_foreign_key_name(source, column)
unless foreign_key_exists?(source, name: fk_name)
raise "cannot find #{fk_name} on #{source} table"
end
disable_statement_timeout do
execute("ALTER TABLE #{source} VALIDATE CONSTRAINT #{fk_name};")
end
end
def foreign_key_exists?(source, target = nil, **options)
foreign_keys(source).any? do |foreign_key|
tables_match?(target.to_s, foreign_key.to_table.to_s) &&
......
......@@ -173,6 +173,19 @@ describe 'Dashboard Projects' do
end
end
shared_examples 'hidden pipeline status' do
it 'does not show the pipeline status' do
visit dashboard_projects_path
page.within('.controls') do
expect(page).not_to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']")
expect(page).not_to have_css('.ci-status-link')
expect(page).not_to have_css('.ci-status-icon-success')
expect(page).not_to have_link('Pipeline: passed')
end
end
end
context 'guest user of project and project has private pipelines' do
let(:guest_user) { create(:user) }
......@@ -182,16 +195,15 @@ describe 'Dashboard Projects' do
sign_in(guest_user)
end
it 'shows that the last pipeline passed' do
visit dashboard_projects_path
it_behaves_like 'hidden pipeline status'
end
page.within('.controls') do
expect(page).not_to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']")
expect(page).not_to have_css('.ci-status-link')
expect(page).not_to have_css('.ci-status-icon-success')
expect(page).not_to have_link('Pipeline: passed')
end
context 'when dashboard_pipeline_status is disabled' do
before do
stub_feature_flags(dashboard_pipeline_status: false)
end
it_behaves_like 'hidden pipeline status'
end
end
......
import bp, { breakpoints } from '~/breakpoints';
describe('breakpoints', () => {
Object.keys(breakpoints).forEach(key => {
const size = breakpoints[key];
it(`returns ${key} when larger than ${size}`, () => {
jest.spyOn(bp, 'windowWidth').mockReturnValue(size + 10);
expect(bp.getBreakpointSize()).toBe(key);
});
});
describe('isDesktop', () => {
it('returns true when screen size is medium', () => {
jest.spyOn(bp, 'windowWidth').mockReturnValue(breakpoints.md + 10);
expect(bp.isDesktop()).toBe(true);
});
it('returns false when screen size is small', () => {
jest.spyOn(bp, 'windowWidth').mockReturnValue(breakpoints.sm + 10);
expect(bp.isDesktop()).toBe(false);
});
});
});
import { mount, createLocalVue } from '@vue/test-utils';
import { mount } from '@vue/test-utils';
import createStore from '~/notes/stores';
import diffDiscussionHeader from '~/notes/components/diff_discussion_header.vue';
......@@ -18,11 +18,9 @@ describe('diff_discussion_header component', () => {
window.mrTabs = {};
store = createStore();
const localVue = createLocalVue();
wrapper = mount(diffDiscussionHeader, {
store,
propsData: { discussion: discussionMock },
localVue,
sync: false,
});
});
......
import { shallowMount, mount, createLocalVue } from '@vue/test-utils';
import { shallowMount, mount } from '@vue/test-utils';
import { discussionMock } from '../../notes/mock_data';
import DiscussionActions from '~/notes/components/discussion_actions.vue';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
......@@ -22,12 +22,10 @@ const createUnallowedNote = () =>
describe('DiscussionActions', () => {
let wrapper;
const createComponentFactory = (shallow = true) => props => {
const localVue = createLocalVue();
const store = createStore();
const mountFn = shallow ? shallowMount : mount;
wrapper = mountFn(DiscussionActions, {
localVue,
store,
propsData: {
discussion: discussionMock,
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import '~/behaviors/markdown/render_gfm';
import { SYSTEM_NOTE } from '~/notes/constants';
import DiscussionNotes from '~/notes/components/discussion_notes.vue';
......@@ -9,8 +9,6 @@ import SystemNote from '~/vue_shared/components/notes/system_note.vue';
import createStore from '~/notes/stores';
import { noteableDataMock, discussionMock, notesDataMock } from '../../notes/mock_data';
const localVue = createLocalVue();
describe('DiscussionNotes', () => {
let wrapper;
......@@ -20,7 +18,6 @@ describe('DiscussionNotes', () => {
store.dispatch('setNotesData', notesDataMock);
wrapper = shallowMount(DiscussionNotes, {
localVue,
store,
propsData: {
discussion: discussionMock,
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
const localVue = createLocalVue();
const buttonText = 'Test Button Text';
describe('ReplyPlaceholder', () => {
......@@ -11,7 +10,6 @@ describe('ReplyPlaceholder', () => {
beforeEach(() => {
wrapper = shallowMount(ReplyPlaceholder, {
localVue,
propsData: {
buttonText,
},
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue';
const buttonTitle = 'Resolve discussion';
describe('resolveDiscussionButton', () => {
let wrapper;
let localVue;
const factory = options => {
localVue = createLocalVue();
wrapper = shallowMount(resolveDiscussionButton, {
localVue,
...options,
});
};
......@@ -69,7 +66,7 @@ describe('resolveDiscussionButton', () => {
const button = wrapper.find({ ref: 'isResolvingIcon' });
localVue.nextTick(() => {
wrapper.vm.$nextTick(() => {
expect(button.exists()).toEqual(false);
});
});
......
import $ from 'helpers/jquery';
import AxiosMockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import { mount, createLocalVue } from '@vue/test-utils';
import { mount } from '@vue/test-utils';
import { setTestTimeout } from 'helpers/timeout';
import axios from '~/lib/utils/axios_utils';
import NotesApp from '~/notes/components/notes_app.vue';
......@@ -48,7 +48,6 @@ describe('note_app', () => {
notesData: mockData.notesDataMock,
userData: mockData.userDataMock,
};
const localVue = createLocalVue();
return mount(
{
......@@ -63,7 +62,6 @@ describe('note_app', () => {
attachToDocument: true,
propsData,
store,
localVue,
sync: false,
},
);
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import NoteEditedText from '~/notes/components/note_edited_text.vue';
const localVue = createLocalVue();
const propsData = {
actionText: 'Edited',
className: 'foo-bar',
......@@ -21,7 +20,6 @@ describe('NoteEditedText', () => {
beforeEach(() => {
wrapper = shallowMount(NoteEditedText, {
localVue,
propsData,
sync: false,
attachToDocument: true,
......
......@@ -2,11 +2,10 @@ import SnippetApp from '~/snippets/components/app.vue';
import SnippetHeader from '~/snippets/components/snippet_header.vue';
import { GlLoadingIcon } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
describe('Snippet view app', () => {
let wrapper;
const localVue = createLocalVue();
const defaultProps = {
snippetGid: 'gid://gitlab/PersonalSnippet/42',
};
......@@ -23,7 +22,6 @@ describe('Snippet view app', () => {
wrapper = shallowMount(SnippetApp, {
sync: false,
mocks: { $apollo },
localVue,
propsData: {
...props,
},
......
......@@ -2,11 +2,10 @@ import SnippetHeader from '~/snippets/components/snippet_header.vue';
import DeleteSnippetMutation from '~/snippets/mutations/deleteSnippet.mutation.graphql';
import { ApolloMutation } from 'vue-apollo';
import { GlButton, GlModal } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
describe('Snippet header component', () => {
let wrapper;
const localVue = createLocalVue();
const snippet = {
snippet: {
id: 'gid://gitlab/PersonalSnippet/50',
......@@ -64,7 +63,6 @@ describe('Snippet header component', () => {
wrapper = shallowMount(SnippetHeader, {
sync: false,
mocks: { $apollo },
localVue,
propsData: {
...defaultProps,
},
......
......@@ -29,7 +29,7 @@ describe('Merge Requests Artifacts list app', () => {
});
const createComponent = () => {
wrapper = mount(localVue.extend(ArtifactsListApp), {
wrapper = mount(ArtifactsListApp, {
propsData: {
endpoint: TEST_HOST,
},
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
import ArtifactsList from '~/vue_merge_request_widget/components/artifacts_list.vue';
import { artifactsList } from './mock_data';
describe('Artifacts List', () => {
let wrapper;
const localVue = createLocalVue();
const data = {
artifacts: artifactsList,
};
const mountComponent = props => {
wrapper = shallowMount(localVue.extend(ArtifactsList), {
wrapper = shallowMount(ArtifactsList, {
propsData: {
...props,
},
sync: false,
localVue,
});
};
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import MrWidgetContainer from '~/vue_merge_request_widget/components/mr_widget_container.vue';
const BODY_HTML = '<div class="test-body">Hello World</div>';
......@@ -8,10 +8,7 @@ describe('MrWidgetContainer', () => {
let wrapper;
const factory = (options = {}) => {
const localVue = createLocalVue();
wrapper = shallowMount(localVue.extend(MrWidgetContainer), {
localVue,
wrapper = shallowMount(MrWidgetContainer, {
...options,
});
};
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import MrWidgetIcon from '~/vue_merge_request_widget/components/mr_widget_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
......@@ -8,14 +8,11 @@ describe('MrWidgetIcon', () => {
let wrapper;
beforeEach(() => {
const localVue = createLocalVue();
wrapper = shallowMount(localVue.extend(MrWidgetIcon), {
wrapper = shallowMount(MrWidgetIcon, {
propsData: {
name: TEST_ICON,
},
sync: false,
localVue,
});
});
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
const localVue = createLocalVue();
const testCommitMessage = 'Test commit message';
const testLabel = 'Test label';
const testInputId = 'test-input-id';
......@@ -10,8 +9,7 @@ describe('Commits edit component', () => {
let wrapper;
const createComponent = (slots = {}) => {
wrapper = shallowMount(localVue.extend(CommitEdit), {
localVue,
wrapper = shallowMount(CommitEdit, {
sync: false,
propsData: {
value: testCommitMessage,
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import { GlDropdownItem } from '@gitlab/ui';
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
const localVue = createLocalVue();
const commits = [
{
title: 'Commit 1',
......@@ -25,8 +24,7 @@ describe('Commits message dropdown component', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMount(localVue.extend(CommitMessageDropdown), {
localVue,
wrapper = shallowMount(CommitMessageDropdown, {
sync: false,
propsData: {
commits,
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
import Icon from '~/vue_shared/components/icon.vue';
const localVue = createLocalVue();
describe('Commits header component', () => {
let wrapper;
const createComponent = props => {
wrapper = shallowMount(localVue.extend(CommitsHeader), {
localVue,
wrapper = shallowMount(CommitsHeader, {
sync: false,
propsData: {
isSquashEnabled: false,
......
import { mount, createLocalVue } from '@vue/test-utils';
import { mount } from '@vue/test-utils';
import DeploymentViewButton from '~/vue_merge_request_widget/components/deployment/deployment_view_button.vue';
import ReviewAppLink from '~/vue_merge_request_widget/components/review_app_link.vue';
import deploymentMockData from './deployment_mock_data';
......@@ -7,10 +7,7 @@ describe('Deployment View App button', () => {
let wrapper;
const factory = (options = {}) => {
const localVue = createLocalVue();
wrapper = mount(localVue.extend(DeploymentViewButton), {
localVue,
wrapper = mount(DeploymentViewButton, {
...options,
});
};
......
......@@ -3,7 +3,6 @@ import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import MergeRequestTabs from '~/merge_request_tabs';
import '~/commit/pipelines/pipelines_bundle';
import '~/breakpoints';
import '~/lib/utils/common_utils';
import 'vendor/jquery.scrollTo';
import initMrPage from './helpers/init_vue_mr_page_helper';
......
......@@ -41,6 +41,7 @@ describe Gitlab::Ci::Config::Entry::Reports do
:container_scanning | 'gl-container-scanning-report.json'
:dast | 'gl-dast-report.json'
:license_management | 'gl-license-management-report.json'
:license_scanning | 'gl-license-management-report.json'
:performance | 'performance.json'
end
......
......@@ -347,6 +347,48 @@ describe Gitlab::Database::MigrationHelpers do
end
end
describe '#validate_foreign_key' do
context 'when name is provided' do
it 'does not infer the foreign key constraint name' do
expect(model).to receive(:foreign_key_exists?).with(:projects, name: :foo).and_return(true)
aggregate_failures do
expect(model).not_to receive(:concurrent_foreign_key_name)
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/ALTER TABLE projects VALIDATE CONSTRAINT/)
expect(model).to receive(:execute).ordered.with(/RESET ALL/)
end
model.validate_foreign_key(:projects, :user_id, name: :foo)
end
end
context 'when name is not provided' do
it 'infers the foreign key constraint name' do
expect(model).to receive(:foreign_key_exists?).with(:projects, name: anything).and_return(true)
aggregate_failures do
expect(model).to receive(:concurrent_foreign_key_name)
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/ALTER TABLE projects VALIDATE CONSTRAINT/)
expect(model).to receive(:execute).ordered.with(/RESET ALL/)
end
model.validate_foreign_key(:projects, :user_id)
end
context 'when the inferred foreign key constraint does not exist' do
it 'raises an error' do
expect(model).to receive(:foreign_key_exists?).and_return(false)
expect { model.validate_foreign_key(:projects, :user_id) }.to raise_error(/cannot find/)
end
end
end
end
describe '#concurrent_foreign_key_name' do
it 'returns the name for a foreign key' do
name = model.concurrent_foreign_key_name(:this_is_a_very_long_table_name,
......
......@@ -32,7 +32,8 @@ describe Ci::RetryBuildService do
job_artifacts_metadata job_artifacts_trace job_artifacts_junit
job_artifacts_sast job_artifacts_dependency_scanning
job_artifacts_container_scanning job_artifacts_dast
job_artifacts_license_management job_artifacts_performance
job_artifacts_license_management job_artifacts_license_scanning
job_artifacts_performance
job_artifacts_codequality job_artifacts_metrics scheduled_at
job_variables waiting_for_resource_at].freeze
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment