Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-11-26 03:11:11 +00:00
parent 118b785094
commit 7de2fb40ba
19 changed files with 27 additions and 504 deletions

View File

@ -1,127 +0,0 @@
<script>
import { GlIcon, GlLink } from '@gitlab/ui';
import { __ } from '~/locale';
import createFlash from '~/flash';
import { helpPagePath } from '~/helpers/help_page_helper';
import codeOwnersInfoQuery from '../queries/code_owners_info.query.graphql';
import getRefMixin from '../mixins/get_ref';
export default {
i18n: {
title: __('Code owners'),
about: __('About this feature'),
andSeparator: __('and'),
errorMessage: __('An error occurred while loading code owners.'),
},
codeOwnersHelpPath: helpPagePath('user/project/code_owners'),
components: {
GlIcon,
GlLink,
},
mixins: [getRefMixin],
apollo: {
project: {
query: codeOwnersInfoQuery,
variables() {
return {
projectPath: this.projectPath,
filePath: this.filePath,
ref: this.ref,
};
},
skip() {
return !this.filePath;
},
result() {
this.isFetching = false;
},
error() {
createFlash({ message: this.$options.i18n.errorMessage });
},
},
},
props: {
projectPath: {
type: String,
required: true,
},
filePath: {
type: String,
required: false,
default: null,
},
},
data() {
return {
isFetching: false,
project: {
repository: {
blobs: {
nodes: [
{
codeOwners: [],
},
],
},
},
},
};
},
computed: {
blobInfo() {
return this.project?.repository?.blobs?.nodes[0];
},
codeOwners() {
return this.blobInfo?.codeOwners || [];
},
hasCodeOwners() {
return this.filePath && Boolean(this.codeOwners.length);
},
commaSeparateList() {
return this.codeOwners.length > 2;
},
showAndSeparator() {
return this.codeOwners.length > 1;
},
lastListItem() {
return this.codeOwners.length - 1;
},
},
watch: {
filePath() {
this.isFetching = true;
this.$apollo.queries.project.refetch();
},
},
};
</script>
<template>
<div
v-if="hasCodeOwners && !isFetching"
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
>
<gl-icon name="users" data-testid="users-icon" />
<strong>{{ $options.i18n.title }}</strong>
<gl-link :href="$options.codeOwnersHelpPath" target="_blank" :title="$options.i18n.about">
<gl-icon name="question-o" data-testid="help-icon" />
</gl-link>
:
<div
v-for="(owner, index) in codeOwners"
:key="index"
:class="[
{ 'gl-display-inline-block': commaSeparateList, 'gl-display-inline': !commaSeparateList },
]"
data-testid="code-owners"
>
<span v-if="commaSeparateList && index > 0" data-testid="comma-separator">,</span>
<span v-if="showAndSeparator && index === lastListItem" data-testid="and-separator">{{
$options.i18n.andSeparator
}}</span>
<gl-link :href="owner.webPath" target="_blank" :title="$options.i18n.about">
{{ owner.name }}
</gl-link>
</div>
</div>
</template>

View File

@ -111,7 +111,7 @@ export default {
</script>
<template>
<div class="well-segment commit gl-p-5 gl-w-full">
<div class="info-well d-none d-sm-flex project-last-commit commit p-3">
<gl-loading-icon v-if="isLoading" size="md" color="dark" class="m-auto" />
<template v-else-if="commit">
<user-avatar-link

View File

@ -9,7 +9,6 @@ import App from './components/app.vue';
import Breadcrumbs from './components/breadcrumbs.vue';
import DirectoryDownloadLinks from './components/directory_download_links.vue';
import LastCommit from './components/last_commit.vue';
import CodeOwners from './components/code_owners.vue';
import apolloProvider from './graphql';
import commitsQuery from './queries/commits.query.graphql';
import projectPathQuery from './queries/project_path.query.graphql';
@ -72,23 +71,7 @@ export default function setupVueRepositoryList() {
},
});
const initCodeOwnersApp = () =>
new Vue({
el: document.getElementById('js-code-owners'),
router,
apolloProvider,
render(h) {
return h(CodeOwners, {
props: {
filePath: this.$route.params.path,
projectPath,
},
});
},
});
initLastCommitApp();
initCodeOwnersApp();
router.afterEach(({ params: { path } }) => {
setTitle(path, ref, fullName);

View File

@ -1,15 +0,0 @@
query getCodeOwnersInfo($projectPath: ID!, $filePath: String!, $ref: String!) {
project(fullPath: $projectPath) {
id
repository {
blobs(paths: [$filePath], ref: $ref) {
nodes {
codeOwners {
name
webPath
}
}
}
}
}
}

View File

@ -71,10 +71,6 @@ module Types
field :pipeline_editor_path, GraphQL::Types::String, null: true,
description: 'Web path to edit .gitlab-ci.yml file.'
field :code_owners, [Types::UserType], null: true,
description: 'List of code owners for the blob.',
calls_gitaly: true
field :file_type, GraphQL::Types::String, null: true,
description: 'Expected format of the blob based on the extension.'

View File

@ -66,10 +66,6 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
project_ci_pipeline_editor_path(project, branch_name: blob.commit_id) if can_collaborate_with_project?(project) && blob.path == project.ci_config_path_or_default
end
def code_owners
Gitlab::CodeOwners.for_blob(project, blob)
end
def fork_and_edit_path
fork_path_for_current_user(project, edit_blob_path)
end

View File

@ -10,11 +10,10 @@
.nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch
= render 'projects/tree/tree_header', tree: @tree
.info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column
#js-last-commit.gl-m-auto
#js-last-commit
.info-well.gl-display-none.gl-sm-display-flex.project-last-commit
.gl-spinner-container.m-auto
= loading_icon(size: 'md', color: 'dark', css_class: 'align-text-bottom')
#js-code-owners
- if is_project_overview
.project-buttons.gl-mb-3.js-show-on-project-root

View File

@ -4,7 +4,9 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Install the Kubernetes Agent Server (KAS) **(PREMIUM SELF)**
# Install the Kubernetes Agent Server (KAS) **(FREE SELF)**
> [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
The Kubernetes Agent Server (KAS) is a GitLab backend service dedicated to
managing [Kubernetes Agents](../../user/clusters/agent/index.md).

View File

@ -50,6 +50,8 @@ attachments and avatars, and the whole database. This means user accounts,
issues, merge requests, groups, project data, and so on, will be available for
query.
For more details, see the [supported Geo data types](datatypes.md).
## Can I `git push` to a **secondary** site?
Yes! Pushing directly to a **secondary** site (for both HTTP and SSH, including Git LFS) was [introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in GitLab 11.3.

View File

@ -14073,7 +14073,6 @@ Returns [`Tree`](#tree).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="repositoryblobcanmodifyblob"></a>`canModifyBlob` | [`Boolean`](#boolean) | Whether the current user can modify the blob. |
| <a id="repositoryblobcodeowners"></a>`codeOwners` | [`[UserCore!]`](#usercore) | List of code owners for the blob. |
| <a id="repositoryblobeditblobpath"></a>`editBlobPath` | [`String`](#string) | Web path to edit the blob in the old-style editor. |
| <a id="repositoryblobexternalstorageurl"></a>`externalStorageUrl` | [`String`](#string) | Web path to download the raw blob via external storage, if enabled. |
| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | Expected format of the blob based on the extension. |

View File

@ -274,6 +274,15 @@ To change your primary email:
1. In the **Email** field, enter your new email address.
1. Select **Update profile settings**.
## Set your public email
You can select one of your [configured email addresses](#add-emails-to-your-user-profile) to be displayed on your public profile:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
1. In the **Public email** field, select one of the available email addresses.
1. Select **Update profile settings**.
### Use an automatically-generated private commit email
GitLab provides an automatically-generated private commit email address,

View File

@ -3752,9 +3752,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
msgid "An error occurred while loading code owners."
msgstr ""
msgid "An error occurred while loading commit signatures"
msgstr ""

View File

@ -199,6 +199,13 @@ module QA
max_duration: 180,
retry_on_exception: true
)
QA::Runtime::Logger.info('Wait until Praefect starts and is listening')
wait_until_shell_command_matches(
"docker exec #{@praefect} bash -c 'cat /var/log/gitlab/praefect/current'",
/listening at tcp address/
)
wait_for_gitaly_check
end

View File

@ -1,220 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Code owners component matches the snapshot 1`] = `<!---->`;
exports[`Code owners component matches the snapshot 2`] = `
<div
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
>
<gl-icon-stub
data-testid="users-icon"
name="users"
size="16"
/>
<strong>
Code owners
</strong>
<gl-link-stub
href="/help/user/project/code_owners"
target="_blank"
title="About this feature"
>
<gl-icon-stub
data-testid="help-icon"
name="question-o"
size="16"
/>
</gl-link-stub>
:
<div
class="gl-display-inline"
data-testid="code-owners"
>
<!---->
<!---->
<gl-link-stub
href="path/to/@johnDoe"
target="_blank"
title="About this feature"
>
John Doe
</gl-link-stub>
</div>
</div>
`;
exports[`Code owners component matches the snapshot 3`] = `
<div
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
>
<gl-icon-stub
data-testid="users-icon"
name="users"
size="16"
/>
<strong>
Code owners
</strong>
<gl-link-stub
href="/help/user/project/code_owners"
target="_blank"
title="About this feature"
>
<gl-icon-stub
data-testid="help-icon"
name="question-o"
size="16"
/>
</gl-link-stub>
:
<div
class="gl-display-inline"
data-testid="code-owners"
>
<!---->
<!---->
<gl-link-stub
href="path/to/@johnDoe"
target="_blank"
title="About this feature"
>
John Doe
</gl-link-stub>
</div>
<div
class="gl-display-inline"
data-testid="code-owners"
>
<!---->
<span
data-testid="and-separator"
>
and
</span>
<gl-link-stub
href="path/to/@johnDoe"
target="_blank"
title="About this feature"
>
John Doe
</gl-link-stub>
</div>
</div>
`;
exports[`Code owners component matches the snapshot 4`] = `
<div
class="well-segment blob-auxiliary-viewer file-owner-content qa-file-owner-content"
>
<gl-icon-stub
data-testid="users-icon"
name="users"
size="16"
/>
<strong>
Code owners
</strong>
<gl-link-stub
href="/help/user/project/code_owners"
target="_blank"
title="About this feature"
>
<gl-icon-stub
data-testid="help-icon"
name="question-o"
size="16"
/>
</gl-link-stub>
:
<div
class="gl-display-inline-block"
data-testid="code-owners"
>
<!---->
<!---->
<gl-link-stub
href="path/to/@johnDoe"
target="_blank"
title="About this feature"
>
John Doe
</gl-link-stub>
</div>
<div
class="gl-display-inline-block"
data-testid="code-owners"
>
<span
data-testid="comma-separator"
>
,
</span>
<!---->
<gl-link-stub
href="path/to/@johnDoe"
target="_blank"
title="About this feature"
>
John Doe
</gl-link-stub>
</div>
<div
class="gl-display-inline-block"
data-testid="code-owners"
>
<span
data-testid="comma-separator"
>
,
</span>
<span
data-testid="and-separator"
>
and
</span>
<gl-link-stub
href="path/to/@johnDoe"
target="_blank"
title="About this feature"
>
John Doe
</gl-link-stub>
</div>
</div>
`;

View File

@ -2,7 +2,7 @@
exports[`Repository last commit component renders commit widget 1`] = `
<div
class="well-segment commit gl-p-5 gl-w-full"
class="info-well d-none d-sm-flex project-last-commit commit p-3"
>
<user-avatar-link-stub
class="avatar-cell"
@ -108,7 +108,7 @@ exports[`Repository last commit component renders commit widget 1`] = `
exports[`Repository last commit component renders the signature HTML as returned by the backend 1`] = `
<div
class="well-segment commit gl-p-5 gl-w-full"
class="info-well d-none d-sm-flex project-last-commit commit p-3"
>
<user-avatar-link-stub
class="avatar-cell"

View File

@ -1,89 +0,0 @@
import { GlLink } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import CodeOwners from '~/repository/components/code_owners.vue';
import codeOwnersInfoQuery from '~/repository/queries/code_owners_info.query.graphql';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { codeOwnerMock, codeOwnersDataMock, refMock } from '../mock_data';
let wrapper;
let mockResolver;
const localVue = createLocalVue();
const createComponent = async (codeOwners = [codeOwnerMock]) => {
localVue.use(VueApollo);
const project = {
...codeOwnersDataMock,
repository: {
blobs: {
nodes: [{ codeOwners }],
},
},
};
mockResolver = jest.fn().mockResolvedValue({ data: { project } });
wrapper = extendedWrapper(
shallowMount(CodeOwners, {
localVue,
apolloProvider: createMockApollo([[codeOwnersInfoQuery, mockResolver]]),
propsData: { projectPath: 'some/project', filePath: 'some/file' },
mixins: [{ data: () => ({ ref: refMock }) }],
}),
);
wrapper.setData({ isFetching: false });
await waitForPromises();
};
describe('Code owners component', () => {
const findHelpIcon = () => wrapper.findByTestId('help-icon');
const findUsersIcon = () => wrapper.findByTestId('users-icon');
const findCodeOwners = () => wrapper.findAllByTestId('code-owners');
const findCommaSeparators = () => wrapper.findAllByTestId('comma-separator');
const findAndSeparator = () => wrapper.findAllByTestId('and-separator');
const findLink = () => wrapper.findComponent(GlLink);
beforeEach(() => createComponent());
afterEach(() => wrapper.destroy());
describe('help link', () => {
it('renders a GlLink component', () => {
expect(findLink().exists()).toBe(true);
expect(findLink().attributes('href')).toBe('/help/user/project/code_owners');
expect(findLink().attributes('target')).toBe('_blank');
expect(findLink().attributes('title')).toBe('About this feature');
});
it('renders a Help icon', () => {
expect(findHelpIcon().exists()).toBe(true);
expect(findHelpIcon().props('name')).toBe('question-o');
});
});
it('renders a Users icon', () => {
expect(findUsersIcon().exists()).toBe(true);
expect(findUsersIcon().props('name')).toBe('users');
});
it.each`
codeOwners | commaSeparators | hasAndSeparator
${[]} | ${0} | ${false}
${[codeOwnerMock]} | ${0} | ${false}
${[codeOwnerMock, codeOwnerMock]} | ${0} | ${true}
${[codeOwnerMock, codeOwnerMock, codeOwnerMock]} | ${2} | ${true}
`('matches the snapshot', async ({ codeOwners, commaSeparators, hasAndSeparator }) => {
await createComponent(codeOwners);
expect(findCommaSeparators().length).toBe(commaSeparators);
expect(findAndSeparator().exists()).toBe(hasAndSeparator);
expect(findCodeOwners().length).toBe(codeOwners.length);
expect(wrapper.element).toMatchSnapshot();
});
});

View File

@ -55,18 +55,3 @@ export const projectMock = {
export const propsMock = { path: 'some_file.js', projectPath: 'some/path' };
export const refMock = 'default-ref';
export const codeOwnerMock = { name: 'John Doe', webPath: 'path/to/@johnDoe' };
export const codeOwnersDataMock = {
id: '1234',
repository: {
blobs: {
nodes: [
{
codeOwners: [],
},
],
},
},
};

View File

@ -24,7 +24,6 @@ RSpec.describe Types::Repository::BlobType do
:raw_path,
:replace_path,
:pipeline_editor_path,
:code_owners,
:simple_viewer,
:rich_viewer,
:plain_data,

View File

@ -51,7 +51,7 @@ module SimpleCovEnv
add_filter '/vendor/ruby/'
add_filter '/app/controllers/sherlock/' # Profiling tool used only in development
add_filter '/bin/'
add_filter 'db/fixtures/' # Matches EE files as well
add_filter 'db/fixtures/development/' # Matches EE files as well
add_group 'Channels', 'app/channels' # Matches EE files as well
add_group 'Controllers', 'app/controllers' # Matches EE files as well