Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
576bba90f9
commit
cd5179ede2
|
@ -42,7 +42,7 @@ import {
|
|||
import diffsEventHub from '../event_hub';
|
||||
import { reviewStatuses } from '../utils/file_reviews';
|
||||
import { diffsApp } from '../utils/performance';
|
||||
import { updateChangesTabCount } from '../utils/merge_request';
|
||||
import { updateChangesTabCount, extractFileHash } from '../utils/merge_request';
|
||||
import { queueRedisHllEvents } from '../utils/queue_events';
|
||||
import FindingsDrawer from './shared/findings_drawer.vue';
|
||||
import CollapsedFilesWarning from './collapsed_files_warning.vue';
|
||||
|
@ -344,12 +344,13 @@ export default {
|
|||
...mapActions(['startTaskList']),
|
||||
...mapActions('diffs', [
|
||||
'moveToNeighboringCommit',
|
||||
'setBaseConfig',
|
||||
'setCodequalityEndpoint',
|
||||
'setSastEndpoint',
|
||||
'fetchDiffFilesMeta',
|
||||
'fetchDiffFilesBatch',
|
||||
'fetchFileByFile',
|
||||
'loadCollapsedDiff',
|
||||
'setFileForcedOpen',
|
||||
'fetchCoverageFiles',
|
||||
'fetchCodequality',
|
||||
'fetchSast',
|
||||
|
@ -373,15 +374,34 @@ export default {
|
|||
notesEventHub.$on('refetchDiffData', this.refetchDiffData);
|
||||
notesEventHub.$on('fetchedNotesData', this.rereadNoteHash);
|
||||
diffsEventHub.$on('diffFilesModified', this.setDiscussions);
|
||||
diffsEventHub.$on('doneLoadingBatches', this.autoScroll);
|
||||
diffsEventHub.$on(EVT_MR_PREPARED, this.fetchData);
|
||||
},
|
||||
unsubscribeFromEvents() {
|
||||
diffsEventHub.$off(EVT_MR_PREPARED, this.fetchData);
|
||||
diffsEventHub.$off('doneLoadingBatches', this.autoScroll);
|
||||
diffsEventHub.$off('diffFilesModified', this.setDiscussions);
|
||||
notesEventHub.$off('fetchedNotesData', this.rereadNoteHash);
|
||||
notesEventHub.$off('refetchDiffData', this.refetchDiffData);
|
||||
notesEventHub.$off('fetchDiffData', this.fetchData);
|
||||
},
|
||||
autoScroll() {
|
||||
const lineCode = window.location.hash;
|
||||
const sha1InHash = extractFileHash({ input: lineCode });
|
||||
|
||||
if (sha1InHash) {
|
||||
const idx = this.diffs.findIndex((diffFile) => diffFile.file_hash === sha1InHash);
|
||||
const file = this.diffs[idx];
|
||||
|
||||
this.loadCollapsedDiff({ file })
|
||||
.then(() => {
|
||||
this.setDiscussions();
|
||||
this.scrollVirtualScrollerToIndex(idx);
|
||||
this.setFileForcedOpen({ filePath: file.new_path });
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
navigateToDiffFileNumber(number) {
|
||||
this.navigateToDiffFileIndex(number - 1);
|
||||
},
|
||||
|
|
|
@ -161,6 +161,9 @@ export default {
|
|||
manuallyCollapsed() {
|
||||
return collapsedType(this.file) === DIFF_FILE_MANUAL_COLLAPSE;
|
||||
},
|
||||
forcedOpen() {
|
||||
return this.file.viewer.forceOpen;
|
||||
},
|
||||
showBody() {
|
||||
return !this.isCollapsed || this.automaticallyCollapsed;
|
||||
},
|
||||
|
@ -174,6 +177,10 @@ export default {
|
|||
return Boolean(gon.current_user_id);
|
||||
},
|
||||
isCollapsed() {
|
||||
if (this.forcedOpen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (collapsedType(this.file) !== DIFF_FILE_MANUAL_COLLAPSE) {
|
||||
return this.viewDiffsFileByFile ? false : this.file.viewer?.automaticallyCollapsed;
|
||||
}
|
||||
|
@ -201,6 +208,11 @@ export default {
|
|||
this.manageViewedEffects();
|
||||
},
|
||||
},
|
||||
'file.viewer.forceOpen': {
|
||||
handler: function fileForcedOpenHandler() {
|
||||
this.handleToggle();
|
||||
},
|
||||
},
|
||||
'file.file_hash': {
|
||||
handler: function hashChangeWatch(newHash, oldHash) {
|
||||
if (
|
||||
|
|
|
@ -232,10 +232,15 @@ export default {
|
|||
'setCurrentFileHash',
|
||||
'reviewFile',
|
||||
'setFileCollapsedByUser',
|
||||
'setFileForcedOpen',
|
||||
'setGenerateTestFilePath',
|
||||
'toggleFileCommentForm',
|
||||
]),
|
||||
handleToggleFile() {
|
||||
this.setFileForcedOpen({
|
||||
filePath: this.diffFile.file_path,
|
||||
forced: false,
|
||||
});
|
||||
this.$emit('toggleFile');
|
||||
},
|
||||
showForkMessage(e) {
|
||||
|
@ -278,6 +283,10 @@ export default {
|
|||
}
|
||||
|
||||
if ((open && reviewed) || (closed && !reviewed)) {
|
||||
this.setFileForcedOpen({
|
||||
filePath: this.diffFile.file_path,
|
||||
forced: false,
|
||||
});
|
||||
this.$emit('toggleFile');
|
||||
}
|
||||
},
|
||||
|
|
|
@ -254,6 +254,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
|
|||
|
||||
if (totalLoaded === pagination.total_pages || pagination.total_pages === null) {
|
||||
commit(types.SET_RETRIEVING_BATCHES, false);
|
||||
eventHub.$emit('doneLoadingBatches');
|
||||
|
||||
// We need to check that the currentDiffFileId points to a file that exists
|
||||
if (
|
||||
|
@ -879,6 +880,7 @@ export function switchToFullDiffFromRenamedFile({ commit }, { diffFile }) {
|
|||
...diffFile.alternate_viewer,
|
||||
automaticallyCollapsed: false,
|
||||
manuallyCollapsed: false,
|
||||
forceOpen: false,
|
||||
},
|
||||
});
|
||||
commit(types.SET_CURRENT_VIEW_DIFF_FILE_LINES, { filePath: diffFile.file_path, lines });
|
||||
|
@ -893,6 +895,10 @@ export const setFileCollapsedAutomatically = ({ commit }, { filePath, collapsed
|
|||
commit(types.SET_FILE_COLLAPSED, { filePath, collapsed, trigger: DIFF_FILE_AUTOMATIC_COLLAPSE });
|
||||
};
|
||||
|
||||
export function setFileForcedOpen({ commit }, { filePath, forced }) {
|
||||
commit(types.SET_FILE_FORCED_OPEN, { filePath, forced });
|
||||
}
|
||||
|
||||
export const setSuggestPopoverDismissed = ({ commit, state }) =>
|
||||
axios
|
||||
.post(state.dismissEndpoint, {
|
||||
|
|
|
@ -39,6 +39,7 @@ export const REQUEST_FULL_DIFF = 'REQUEST_FULL_DIFF';
|
|||
export const RECEIVE_FULL_DIFF_SUCCESS = 'RECEIVE_FULL_DIFF_SUCCESS';
|
||||
export const RECEIVE_FULL_DIFF_ERROR = 'RECEIVE_FULL_DIFF_ERROR';
|
||||
export const SET_FILE_COLLAPSED = 'SET_FILE_COLLAPSED';
|
||||
export const SET_FILE_FORCED_OPEN = 'SET_FILE_FORCED_OPEN';
|
||||
|
||||
export const SET_CURRENT_VIEW_DIFF_FILE_LINES = 'SET_CURRENT_VIEW_DIFF_FILE_LINES';
|
||||
export const ADD_CURRENT_VIEW_DIFF_FILE_LINES = 'ADD_CURRENT_VIEW_DIFF_FILE_LINES';
|
||||
|
|
|
@ -349,6 +349,11 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
[types.SET_FILE_FORCED_OPEN](state, { filePath, forced = true }) {
|
||||
const file = state.diffFiles.find((f) => f.file_path === filePath);
|
||||
|
||||
Vue.set(file.viewer, 'forceOpen', forced);
|
||||
},
|
||||
[types.SET_CURRENT_VIEW_DIFF_FILE_LINES](state, { filePath, lines }) {
|
||||
const file = state.diffFiles.find((f) => f.file_path === filePath);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ function collapsed(file) {
|
|||
return {
|
||||
automaticallyCollapsed: viewer.automaticallyCollapsed || viewer.collapsed || false,
|
||||
manuallyCollapsed: null,
|
||||
forceOpen: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { ZERO_CHANGES_ALT_DISPLAY } from '../constants';
|
||||
|
||||
const endpointRE = /^(\/?(.+\/)+(.+)\/-\/merge_requests\/(\d+)).*$/i;
|
||||
const SHA1RE = /([a-f0-9]{40})/g;
|
||||
|
||||
function getVersionInfo({ endpoint } = {}) {
|
||||
const dummyRoot = 'https://gitlab.com';
|
||||
|
@ -51,3 +52,9 @@ export function getDerivedMergeRequestInformation({ endpoint } = {}) {
|
|||
startSha,
|
||||
};
|
||||
}
|
||||
|
||||
export function extractFileHash({ input = '' } = {}) {
|
||||
const matches = input.match(SHA1RE);
|
||||
|
||||
return matches?.[0];
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ export default {
|
|||
<template>
|
||||
<gl-tabs
|
||||
v-model="selectedTabIndex"
|
||||
content-class="gl-py-0"
|
||||
sync-active-tab-with-query-params
|
||||
:query-param-name="$options.ACTIVE_TAB_QUERY_PARAM_NAME"
|
||||
>
|
||||
|
|
|
@ -63,6 +63,6 @@ class Admin::IdentitiesController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def identity_params
|
||||
params.require(:identity).permit(:provider, :extern_uid)
|
||||
params.require(:identity).permit(:provider, :extern_uid, :saml_provider_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module SidekiqHelper
|
||||
SIDEKIQ_PS_REGEXP = %r{\A
|
||||
(?<pid>\d+)\s+
|
||||
(?<cpu>[\d\.,]+)\s+
|
||||
(?<mem>[\d\.,]+)\s+
|
||||
(?<state>[DIEKNRSTVWXZLpsl\+<>/\d]+)\s+
|
||||
(?<start>.+?)\s+
|
||||
(?<command>(?:ruby\d+:\s+)?sidekiq.*\].*)
|
||||
\z}x
|
||||
|
||||
def parse_sidekiq_ps(line)
|
||||
match = line.strip.match(SIDEKIQ_PS_REGEXP)
|
||||
match ? match[1..6] : Array.new(6, '?')
|
||||
end
|
||||
end
|
|
@ -64,15 +64,6 @@ module SortingHelper
|
|||
options
|
||||
end
|
||||
|
||||
def forks_sort_options_hash
|
||||
{
|
||||
sort_value_recently_created => sort_title_created_date,
|
||||
sort_value_oldest_created => sort_title_created_date,
|
||||
sort_value_latest_activity => sort_title_latest_activity,
|
||||
sort_value_oldest_activity => sort_title_latest_activity
|
||||
}
|
||||
end
|
||||
|
||||
def forks_reverse_sort_options_hash
|
||||
{
|
||||
sort_value_recently_created => sort_value_oldest_created,
|
||||
|
@ -93,12 +84,6 @@ module SortingHelper
|
|||
}
|
||||
end
|
||||
|
||||
def subgroups_sort_options_hash
|
||||
groups_sort_options_hash.merge(
|
||||
sort_value_stars_desc => sort_title_most_stars
|
||||
)
|
||||
end
|
||||
|
||||
def admin_groups_sort_options_hash
|
||||
groups_sort_options_hash.merge(
|
||||
sort_value_largest_group => sort_title_largest_group
|
||||
|
@ -199,19 +184,6 @@ module SortingHelper
|
|||
}.merge(issuable_sort_option_overrides)
|
||||
end
|
||||
|
||||
def audit_logs_sort_order_hash
|
||||
{
|
||||
sort_value_recently_created => sort_title_recently_created,
|
||||
sort_value_oldest_created => sort_title_oldest_created
|
||||
}
|
||||
end
|
||||
|
||||
def issuable_sort_option_title(sort_value)
|
||||
sort_value = issuable_sort_option_overrides[sort_value] || sort_value
|
||||
|
||||
sort_options_hash[sort_value]
|
||||
end
|
||||
|
||||
def issuable_sort_options(viewing_issues, viewing_merge_requests)
|
||||
options = [
|
||||
{ value: sort_value_priority, text: sort_title_priority, href: page_filter_path(sort: sort_value_priority) },
|
||||
|
@ -321,17 +293,6 @@ module SortingHelper
|
|||
}
|
||||
end
|
||||
|
||||
def packages_sort_option_title(sort_value)
|
||||
packages_sort_options_hash[sort_value] || sort_title_created_date
|
||||
end
|
||||
|
||||
def packages_sort_direction_button(sort_value)
|
||||
reverse_sort = packages_reverse_sort_order_hash[sort_value]
|
||||
url = package_sort_path(sort: reverse_sort)
|
||||
|
||||
sort_direction_button(url, reverse_sort, sort_value)
|
||||
end
|
||||
|
||||
def forks_sort_direction_button(sort_value, without = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id])
|
||||
reverse_sort = forks_reverse_sort_options_hash[sort_value]
|
||||
url = page_filter_path(sort: reverse_sort, without: without)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
.col-sm-10
|
||||
- values = Gitlab::Auth::OAuth::Provider.providers.map { |name| ["#{Gitlab::Auth::OAuth::Provider.label_for(name)} (#{name})", name] }
|
||||
= f.select :provider, values, { allow_blank: false }, class: 'form-control'
|
||||
= render_if_exists partial: 'admin/identities/provider_id', locals: { f: f }
|
||||
.form-group.row
|
||||
.col-sm-2.col-form-label
|
||||
= f.label :extern_uid, _("Identifier")
|
||||
|
@ -15,4 +16,3 @@
|
|||
|
||||
.form-actions
|
||||
= f.submit _('Save changes'), pajamas_button: true
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: use_embeddings_with_vertex
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130421
|
||||
rollout_issue_url:
|
||||
milestone: '16.5'
|
||||
type: development
|
||||
group: group::duo chat
|
||||
default_enabled: false
|
|
@ -135,8 +135,8 @@ The following metrics are available:
|
|||
| `gitlab_issuable_fast_count_by_state_total` | Counter | 13.5 | Total number of row count operations on issue/merge request list pages | |
|
||||
| `gitlab_issuable_fast_count_by_state_failures_total` | Counter | 13.5 | Number of soft-failed row count operations on issue/merge request list pages | |
|
||||
| `gitlab_ci_trace_finalize_duration_seconds` | Histogram | 13.6 | Duration of build trace chunks migration to object storage | |
|
||||
| `gitlab_vulnerability_report_branch_comparison_real_duration_seconds` | Histogram | 15.11 | Execution duration of vulnerability report present on default branch sql query | |
|
||||
| `gitlab_vulnerability_report_branch_comparison_cpu_duration_seconds` | Histogram | 15.11 | Execution duration of vulnerability report present on default branch sql query | |
|
||||
| `gitlab_vulnerability_report_branch_comparison_real_duration_seconds` | Histogram | 15.11 | Execution duration of vulnerability report present on default branch SQL query | |
|
||||
| `gitlab_vulnerability_report_branch_comparison_cpu_duration_seconds` | Histogram | 15.11 | Execution duration of vulnerability report present on default branch SQL query | |
|
||||
| `gitlab_external_http_total` | Counter | 13.8 | Total number of HTTP calls to external systems | `controller`, `action` |
|
||||
| `gitlab_external_http_duration_seconds` | Counter | 13.8 | Duration in seconds spent on each HTTP call to external systems | |
|
||||
| `gitlab_external_http_exception_total` | Counter | 13.8 | Total number of exceptions raised when making external HTTP calls | |
|
||||
|
|
|
@ -833,7 +833,7 @@ to be used with GitLab. The following IPs will be used as an example:
|
|||
|
||||
You can optionally use a third party external service for Redis as long as it meets the [requirements](../../install/requirements.md#redis).
|
||||
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
|
||||
### Configure the Redis Cache cluster
|
||||
|
||||
|
|
|
@ -850,7 +850,7 @@ to be used with GitLab. The following IPs will be used as an example:
|
|||
|
||||
You can optionally use a third party external service for Redis as long as it meets the [requirements](../../install/requirements.md#redis).
|
||||
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
|
||||
### Configure the Redis Cache cluster
|
||||
|
||||
|
|
|
@ -334,7 +334,7 @@ to be used with GitLab.
|
|||
|
||||
You can optionally use a third party external service for Redis as long as it meets the [requirements](../../install/requirements.md#redis).
|
||||
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
|
||||
### Standalone Redis using the Linux package
|
||||
|
||||
|
|
|
@ -450,7 +450,7 @@ to be used with GitLab. The following IPs will be used as an example:
|
|||
|
||||
You can optionally use a third party external service for Redis as long as it meets the [requirements](../../install/requirements.md#redis).
|
||||
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
|
||||
### Standalone Redis using the Linux package
|
||||
|
||||
|
|
|
@ -843,7 +843,7 @@ to be used with GitLab. The following IPs will be used as an example:
|
|||
|
||||
You can optionally use a third party external service for Redis as long as it meets the [requirements](../../install/requirements.md#redis).
|
||||
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
|
||||
### Configure the Redis Cache cluster
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ to be used with GitLab. The following IPs are used as an example:
|
|||
|
||||
You can optionally use a third party external service for Redis as long as it meets the [requirements](../../install/requirements.md#redis).
|
||||
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS Elasticache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
A reputable provider or solution should be used for this. [Google Memorystore](https://cloud.google.com/memorystore/docs/redis/redis-overview) and [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html) are known to work. However, note that the Redis Cluster mode specifically isn't supported by GitLab. See [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
|
||||
|
||||
### Standalone Redis using the Linux package
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ and subject to change without notice.
|
|||
Create a new CycloneDX JSON export for all the project dependencies detected in a pipeline.
|
||||
|
||||
If an authenticated user doesn't have permission to
|
||||
[read_dependency](../user/permissions.md#custom-role-requirements),
|
||||
[`read_dependency`](../user/permissions.md#custom-role-requirements),
|
||||
this request returns a `403 Forbidden` status code.
|
||||
|
||||
SBOM exports can be only accessed by the export's author.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1330,7 +1330,8 @@ target the upstream project by default.
|
|||
"kind": "group",
|
||||
"full_path": "gitlab-org",
|
||||
"parent_id": null
|
||||
}
|
||||
},
|
||||
"repository_storage": "default"
|
||||
}
|
||||
|
||||
...
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 237 KiB |
|
@ -32,7 +32,7 @@ translate the content of the redirected request where needed.
|
|||
|
||||

|
||||
|
||||
[src of the architecture diagram](https://docs.google.com/drawings/d/1PYl5Q5oWHnQAuxM-Jcw0C3eYoGw8a9w8atFpoLhhEas/edit)
|
||||
[Diagram source](https://docs.google.com/drawings/d/1PYl5Q5oWHnQAuxM-Jcw0C3eYoGw8a9w8atFpoLhhEas/edit)
|
||||
|
||||
By using a hosted service under the control of GitLab we can ensure
|
||||
that we provide all GitLab instances with AI features in a scalable
|
||||
|
@ -385,15 +385,19 @@ different.
|
|||
|
||||
## Authentication & Authorization
|
||||
|
||||
GitLab will provide the first layer of authorization: It authenticate
|
||||
the user and check if the license allows using the feature the user is
|
||||
trying to use. This can be done using the authentication and license
|
||||
GitLab provides the first layer of authorization: It authenticates
|
||||
the user and checks if the license allows using the feature the user is
|
||||
trying to use. This can be done using the authentication, policy and license
|
||||
checks that are already built into GitLab.
|
||||
|
||||
Authenticating the GitLab-instance on the AI-gateway will be discussed
|
||||
in[#177](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/issues/177).
|
||||
Because the AI-gateway exposes proxied endpoints to AI providers, it
|
||||
is important that the authentication tokens have limited validity.
|
||||
Authenticating the GitLab-instance on the AI-gateway was discussed
|
||||
in:
|
||||
|
||||
- [Issue 177](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/issues/177)
|
||||
- [Epic 10808](https://gitlab.com/groups/gitlab-org/-/epics/10808)
|
||||
|
||||
The specific mechanism by which trust is delegated between end-users, GitLab instances,
|
||||
and the AI-gateway is covered in the [AI gateway access token validation documentation](../../../development/cloud_connector/code_suggestions_for_sm.md#ai-gateway-access-token-validation).
|
||||
|
||||
## Embeddings
|
||||
|
||||
|
|
|
@ -264,16 +264,16 @@ GitLab administrators can add a namespace to the reduced cost factor
|
|||
|
||||
GitLab SaaS runners have different cost factors, depending on the runner type (Linux, Windows, macOS) and the virtual machine configuration.
|
||||
|
||||
| GitLab SaaS runner type | Machine Size | Cost factor |
|
||||
|:-----------------------------|:---------------------|:------------|
|
||||
| Linux OS amd64 | small | 1 |
|
||||
| Linux OS amd64 | medium | 2 |
|
||||
| Linux OS amd64 | large | 3 |
|
||||
| Linux OS amd64 | xlarge | 6 |
|
||||
| Linux OS amd64 | 2xlarge | 12 |
|
||||
| Linux OS amd64 + GPU-enabled | medium, GPU standard | 7 |
|
||||
| macOS M1 | medium | 6 (Beta) |
|
||||
| Windows Server | - | 1 (Beta) |
|
||||
| GitLab SaaS runner type | Machine Size | Cost factor |
|
||||
|:-----------------------------|:-----------------------|:------------|
|
||||
| Linux OS amd64 | `small` | 1 |
|
||||
| Linux OS amd64 | `medium` | 2 |
|
||||
| Linux OS amd64 | `large` | 3 |
|
||||
| Linux OS amd64 | `xlarge` | 6 |
|
||||
| Linux OS amd64 | `2xlarge` | 12 |
|
||||
| Linux OS amd64 + GPU-enabled | `medium`, GPU standard | 7 |
|
||||
| macOS M1 | `medium` | 6 (Beta) |
|
||||
| Windows Server | - | 1 (Beta) |
|
||||
|
||||
### Monthly reset of compute usage
|
||||
|
||||
|
|
|
@ -72,9 +72,10 @@ To continue using registration tokens after GitLab 17.0:
|
|||
|
||||
Plans to implement a UI setting to re-enable registration tokens are proposed in [issue 411923](https://gitlab.com/gitlab-org/gitlab/-/issues/411923)
|
||||
|
||||
## Runners registered with a registration token will continue to work after 18.0
|
||||
## Using runners registered with a runner registration token
|
||||
|
||||
Existing runners will not be affected by these changes, they will still work even after the legacy registration method is removed.
|
||||
Existing runners will not be affected by these changes and will continue to
|
||||
work after the legacy registration method is removed in GitLab 18.0.
|
||||
|
||||
## Changes to the `gitlab-runner register` command syntax
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ the authentication token is stored in the `config.toml`.
|
|||
|
||||
WARNING:
|
||||
The ability to pass a runner registration token, and support for certain configuration arguments was
|
||||
[deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/380872) in GitLab 15.6 and will be removed in GitLab 17.0. Authentication tokens
|
||||
[deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/380872) in GitLab 15.6 and will be removed in GitLab 18.0. Runner authentication tokens
|
||||
should be used instead. For more information, see [Migrating to the new runner registration workflow](new_creation_workflow.md).
|
||||
|
||||
Prerequisite:
|
||||
|
@ -466,7 +466,7 @@ The runner authentication token displays in the UI for only a short period of ti
|
|||
|
||||
WARNING:
|
||||
The ability to pass a runner registration token, and support for certain configuration arguments was
|
||||
[deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/380872) in GitLab 15.6 and will be removed in GitLab 17.0. Authentication tokens
|
||||
[deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/380872) in GitLab 15.6 and will be removed in GitLab 18.0. Runner authentication tokens
|
||||
should be used instead. For more information, see [Migrating to the new runner registration workflow](new_creation_workflow.md).
|
||||
|
||||
Prerequisite:
|
||||
|
|
|
@ -18,7 +18,7 @@ In GitLab 16.0 and later you can use ID tokens without any settings changes.
|
|||
Jobs that use `secrets:vault` automatically do not have `CI_JOB_JWT` tokens available,
|
||||
Jobs that don't use `secrets:vault` can still use `CI_JOB_JWT` tokens.
|
||||
|
||||
This tutorial will focus on v16 onwards, if you are running a slightly older version you will need to toggle the `Limit JSON Web Token (JWT) access` setting as appropriate.
|
||||
This tutorial will focus on v16 onward, if you are running a slightly older version you will need to toggle the `Limit JSON Web Token (JWT) access` setting as appropriate.
|
||||
|
||||
There isn't one standard method to migrate to [ID tokens](../secrets/id_token_authentication.md), so this tutorial includes two variations for how to convert your existing CI/CD secrets. Choose the method that is most appropriate for your use case:
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ In this example:
|
|||
- `image: ruby:3.0` and `retry: 2` are the default keywords for all jobs in the pipeline.
|
||||
- The `rspec` job does not have `image` or `retry` defined, so it uses the defaults of
|
||||
`image: ruby:3.0` and `retry: 2`.
|
||||
- The `rspec 2.7` job does not have `retry` defined, but it does have `image` explictly defined.
|
||||
- The `rspec 2.7` job does not have `retry` defined, but it does have `image` explicitly defined.
|
||||
It uses the default `retry: 2`, but ignores the default `image` and uses the `image: ruby:2.7`
|
||||
defined in the job.
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ GitLab has created a common set of tools to support our product groups and their
|
|||
|
||||
AI is moving very quickly, and we need to be able to keep pace with changes in the area. We have built an [abstraction layer](../../ee/development/ai_features/index.md) to do this, allowing us to take a more "pluggable" approach to the underlying models, data stores, and other technologies.
|
||||
|
||||
The following diagram from the [architecture blueprint](../architecture/blueprints/ai_gateway/index.md) shows a simplified view of how the different components in GitLab interact. The abstraction layer helps avoid code duplication within the REST APIs within the `AI API` block.
|
||||
The following diagram from the [architecture blueprint](../architecture/blueprints/ai_gateway/index.md) shows a simplified view of how the different components in GitLab interact. The abstraction layer helps avoid code duplication within the REST APIs.
|
||||
|
||||

|
||||

|
||||
|
||||
## SaaS-based AI abstraction layer
|
||||
|
||||
|
@ -33,8 +33,7 @@ By default, these actions are performed asynchronously via a Sidekiq
|
|||
job to prevent long-running requests in Puma. It should be used for
|
||||
non-latency sensitive actions due to the added latency by Sidekiq.
|
||||
|
||||
At the time of writing, the Abstraction Layer still directly calls the AI providers. This will be
|
||||
changed [in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/424614).
|
||||
At the time of writing, the Abstraction Layer still directly calls the AI providers. [Epic 11484](https://gitlab.com/groups/gitlab-org/-/epics/11484) proposes to change this.
|
||||
|
||||
When a certain action is latency sensitive, we can decide to call the
|
||||
AI-gateway directly. This avoids the latency added by Sidekiq.
|
||||
|
@ -88,24 +87,24 @@ For optimal `probes` and `lists` values:
|
|||
- Use `lists` equal to `rows / 1000` for tables with up to 1 million rows and `sqrt(rows)` for larger datasets.
|
||||
- For `probes` start with `lists / 10` for tables up to 1 million rows and `sqrt(lists)` for larger datasets.
|
||||
|
||||
### Code Suggestions
|
||||
## Code Suggestions
|
||||
|
||||
Code Suggestions is being integrated as part of the GitLab-Rails repository which will unify the architectures between Code Suggestions and AI features that use the abstraction layer, along with offering self-managed support for the other AI features.
|
||||
Code Suggestions is being integrated as part of the GitLab-Rails repository which will unify the architectures between Code Suggestions and AI features that use the abstraction layer, along with offering [self-managed support](#self-managed-support) for the other AI features.
|
||||
|
||||
The following table documents functionality that Code Suggestions offers today, and what those changes will look like as part of the unification:
|
||||
|
||||
| Topic | Details | Where this happens today | Where this will happen going forward |
|
||||
| ----- | ------ | -------------- | ------------------ |
|
||||
| Request processing | | | |
|
||||
| | Receives requests from IDEs (VSCode, GitLab WebIDE, MS Visual Studio, IntelliJ, JetBrains, VIM, Emacs, Sublime), including code before and after the cursor | AI Gateway | Abstraction Layer |
|
||||
| | Authentication the current user, verifies they are authorized to use Code Suggestions for this project | AI Gateway | Abstraction layer |
|
||||
| | Receives requests from IDEs (VSCode, GitLab WebIDE, MS Visual Studio, IntelliJ, JetBrains, VIM, Emacs, Sublime), including code before and after the cursor | GitLab Rails | GitLab Rails |
|
||||
| | Authenticates the current user, verifies they are authorized to use Code Suggestions for this project | GitLab Rails + AI Gateway | GitLab Rails + AI Gateway |
|
||||
| | Preprocesses the request to add context, such as including imports via TreeSitter | AI Gateway | Undecided |
|
||||
| | Routes the request to the AI Provider | AI Gateway | AI Gateway |
|
||||
| | Returns the response to the IDE | AI Gateway | Abstraction Layer |
|
||||
| | Logs the request, including timestamp, response time, model, etc | AI Gateway | Both |
|
||||
| | Returns the response to the IDE | GitLab Rails | GitLab Rails |
|
||||
| | Logs the request, including timestamp, response time, model, etc | Both | Both |
|
||||
| Telemetry | | | |
|
||||
| | User acceptance or rejection in the IDE | AI Gateway | [Both](https://gitlab.com/gitlab-org/gitlab/-/issues/418282) |
|
||||
| | Number of unique users per day | [Abstraction Layer](https://app.periscopedata.com/app/gitlab/1143612/Code-Suggestions-Usage) | Undecided |
|
||||
| | Number of unique users per day | [GitLab Rails](https://app.periscopedata.com/app/gitlab/1143612/Code-Suggestions-Usage), AI gateway | Undecided |
|
||||
| | Error rate, model usage, response time, IDE usage | [AI Gateway](https://log.gprd.gitlab.net/app/dashboards#/view/6c947f80-7c07-11ed-9f43-e3784d7fe3ca?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-6h,to:now))) | Both |
|
||||
| | Suggestions per language | AI Gateway |[Both](https://gitlab.com/groups/gitlab-org/-/epics/11017) |
|
||||
| Monitoring | | Both | Both |
|
||||
|
@ -115,7 +114,15 @@ The following table documents functionality that Code Suggestions offers today,
|
|||
| Internal Models | | | |
|
||||
| | Currently unmaintained, the ability to run models in our own instance, running them inside Triton, and routing requests to our own models | AI Gateway | AI Gateway |
|
||||
|
||||
#### Code Suggestions Latency
|
||||
### Self-managed support
|
||||
|
||||
Code Suggestions for self-managed users was introduced as part of the [Cloud Connector MVC](https://gitlab.com/groups/gitlab-org/-/epics/10516).
|
||||
|
||||
For more information on the technical solution for this project see the [Cloud Connector MVC documentation](cloud_connector/code_suggestions_for_sm.md).
|
||||
|
||||
The intention is to evolve this solution to service other AI features under the Cloud Connector product umbrella.
|
||||
|
||||
### Code Suggestions Latency
|
||||
|
||||
Code Suggestions acceptance rates are _highly_ sensitive to latency. While writing code with an AI assistant, a user will pause only for a short duration before continuing on with manually typing out a block of code. As soon as the user has pressed a subsequent keypress, the existing suggestion will be invalidated and a new request will need to be issued to the Code Suggestions endpoint. In turn, this request will also be highly sensitive to latency.
|
||||
|
||||
|
|
|
@ -134,17 +134,26 @@ Gitlab::CurrentSettings.update(openai_api_key: "<open-ai-key>")
|
|||
Gitlab::CurrentSettings.update!(anthropic_api_key: <insert API key>)
|
||||
```
|
||||
|
||||
#### Populating embeddings and using embeddings fixture
|
||||
### Populating embeddings and using embeddings fixture
|
||||
|
||||
Currently we have embeddings generate both with OpenAI and VertexAI. Bellow sections explain how to populate
|
||||
embeddings in the DB or extract embeddings to be used in specs.
|
||||
|
||||
FLAG:
|
||||
We are moving towards having VertexAI embeddings only, so eventually the OpenAI embeddings support will be drop
|
||||
as well as the section bellow will be removed.
|
||||
|
||||
#### OpenAI embeddings
|
||||
|
||||
To seed your development database with the embeddings for GitLab Documentation,
|
||||
you may use the pre-generated embeddings and a Rake test.
|
||||
you may use the pre-generated embeddings and a Rake task.
|
||||
|
||||
```shell
|
||||
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:seed_pre_generated
|
||||
```
|
||||
|
||||
The DBCleaner gem we use clear the database tables before each test runs.
|
||||
Instead of fully populating the table `tanuki_bot_mvc` where we store embeddings for the documentations,
|
||||
Instead of fully populating the table `tanuki_bot_mvc` where we store OpenAI embeddings for the documentations,
|
||||
we can add a few selected embeddings to the table from a pre-generated fixture.
|
||||
|
||||
For instance, to test that the question "How can I reset my password" is correctly
|
||||
|
@ -157,6 +166,31 @@ You can add or remove the questions needed to be tested in the Rake task and run
|
|||
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:extract_embeddings
|
||||
```
|
||||
|
||||
#### VertexAI embeddings
|
||||
|
||||
To seed your development database with the embeddings for GitLab Documentation,
|
||||
you may use the pre-generated embeddings and a Rake task.
|
||||
|
||||
```shell
|
||||
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:vertex:seed
|
||||
```
|
||||
|
||||
The DBCleaner gem we use clear the database tables before each test runs.
|
||||
Instead of fully populating the table `vertex_gitlab_docs` where we store VertexAI embeddings for the documentations,
|
||||
we can add a few selected embeddings to the table from a pre-generated fixture.
|
||||
|
||||
For instance, to test that the question "How can I reset my password" is correctly
|
||||
retrieving the relevant embeddings and answered, we can extract the top N closet embeddings
|
||||
to the question into a fixture and only restore a small number of embeddings quickly.
|
||||
To faciliate an extraction process, a Rake task been written.
|
||||
You can add or remove the questions needed to be tested in the Rake task and run the task to generate a new fixture.
|
||||
|
||||
```shell
|
||||
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:vertex:extract_embeddings
|
||||
```
|
||||
|
||||
#### Using embeddings in specs
|
||||
|
||||
In the specs where you need to use the embeddings,
|
||||
use the RSpec config hook `:ai_embedding_fixtures` on a context.
|
||||
|
||||
|
|
|
@ -1423,7 +1423,7 @@ wrapper = mount(SomeComponent, {
|
|||
|
||||
#### Testing subscriptions
|
||||
|
||||
When testing subscriptions, be aware that default behavior for subscription in `vue-apollo@4` is to re-subscribe and immediatelly issue new request on error (unless value of `skip` restricts us from doing that)
|
||||
When testing subscriptions, be aware that default behavior for subscription in `vue-apollo@4` is to re-subscribe and immediately issue new request on error (unless value of `skip` restricts us from doing that)
|
||||
|
||||
```javascript
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 140 KiB |
|
@ -139,7 +139,7 @@ Save the changes and then run `sudo gitlab-ctl reconfigure`. If there are no err
|
|||
|
||||
## Specify numeric user and group identifiers
|
||||
|
||||
The Linux pacakage creates a user and group `mattermost`. You can specify the
|
||||
The Linux package creates a user and group `mattermost`. You can specify the
|
||||
numeric identifiers for these users in `/etc/gitlab/gitlab.rb` as follows:
|
||||
|
||||
```ruby
|
||||
|
|
|
@ -1353,7 +1353,7 @@ The `go.sum` file contains an entry of every module that was considered while ge
|
|||
Multiple versions of a module are included in the `go.sum` file, but the [MVS](https://go.dev/ref/mod#minimal-version-selection)
|
||||
algorithm used by `go build` only selects one. As a result, when dependency scanning uses `go.sum`, it might report false positives.
|
||||
|
||||
To prevent false positives, gemnasium only uses `go.sum` if it is unable to generate the build list for the Go project. If `go.sum` is selected, a warning occurs:
|
||||
To prevent false positives, Gemnasium only uses `go.sum` if it is unable to generate the build list for the Go project. If `go.sum` is selected, a warning occurs:
|
||||
|
||||
```shell
|
||||
[WARN] [Gemnasium] [2022-09-14T20:59:38Z] ▶ Selecting "go.sum" parser for "/test-projects/gitlab-shell/go.sum". False positives may occur. See https://gitlab.com/gitlab-org/gitlab/-/issues/321081.
|
||||
|
|
|
@ -143,14 +143,14 @@ The workaround is to amend your group or instance push rules to allow branches f
|
|||
|
||||
- Confirm that scanners are properly configured and producing results for the latest branch. Security Policies are designed to require approval when there are no results (no security report), as this ensures that no vulnerabilities are introduced. We cannot know if there are any vulnerabilities unless the scans enforced by the policy complete successfully and are evaluated.
|
||||
- For scan result policies, we require artifacts for each scanner defined in the policy for both the source and target branch. To ensure scan result policies capture the necessary results, confirm your scan execution is properly implemented and enforced. If using scan execution policies, enforcing on `all branches` often address this need.
|
||||
- When running scan execution policies based on a SAST action, ensure target repositories contain proper code files. SAST runs different analyzers [based on the types of files in the repo](../sast/index.md#supported-languages-and-frameworks), and if no supported files are found it will not run any jobs. See the [SAST CI template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml) for more details.
|
||||
- When running scan execution policies based on a SAST action, ensure target repositories contain proper code files. SAST runs different analyzers [based on the types of files in the repository](../sast/index.md#supported-languages-and-frameworks), and if no supported files are found it will not run any jobs. See the [SAST CI template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml) for more details.
|
||||
- Check for any branch configuration conflicts. If your policy is configured to enforce rules on `main` but some projects within the scope are using `master` as their default branch, the policy is not applied for the latter. You can define policies to enforce rules generically on `default` branches regardless of the name used in the project or on `all protected branches` to address this issue.
|
||||
- Scan result policies created at the group or sub-group level can take some time to apply to all the merge requests in the group.
|
||||
- Scheduled scan execution policies run with a minimum 15 minute cadence. Learn more [about the schedule rule type](../policies/scan-execution-policies.md#schedule-rule-type).
|
||||
- When scheduling pipelines, keep in mind that CRON scheduling is based on UTC on GitLab SaaS and is based on your server time for self managed instances. When testing new policies, it may appear pipelines are not running properly when in fact they are scheduled in your server's timezone.
|
||||
- When enforcing scan execution policies, security policies use a bot in the target project that will trigger scheduled pipelines to ensure enforcement. When the bot is missing, it will be automatically created, and the following scheduled scan will use it.
|
||||
- You should not link a security policy project to a development project and to the group or sub-group the development project belongs to at the same time. Linking this way will result in approval rules from the Scan Result Policy not being applied to merge requests in the development project.
|
||||
- When creating a Scan Result Policy, neither the array `severity_levels` nor the array `vulnerability_states` in the [scan_finding rule](../policies/scan-result-policies.md#scan_finding-rule-type) can be left empty; for a working rule, at least one entry must exist.
|
||||
- When creating a Scan Result Policy, neither the array `severity_levels` nor the array `vulnerability_states` in the [`scan_finding` rule](../policies/scan-result-policies.md#scan_finding-rule-type) can be left empty; for a working rule, at least one entry must exist.
|
||||
- When configuring pipeline and scan result policies, it's important to remember that security scans performed in manual jobs aren't verified to determine whether MR approval is required. When you run a manual job with security scans, it won't ensure approval even if vulnerabilities are introduced.
|
||||
|
||||
If you are still experiencing issues, you can [view recent reported bugs](https://gitlab.com/gitlab-org/gitlab/-/issues/?sort=popularity&state=opened&label_name%5B%5D=group%3A%3Asecurity%20policies&label_name%5B%5D=type%3A%3Abug&first_page_size=20) and raise new unreported issues.
|
||||
|
|
|
@ -39,7 +39,7 @@ A project can have multiple pipeline types configured. A single commit can initi
|
|||
pipelines, each of which may contain a security scan.
|
||||
|
||||
- In GitLab 16.3 and later, the results of all completed pipelines for the latest commit in
|
||||
the MR's source and target branch are evaluated and used to enforce the scan result policy.
|
||||
the merge request's source and target branch are evaluated and used to enforce the scan result policy.
|
||||
Parent-child pipelines and on-demand DAST pipelines are not considered.
|
||||
- In GitLab 16.2 and earlier, only the results of the latest completed pipeline were evaluated
|
||||
when enforcing scan result policies.
|
||||
|
|
|
@ -99,4 +99,4 @@ This error typically occurs when the user you're trying to remove is part of an
|
|||
- Remove the invited group membership from your project or group members page.
|
||||
- Recommended. Remove the user directly from the invited group, if you have access to the group.
|
||||
|
||||
The feature request to **Update billable_members endpoint to include invited group** is currently being worked on. For more information, see [issue 386583](https://gitlab.com/gitlab-org/gitlab/-/issues/386583)
|
||||
The feature request to **Update `billable_members` endpoint to include invited group** is currently being worked on. For more information, see [issue 386583](https://gitlab.com/gitlab-org/gitlab/-/issues/386583)
|
||||
|
|
|
@ -49,7 +49,7 @@ To view the updated syntax highlighting theme, refresh your project's page.
|
|||
To customize the syntax highlighting theme, you can also [use the Application settings API](../../api/settings.md#list-of-settings-that-can-be-accessed-via-api-calls). Use `default_syntax_highlighting_theme` to change the syntax highlighting colors on a more granular level.
|
||||
|
||||
If these steps do not work, your programming language might not be supported by the syntax highlighters.
|
||||
For more information, view [Rouge Ruby Library](https://github.com/rouge-ruby/rouge) for guidance on code files and Snippets. View [Moncaco Editor](https://microsoft.github.io/monaco-editor/) and [Monarch](https://microsoft.github.io/monaco-editor/monarch.html) for guidance on the Web IDE.
|
||||
For more information, view [Rouge Ruby Library](https://github.com/rouge-ruby/rouge) for guidance on code files and Snippets. View [Monaco Editor](https://microsoft.github.io/monaco-editor/) and [Monarch](https://microsoft.github.io/monaco-editor/monarch.html) for guidance on the Web IDE.
|
||||
|
||||
## Change the diff colors
|
||||
|
||||
|
@ -105,17 +105,17 @@ To change the default content on your group overview page:
|
|||
1. On the left sidebar, select your avatar.
|
||||
1. Select **Preferences**.
|
||||
1. Go to the **Behavior** section.
|
||||
1. For **Group overivew content**, select an option.
|
||||
1. For **Group overview content**, select an option.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### Customize default content on your project overview page
|
||||
|
||||
Your project overview page is the page you view when you select **Project overview** on the left sidebar. You can set your main project overview page to the Activity page, the Readme file, and other content.
|
||||
Your project overview page is the page you view when you select **Project overview** on the left sidebar. You can set your main project overview page to the Activity page, the README file, and other content.
|
||||
|
||||
1. On the left sidebar, select your avatar.
|
||||
1. Select **Preferences**.
|
||||
1. Go to the **Behavior** section.
|
||||
1. For **Project overivew content**, select an option.
|
||||
1. For **Project overview content**, select an option.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### Hide shortcut buttons
|
||||
|
|
|
@ -120,7 +120,7 @@ To use custom settings for a project or group integration:
|
|||
| Buildkite | Run CI/CD pipelines with Buildkite. | **{check-circle}** Yes |
|
||||
| Campfire | Connect to chat. | **{dotted-circle}** No |
|
||||
| [ClickUp](clickup.md) | Use ClickUp as the issue tracker. | **{dotted-circle}** No |
|
||||
| [Confluence Workspace](../../../api/integrations.md#confluence-integration) | Use Confluence Cloud Workspace as an internal wiki. | **{dotted-circle}** No |
|
||||
| [Confluence Workspace](../../../api/integrations.md#confluence-workspace) | Use Confluence Cloud Workspace as an internal wiki. | **{dotted-circle}** No |
|
||||
| [Custom issue tracker](custom_issue_tracker.md) | Use a custom issue tracker. | **{dotted-circle}** No |
|
||||
| [Datadog](../../../integration/datadog.md) | Trace your GitLab pipelines with Datadog. | **{check-circle}** Yes |
|
||||
| [Discord Notifications](discord_notifications.md) | Send notifications about project events to a Discord channel. | **{dotted-circle}** No |
|
||||
|
|
|
@ -100,7 +100,7 @@ from the GitLab user interface.
|
|||
|
||||
Prerequisites:
|
||||
|
||||
- The [Jetbrains Toolbox App](https://www.jetbrains.com/toolbox-app/) must be also be installed.
|
||||
- The [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/) must be also be installed.
|
||||
|
||||
To do this:
|
||||
|
||||
|
|
|
@ -41,6 +41,10 @@ module API
|
|||
expose :namespace, using: 'API::Entities::NamespaceBasic'
|
||||
expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes
|
||||
|
||||
expose :repository_storage, documentation: { type: 'string', example: 'default' }, if: ->(project, options) {
|
||||
Ability.allowed?(options[:current_user], :change_repository_storage, project)
|
||||
}
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def self.preload_relation(projects_relation, options = {})
|
||||
# Preloading topics, should be done with using only `:topics`,
|
||||
|
|
|
@ -159,9 +159,6 @@ module API
|
|||
}
|
||||
|
||||
expose :autoclose_referenced_issues, documentation: { type: 'boolean' }
|
||||
expose :repository_storage, documentation: { type: 'string', example: 'default' }, if: ->(project, options) {
|
||||
Ability.allowed?(options[:current_user], :change_repository_storage, project)
|
||||
}
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def self.preload_resource(project)
|
||||
|
|
|
@ -38389,6 +38389,9 @@ msgstr ""
|
|||
msgid "Provider"
|
||||
msgstr ""
|
||||
|
||||
msgid "Provider ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Provision instructions"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import Vue, { nextTick } from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import { TEST_HOST } from 'spec/test_constants';
|
||||
|
||||
import App from '~/diffs/components/app.vue';
|
||||
import CommitWidget from '~/diffs/components/commit_widget.vue';
|
||||
import CompareVersions from '~/diffs/components/compare_versions.vue';
|
||||
|
@ -17,6 +18,8 @@ import DiffsFileTree from '~/diffs/components/diffs_file_tree.vue';
|
|||
import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue';
|
||||
import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue';
|
||||
|
||||
import eventHub from '~/diffs/event_hub';
|
||||
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
|
||||
import { Mousetrap } from '~/lib/mousetrap';
|
||||
|
@ -760,4 +763,29 @@ describe('diffs/components/app', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('autoscroll', () => {
|
||||
let loadSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
loadSpy = jest.spyOn(wrapper.vm, 'loadCollapsedDiff').mockResolvedValue('resolved');
|
||||
});
|
||||
|
||||
it('does nothing if the location hash does not include a file hash', () => {
|
||||
window.location.hash = 'not_a_file_hash';
|
||||
|
||||
eventHub.$emit('doneLoadingBatches');
|
||||
|
||||
expect(loadSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('requests that the correct file be loaded', () => {
|
||||
window.location.hash = '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_0_1';
|
||||
|
||||
eventHub.$emit('doneLoadingBatches');
|
||||
|
||||
expect(loadSpy).toHaveBeenCalledWith({ file: store.state.diffs.diffFiles[0] });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,8 +8,12 @@ import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
|
|||
|
||||
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
|
||||
import { DIFF_FILE_AUTOMATIC_COLLAPSE, DIFF_FILE_MANUAL_COLLAPSE } from '~/diffs/constants';
|
||||
import { reviewFile } from '~/diffs/store/actions';
|
||||
import { SET_DIFF_FILE_VIEWED, SET_MR_FILE_REVIEWS } from '~/diffs/store/mutation_types';
|
||||
import { reviewFile, setFileForcedOpen } from '~/diffs/store/actions';
|
||||
import {
|
||||
SET_DIFF_FILE_VIEWED,
|
||||
SET_MR_FILE_REVIEWS,
|
||||
SET_FILE_FORCED_OPEN,
|
||||
} from '~/diffs/store/mutation_types';
|
||||
import { diffViewerModes } from '~/ide/constants';
|
||||
import { scrollToElement } from '~/lib/utils/common_utils';
|
||||
import { truncateSha } from '~/lib/utils/text_utility';
|
||||
|
@ -67,6 +71,7 @@ describe('DiffFileHeader component', () => {
|
|||
toggleFullDiff: jest.fn(),
|
||||
setCurrentFileHash: jest.fn(),
|
||||
setFileCollapsedByUser: jest.fn(),
|
||||
setFileForcedOpen: jest.fn(),
|
||||
reviewFile: jest.fn(),
|
||||
},
|
||||
},
|
||||
|
@ -138,6 +143,19 @@ describe('DiffFileHeader component', () => {
|
|||
expect(wrapper.emitted().toggleFile).toBeDefined();
|
||||
});
|
||||
|
||||
it('when header is clicked it triggers the action that removes the value that forces a file to be uncollapsed', () => {
|
||||
createComponent();
|
||||
findHeader().trigger('click');
|
||||
|
||||
return testAction(
|
||||
setFileForcedOpen,
|
||||
{ filePath: diffFile.file_path, forced: false },
|
||||
{},
|
||||
[{ type: SET_FILE_FORCED_OPEN, payload: { filePath: diffFile.file_path, forced: false } }],
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it('when collapseIcon is clicked emits toggleFile', async () => {
|
||||
createComponent({ props: { collapsible: true } });
|
||||
findCollapseButton().vm.$emit('click', new Event('click'));
|
||||
|
@ -643,6 +661,44 @@ describe('DiffFileHeader component', () => {
|
|||
expect(Boolean(wrapper.emitted().toggleFile)).toBe(fires);
|
||||
},
|
||||
);
|
||||
|
||||
it('removes the property that forces a file to be shown when the file review is toggled', () => {
|
||||
createComponent({
|
||||
props: {
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
viewer: {
|
||||
...diffFile.viewer,
|
||||
automaticallyCollapsed: false,
|
||||
manuallyCollapsed: null,
|
||||
},
|
||||
},
|
||||
showLocalFileReviews: true,
|
||||
addMergeRequestButtons: true,
|
||||
expanded: false,
|
||||
},
|
||||
});
|
||||
|
||||
findReviewFileCheckbox().vm.$emit('change', true);
|
||||
|
||||
testAction(
|
||||
setFileForcedOpen,
|
||||
{ filePath: diffFile.file_path, forced: false },
|
||||
{},
|
||||
[{ type: SET_FILE_FORCED_OPEN, payload: { filePath: diffFile.file_path, forced: false } }],
|
||||
[],
|
||||
);
|
||||
|
||||
findReviewFileCheckbox().vm.$emit('change', false);
|
||||
|
||||
testAction(
|
||||
setFileForcedOpen,
|
||||
{ filePath: diffFile.file_path, forced: false },
|
||||
{},
|
||||
[{ type: SET_FILE_FORCED_OPEN, payload: { filePath: diffFile.file_path, forced: false } }],
|
||||
[],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should render the comment on files button', () => {
|
||||
|
|
|
@ -324,6 +324,22 @@ describe('DiffFile', () => {
|
|||
});
|
||||
|
||||
describe('collapsing', () => {
|
||||
describe('forced open', () => {
|
||||
it('should have content even when it is automatically collapsed', () => {
|
||||
makeFileAutomaticallyCollapsed(store);
|
||||
|
||||
expect(findDiffContentArea(wrapper).element.children.length).toBe(1);
|
||||
expect(wrapper.classes('has-body')).toBe(true);
|
||||
});
|
||||
|
||||
it('should have content even when it is manually collapsed', () => {
|
||||
makeFileManuallyCollapsed(store);
|
||||
|
||||
expect(findDiffContentArea(wrapper).element.children.length).toBe(1);
|
||||
expect(wrapper.classes('has-body')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`\`${EVT_EXPAND_ALL_FILES}\` event`, () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(wrapper.vm, 'handleToggle').mockImplementation(() => {});
|
||||
|
|
|
@ -1627,6 +1627,7 @@ describe('DiffsStoreActions', () => {
|
|||
name: updatedViewerName,
|
||||
automaticallyCollapsed: false,
|
||||
manuallyCollapsed: false,
|
||||
forceOpen: false,
|
||||
};
|
||||
const testData = [{ rich_text: 'test' }, { rich_text: 'file2' }];
|
||||
let renamedFile;
|
||||
|
@ -1673,7 +1674,7 @@ describe('DiffsStoreActions', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('setFileUserCollapsed', () => {
|
||||
describe('setFileCollapsedByUser', () => {
|
||||
it('commits SET_FILE_COLLAPSED', () => {
|
||||
return testAction(
|
||||
diffActions.setFileCollapsedByUser,
|
||||
|
@ -1690,6 +1691,17 @@ describe('DiffsStoreActions', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('setFileForcedOpen', () => {
|
||||
it('commits SET_FILE_FORCED_OPEN', () => {
|
||||
return testAction(diffActions.setFileForcedOpen, { filePath: 'test', forced: true }, null, [
|
||||
{
|
||||
type: types.SET_FILE_FORCED_OPEN,
|
||||
payload: { filePath: 'test', forced: true },
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setExpandedDiffLines', () => {
|
||||
beforeEach(() => {
|
||||
utils.idleCallback.mockImplementation((cb) => {
|
||||
|
|
|
@ -1055,4 +1055,14 @@ describe('DiffsStoreMutations', () => {
|
|||
expect(state.diffFiles[0].drafts[0]).toEqual('test');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_FILE_FORCED_OPEN', () => {
|
||||
it('sets the forceOpen property of a diff file viewer correctly', () => {
|
||||
const state = { diffFiles: [{ file_path: 'abc', viewer: { forceOpen: 'not-a-boolean' } }] };
|
||||
|
||||
mutations[types.SET_FILE_FORCED_OPEN](state, { filePath: 'abc', force: true });
|
||||
|
||||
expect(state.diffFiles[0].viewer.forceOpen).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
updateChangesTabCount,
|
||||
getDerivedMergeRequestInformation,
|
||||
extractFileHash,
|
||||
} from '~/diffs/utils/merge_request';
|
||||
import { ZERO_CHANGES_ALT_DISPLAY } from '~/diffs/constants';
|
||||
import { diffMetadata } from '../mock_data/diff_metadata';
|
||||
|
@ -128,4 +129,19 @@ describe('Merge Request utilities', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractFileHash', () => {
|
||||
const sha1Like = 'abcdef1234567890abcdef1234567890abcdef12';
|
||||
const sha1LikeToo = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
|
||||
it('returns undefined when a SHA1-like string cannot be found in the input', () => {
|
||||
expect(extractFileHash({ input: 'something' })).toBe(undefined);
|
||||
});
|
||||
|
||||
it('returns the first matching string of SHA1-like characters in the input', () => {
|
||||
const fullString = `#${sha1Like}_34_42--${sha1LikeToo}`;
|
||||
|
||||
expect(extractFileHash({ input: fullString })).toBe(sha1Like);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe SidekiqHelper, feature_category: :shared do
|
||||
describe 'parse_sidekiq_ps' do
|
||||
it 'parses line with time' do
|
||||
line = '55137 10,0 2,1 S+ 2:30pm sidekiq 4.1.4 gitlab [0 of 25 busy] '
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['55137', '10,0', '2,1', 'S+', '2:30pm', 'sidekiq 4.1.4 gitlab [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses line with date' do
|
||||
line = '55137 10,0 2,1 S+ Aug 4 sidekiq 4.1.4 gitlab [0 of 25 busy] '
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['55137', '10,0', '2,1', 'S+', 'Aug 4', 'sidekiq 4.1.4 gitlab [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses line with two digit date' do
|
||||
line = '55137 10,0 2,1 S+ Aug 04 sidekiq 4.1.4 gitlab [0 of 25 busy] '
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['55137', '10,0', '2,1', 'S+', 'Aug 04', 'sidekiq 4.1.4 gitlab [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses line with dot as float separator' do
|
||||
line = '55137 10.0 2.1 S+ 2:30pm sidekiq 4.1.4 gitlab [0 of 25 busy] '
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['55137', '10.0', '2.1', 'S+', '2:30pm', 'sidekiq 4.1.4 gitlab [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses OSX output' do
|
||||
line = ' 1641 1.5 3.8 S+ 4:04PM sidekiq 4.2.1 gitlab [0 of 25 busy]'
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['1641', '1.5', '3.8', 'S+', '4:04PM', 'sidekiq 4.2.1 gitlab [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses Ubuntu output' do
|
||||
# Ubuntu Linux 16.04 LTS / procps-3.3.10-4ubuntu2
|
||||
line = ' 938 1.4 2.5 Sl+ 21:23:21 sidekiq 4.2.1 gitlab [0 of 25 busy] '
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['938', '1.4', '2.5', 'Sl+', '21:23:21', 'sidekiq 4.2.1 gitlab [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses Debian output' do
|
||||
# Debian Linux Wheezy/Jessie
|
||||
line = '17725 1.0 12.1 Ssl 19:20:15 sidekiq 4.2.1 gitlab-rails [0 of 25 busy] '
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['17725', '1.0', '12.1', 'Ssl', '19:20:15', 'sidekiq 4.2.1 gitlab-rails [0 of 25 busy]'])
|
||||
end
|
||||
|
||||
it 'parses OpenBSD output' do
|
||||
# OpenBSD 6.1
|
||||
line = '49258 0.5 2.3 R/0 Fri10PM ruby23: sidekiq 4.2.7 gitlab [0 of 25 busy] (ruby23)'
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['49258', '0.5', '2.3', 'R/0', 'Fri10PM', 'ruby23: sidekiq 4.2.7 gitlab [0 of 25 busy] (ruby23)'])
|
||||
end
|
||||
|
||||
it 'does fail gracefully on line not matching the format' do
|
||||
line = '55137 10.0 2.1 S+ 2:30pm something'
|
||||
parts = helper.parse_sidekiq_ps(line)
|
||||
|
||||
expect(parts).to eq(['?', '?', '?', '?', '?', '?'])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -76,20 +76,6 @@ RSpec.describe SortingHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#issuable_sort_option_title' do
|
||||
it 'returns correct title for issuable_sort_option_overrides key' do
|
||||
expect(issuable_sort_option_title('created_asc')).to eq('Created date')
|
||||
end
|
||||
|
||||
it 'returns correct title for a valid sort value' do
|
||||
expect(issuable_sort_option_title('priority')).to eq('Priority')
|
||||
end
|
||||
|
||||
it 'returns nil for invalid sort value' do
|
||||
expect(issuable_sort_option_title('invalid_key')).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#issuable_sort_direction_button' do
|
||||
before do
|
||||
set_sorting_url 'test_label'
|
||||
|
@ -209,17 +195,6 @@ RSpec.describe SortingHelper do
|
|||
stub_controller_path 'forks'
|
||||
end
|
||||
|
||||
describe '#forks_sort_options_hash' do
|
||||
it 'returns a hash of available sorting options' do
|
||||
expect(forks_sort_options_hash).to include({
|
||||
sort_value_recently_created => sort_title_created_date,
|
||||
sort_value_oldest_created => sort_title_created_date,
|
||||
sort_value_latest_activity => sort_title_latest_activity,
|
||||
sort_value_oldest_activity => sort_title_latest_activity
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe '#forks_reverse_sort_options_hash' do
|
||||
context 'for each sort option' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
|
|
@ -61,4 +61,32 @@ RSpec.describe API::Entities::BasicProjectDetails, feature_category: :api do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#repository_storage' do
|
||||
let_it_be(:project) { build(:project, :public) }
|
||||
|
||||
context 'with anonymous user' do
|
||||
let_it_be(:current_user) { nil }
|
||||
|
||||
it 'is not included' do
|
||||
expect(output).not_to include(:repository_storage)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with normal user' do
|
||||
let_it_be(:current_user) { create(:user) }
|
||||
|
||||
it 'is not included' do
|
||||
expect(output).not_to include(:repository_storage)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with admin user' do
|
||||
let_it_be(:current_user) { create(:user, :admin) }
|
||||
|
||||
it 'is included', :enable_admin_mode do
|
||||
expect(output).to include repository_storage: project.repository_storage
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue