Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d2d9859ef4
commit
7f0fd430c2
|
|
@ -2568,6 +2568,7 @@ Gitlab/BoundedContexts:
|
|||
- 'ee/app/graphql/resolvers/vulnerabilities_grade_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/vulnerabilities_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/vulnerability_severities_count_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/vulnerability_filterable.rb'
|
||||
- 'ee/app/graphql/subscriptions/ai_completion_response.rb'
|
||||
- 'ee/app/graphql/types/access_levels/group_type.rb'
|
||||
- 'ee/app/graphql/types/admin/cloud_licenses/current_license_type.rb'
|
||||
|
|
|
|||
|
|
@ -193,19 +193,6 @@ Layout/ArgumentAlignment:
|
|||
- 'lib/api/ci/resource_groups.rb'
|
||||
- 'lib/api/ci/runner.rb'
|
||||
- 'lib/api/ci/runners.rb'
|
||||
- 'lib/api/ci/triggers.rb'
|
||||
- 'lib/api/commit_statuses.rb'
|
||||
- 'lib/api/commits.rb'
|
||||
- 'lib/api/concerns/packages/debian_distribution_endpoints.rb'
|
||||
- 'lib/api/concerns/packages/npm_endpoints.rb'
|
||||
- 'lib/api/container_repositories.rb'
|
||||
- 'lib/api/dependency_proxy.rb'
|
||||
- 'lib/api/deploy_keys.rb'
|
||||
- 'lib/api/deploy_tokens.rb'
|
||||
- 'lib/api/deployments.rb'
|
||||
- 'lib/api/entities/application.rb'
|
||||
- 'lib/api/entities/application_statistics.rb'
|
||||
- 'lib/api/entities/branch.rb'
|
||||
- 'lib/api/entities/npm_package.rb'
|
||||
- 'lib/api/entities/nuget/dependency_group.rb'
|
||||
- 'lib/api/entities/nuget/package_metadata.rb'
|
||||
|
|
@ -219,19 +206,6 @@ Layout/ArgumentAlignment:
|
|||
- 'lib/api/entities/pull_mirror.rb'
|
||||
- 'lib/api/entities/release.rb'
|
||||
- 'lib/api/entities/resource_access_token.rb'
|
||||
- 'lib/api/merge_requests.rb'
|
||||
- 'lib/api/metrics/dashboard/annotations.rb'
|
||||
- 'lib/api/metrics/user_starred_dashboards.rb'
|
||||
- 'lib/api/milestone_responses.rb'
|
||||
- 'lib/api/notes.rb'
|
||||
- 'lib/api/nuget_project_packages.rb'
|
||||
- 'lib/api/pages.rb'
|
||||
- 'lib/api/pages_domains.rb'
|
||||
- 'lib/api/pagination_params.rb'
|
||||
- 'lib/api/personal_access_tokens.rb'
|
||||
- 'lib/api/project_container_repositories.rb'
|
||||
- 'lib/api/project_export.rb'
|
||||
- 'lib/api/project_import.rb'
|
||||
- 'lib/api/tags.rb'
|
||||
- 'lib/api/terraform/state.rb'
|
||||
- 'lib/api/topics.rb'
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
# Cop supports --autocorrect.
|
||||
Layout/MultilineOperationIndentation:
|
||||
Exclude:
|
||||
- 'app/policies/project_policy.rb'
|
||||
- 'app/serializers/deploy_keys/deploy_key_entity.rb'
|
||||
- 'app/services/ci/create_downstream_pipeline_service.rb'
|
||||
- 'app/services/git/branch_hooks_service.rb'
|
||||
- 'app/services/groups/transfer_service.rb'
|
||||
- 'app/services/issues/update_service.rb'
|
||||
- 'app/services/labels/promote_service.rb'
|
||||
- 'app/services/labels/transfer_service.rb'
|
||||
- 'app/services/members/approve_access_request_service.rb'
|
||||
- 'app/services/webauthn/authenticate_service.rb'
|
||||
|
|
@ -21,18 +21,6 @@ Lint/AmbiguousOperatorPrecedence:
|
|||
- 'ee/app/services/geo/registry_consistency_service.rb'
|
||||
- 'ee/app/services/vulnerabilities/create_service.rb'
|
||||
- 'ee/lib/gitlab/expiring_subscription_message.rb'
|
||||
- 'lib/banzai/filter/references/user_reference_filter.rb'
|
||||
- 'lib/banzai/filter_array.rb'
|
||||
- 'lib/extracts_ref.rb'
|
||||
- 'lib/gitlab/chaos.rb'
|
||||
- 'lib/gitlab/ci/config/normalizer/number_strategy.rb'
|
||||
- 'lib/gitlab/console.rb'
|
||||
- 'lib/gitlab/database/background_migration/batch_metrics.rb'
|
||||
- 'lib/gitlab/database/background_migration/batched_migration.rb'
|
||||
- 'lib/gitlab/database/migrations/background_migration_helpers.rb'
|
||||
- 'lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb'
|
||||
- 'lib/gitlab/database/postgres_hll/buckets.rb'
|
||||
- 'lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb'
|
||||
- 'spec/lib/gitlab/conan_token_spec.rb'
|
||||
- 'spec/lib/gitlab/database/background_migration/batched_job_spec.rb'
|
||||
- 'spec/lib/gitlab/database/batch_count_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
v17.1.0-rc6
|
||||
v17.1.0-rc7
|
||||
|
|
|
|||
11
Gemfile
11
Gemfile
|
|
@ -140,7 +140,7 @@ gem 'rack-cors', '~> 2.0.1', require: 'rack/cors' # rubocop:todo Gemfile/Missing
|
|||
gem 'graphql', '~> 2.3.3', feature_category: :api
|
||||
gem 'graphql-docs', '~> 4.0.0', group: [:development, :test], feature_category: :api
|
||||
gem 'graphiql-rails', '~> 1.8.0', feature_category: :api
|
||||
gem 'apollo_upload_server', '~> 2.1.5', feature_category: :api
|
||||
gem 'apollo_upload_server', '~> 2.1.6', feature_category: :api
|
||||
gem 'graphlient', '~> 0.6.0', feature_category: :importers # Used by BulkImport feature (group::import)
|
||||
|
||||
# Generate Fake data
|
||||
|
|
@ -536,7 +536,7 @@ group :test do
|
|||
|
||||
gem 'capybara', '~> 3.40' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
gem 'capybara-screenshot', '~> 1.0.26' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
gem 'selenium-webdriver', '~> 4.20', '>= 4.20.1' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
gem 'selenium-webdriver', '~> 4.21', '>= 4.21.1' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
gem 'graphlyte', '~> 1.0.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
|
|
@ -682,9 +682,10 @@ gem 'telesignenterprise', '~> 2.2' # rubocop:todo Gemfile/MissingFeatureCategory
|
|||
# BufferedIO patch
|
||||
# Updating this version will require updating scripts/allowed_warnings.txt
|
||||
gem 'net-protocol', '~> 0.1.3' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
# Lock this until we make DNS rebinding work with the updated net-http:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/413528
|
||||
gem 'net-http', '= 0.1.1' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
# This is locked to 0.4.1 because we patch Net::HTTP#connect in
|
||||
# gems/gitlab-http/lib/net_http/connect_patch.rb.
|
||||
gem 'net-http', '= 0.4.1', feature_category: :shared
|
||||
|
||||
gem 'duo_api', '~> 1.3' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
{"name":"aliyun-sdk","version":"0.8.0","platform":"ruby","checksum":"65915d3f9b528082253d1f9ad0e4d13d6b552933fe49251c68c6915cd4d75b9d"},
|
||||
{"name":"amatch","version":"0.4.1","platform":"ruby","checksum":"d3ff15226a2e627c72802e94579db829e5e10c96cf89d329494caec5889145f7"},
|
||||
{"name":"android_key_attestation","version":"0.3.0","platform":"ruby","checksum":"467eb01a99d2bb48ef9cf24cc13712669d7056cba5a52d009554ff037560570b"},
|
||||
{"name":"apollo_upload_server","version":"2.1.5","platform":"ruby","checksum":"0f66bea96bdf7ce8b7278712ebafc8a26b82864ea6541213b58d9b3f673413a5"},
|
||||
{"name":"apollo_upload_server","version":"2.1.6","platform":"ruby","checksum":"dcec4072258e6518b0b82e03b485efbddde946813543c14184fc81952d6bcdb2"},
|
||||
{"name":"app_store_connect","version":"0.29.0","platform":"ruby","checksum":"01d7a923825a4221892099acb5a72f86f6ee7d8aa95815d3c459ba6816ea430f"},
|
||||
{"name":"arr-pm","version":"0.0.12","platform":"ruby","checksum":"fdff482f75239239201f4d667d93424412639aad0b3b0ad4d827e7c637e0ad39"},
|
||||
{"name":"asciidoctor","version":"2.0.18","platform":"ruby","checksum":"bbd1e1d16deed8db94bf9624b9f4474fac32d9ca7225d377f076c08d9adde387"},
|
||||
|
|
@ -395,7 +395,7 @@
|
|||
{"name":"nap","version":"1.1.0","platform":"ruby","checksum":"949691660f9d041d75be611bb2a8d2fd559c467537deac241f4097d9b5eea576"},
|
||||
{"name":"neighbor","version":"0.3.2","platform":"ruby","checksum":"b795bbcc24b1b9ae82d9f7e97a3461b0b3607d24a85a7acbed776bd498e7eba8"},
|
||||
{"name":"nenv","version":"0.3.0","platform":"ruby","checksum":"d9de6d8fb7072228463bf61843159419c969edb34b3cef51832b516ae7972765"},
|
||||
{"name":"net-http","version":"0.1.1","platform":"ruby","checksum":"75a4e109b6f9af32fad0e98a6180c47aceb415927ca3bd70c8fc3e7dbbabbe86"},
|
||||
{"name":"net-http","version":"0.4.1","platform":"ruby","checksum":"a96efc5ea18bcb9715e24dda4159d10f67ff0345c8a980d04630028055b2c282"},
|
||||
{"name":"net-http-persistent","version":"4.0.1","platform":"ruby","checksum":"2752f4cce05fd1c45e0537c6f3a98fa5a4899efd5f88e63c104ed5f05cbddef9"},
|
||||
{"name":"net-imap","version":"0.3.4","platform":"ruby","checksum":"a82a59e2a429433dc54cae5a8b2979ffe49da8c66085740811bfa337dc3729b5"},
|
||||
{"name":"net-ldap","version":"0.17.1","platform":"ruby","checksum":"52571b55f9157120833ac1667f2969ce0139251811d0a9b64657c1c135069cf9"},
|
||||
|
|
@ -617,7 +617,7 @@
|
|||
{"name":"sawyer","version":"0.9.2","platform":"ruby","checksum":"fa3a72d62a4525517b18857ddb78926aab3424de0129be6772a8e2ba240e7aca"},
|
||||
{"name":"sd_notify","version":"0.1.1","platform":"ruby","checksum":"cbc7ac6caa7cedd26b30a72b5eeb6f36050dc0752df263452ea24fb5a4ad3131"},
|
||||
{"name":"seed-fu","version":"2.3.7","platform":"ruby","checksum":"f19673443e9af799b730e3d4eca6a89b39e5a36825015dffd00d02ea3365cf74"},
|
||||
{"name":"selenium-webdriver","version":"4.20.1","platform":"ruby","checksum":"560ca00d45bed16d661089da674290ce81564949888daa1f8659fe77fd39a2ac"},
|
||||
{"name":"selenium-webdriver","version":"4.21.1","platform":"ruby","checksum":"c30b64014532fc5156c60797985f839f36adbe60ff4653e7112b008dc1c83263"},
|
||||
{"name":"semver_dialects","version":"2.0.2","platform":"ruby","checksum":"60059c9f416f931b5212d862fad2879d6b9affb8e0b9afb0d91b793639c116fe"},
|
||||
{"name":"sentry-rails","version":"5.17.3","platform":"ruby","checksum":"017771c42d739c0ad2213a581ca9d005cf543227bc13662cd1ca9909f2429459"},
|
||||
{"name":"sentry-ruby","version":"5.17.3","platform":"ruby","checksum":"61791a4b0bb0f95cd87aceeaa1efa6d4ab34d64236c9d5df820478adfe2fbbfc"},
|
||||
|
|
|
|||
14
Gemfile.lock
14
Gemfile.lock
|
|
@ -48,6 +48,7 @@ PATH
|
|||
concurrent-ruby (~> 1.2)
|
||||
httparty (~> 0.21.0)
|
||||
ipaddress (~> 0.8.3)
|
||||
net-http (= 0.4.1)
|
||||
railties (~> 7)
|
||||
|
||||
PATH
|
||||
|
|
@ -278,7 +279,7 @@ GEM
|
|||
mize
|
||||
tins (~> 1.0)
|
||||
android_key_attestation (0.3.0)
|
||||
apollo_upload_server (2.1.5)
|
||||
apollo_upload_server (2.1.6)
|
||||
actionpack (>= 6.1.6)
|
||||
graphql (>= 1.8)
|
||||
app_store_connect (0.29.0)
|
||||
|
|
@ -1115,8 +1116,7 @@ GEM
|
|||
neighbor (0.3.2)
|
||||
activerecord (>= 6.1)
|
||||
nenv (0.3.0)
|
||||
net-http (0.1.1)
|
||||
net-protocol
|
||||
net-http (0.4.1)
|
||||
uri
|
||||
net-http-persistent (4.0.1)
|
||||
connection_pool (~> 2.2)
|
||||
|
|
@ -1643,7 +1643,7 @@ GEM
|
|||
seed-fu (2.3.7)
|
||||
activerecord (>= 3.1)
|
||||
activesupport (>= 3.1)
|
||||
selenium-webdriver (4.20.1)
|
||||
selenium-webdriver (4.21.1)
|
||||
base64 (~> 0.2)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2, < 3.0)
|
||||
|
|
@ -1912,7 +1912,7 @@ DEPENDENCIES
|
|||
acts-as-taggable-on (~> 10.0)
|
||||
addressable (~> 2.8)
|
||||
akismet (~> 3.0)
|
||||
apollo_upload_server (~> 2.1.5)
|
||||
apollo_upload_server (~> 2.1.6)
|
||||
app_store_connect
|
||||
arr-pm (~> 0.0.12)
|
||||
asciidoctor (~> 2.0.18)
|
||||
|
|
@ -2095,7 +2095,7 @@ DEPENDENCIES
|
|||
minitest (~> 5.11.0)
|
||||
multi_json (~> 1.14.1)
|
||||
neighbor (~> 0.3.2)
|
||||
net-http (= 0.1.1)
|
||||
net-http (= 0.4.1)
|
||||
net-ldap (~> 0.17.1)
|
||||
net-ntp
|
||||
net-protocol (~> 0.1.3)
|
||||
|
|
@ -2203,7 +2203,7 @@ DEPENDENCIES
|
|||
sanitize (~> 6.0.2)
|
||||
sd_notify (~> 0.1.0)
|
||||
seed-fu (~> 2.3.7)
|
||||
selenium-webdriver (~> 4.20, >= 4.20.1)
|
||||
selenium-webdriver (~> 4.21, >= 4.21.1)
|
||||
semver_dialects (~> 2.0, >= 2.0.2)
|
||||
sentry-rails (~> 5.17.3)
|
||||
sentry-ruby (~> 5.17.3)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlForm, GlFormFields, GlButton, GlLink, GlAlert } from '@gitlab/ui';
|
||||
import { GlForm, GlFormFields, GlButton, GlLink, GlAlert, GlSprintf } from '@gitlab/ui';
|
||||
import { formValidators } from '@gitlab/ui/dist/utils';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import { slugify } from '~/lib/utils/text_utility';
|
||||
|
|
@ -7,26 +7,36 @@ import VisibilityLevelRadioButtons from '~/visibility_level/components/visibilit
|
|||
import { GROUP_VISIBILITY_LEVEL_DESCRIPTIONS } from '~/visibility_level/constants';
|
||||
import { restrictedVisibilityLevelsMessage } from '~/visibility_level/utils';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { FORM_FIELD_NAME, FORM_FIELD_PATH, FORM_FIELD_VISIBILITY_LEVEL } from '../constants';
|
||||
import HelpPageLink from '~/vue_shared/components/help_page_link/help_page_link.vue';
|
||||
import {
|
||||
FORM_FIELD_NAME,
|
||||
FORM_FIELD_PATH,
|
||||
FORM_FIELD_ID,
|
||||
FORM_FIELD_VISIBILITY_LEVEL,
|
||||
} from '../constants';
|
||||
import GroupPathField from './group_path_field.vue';
|
||||
|
||||
export default {
|
||||
name: 'NewGroupForm',
|
||||
name: 'NewEditForm',
|
||||
components: {
|
||||
GlForm,
|
||||
GlFormFields,
|
||||
GlButton,
|
||||
GlLink,
|
||||
GlAlert,
|
||||
GlSprintf,
|
||||
GroupPathField,
|
||||
VisibilityLevelRadioButtons,
|
||||
HelpPageLink,
|
||||
},
|
||||
i18n: {
|
||||
cancel: __('Cancel'),
|
||||
submitButtonText: __('Create group'),
|
||||
warningForUsingDotInName: s__(
|
||||
'Groups|Your group name must not contain a period if you intend to use SCIM integration, as it can lead to errors.',
|
||||
),
|
||||
warningForChangingUrl: s__(
|
||||
'Groups|Changing group URL can have unintended side effects. %{linkStart}Learn more%{linkEnd}.',
|
||||
),
|
||||
},
|
||||
GROUP_VISIBILITY_LEVEL_DESCRIPTIONS,
|
||||
formId: 'organization-new-group-form',
|
||||
|
|
@ -39,6 +49,11 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
submitButtonText: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: __('Create group'),
|
||||
},
|
||||
cancelPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
|
@ -66,7 +81,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
hasPathBeenManuallySet: false,
|
||||
hasPathBeenManuallySet: this.initialFormValues[FORM_FIELD_PATH],
|
||||
isPathLoading: false,
|
||||
formValues: this.initialFormValues,
|
||||
};
|
||||
|
|
@ -114,6 +129,20 @@ export default {
|
|||
: null,
|
||||
},
|
||||
},
|
||||
...(this.isEditing
|
||||
? {
|
||||
[FORM_FIELD_ID]: {
|
||||
label: s__('Groups|Group ID'),
|
||||
groupAttrs: {
|
||||
class: 'gl-w-full',
|
||||
},
|
||||
inputAttrs: {
|
||||
class: 'gl-md-form-input-lg',
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
[FORM_FIELD_VISIBILITY_LEVEL]: {
|
||||
label: __('Visibility level'),
|
||||
labelDescription: {
|
||||
|
|
@ -132,6 +161,9 @@ export default {
|
|||
},
|
||||
};
|
||||
},
|
||||
isEditing() {
|
||||
return this.initialFormValues[FORM_FIELD_ID];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
[`formValues.${FORM_FIELD_NAME}`](newName) {
|
||||
|
|
@ -184,6 +216,22 @@ export default {
|
|||
@loading-change="onPathLoading"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="isEditing" #after(path)>
|
||||
<gl-alert
|
||||
class="gl-mb-5"
|
||||
:dismissible="false"
|
||||
variant="warning"
|
||||
data-testid="changing-url-alert"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.warningForChangingUrl">
|
||||
<template #link="{ content }">
|
||||
<help-page-link href="user/group/manage" anchor="change-a-groups-path">{{
|
||||
content
|
||||
}}</help-page-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</gl-alert>
|
||||
</template>
|
||||
<template #input(visibilityLevel)="{ value, input }">
|
||||
<visibility-level-radio-buttons
|
||||
:checked="value"
|
||||
|
|
@ -207,7 +255,7 @@ export default {
|
|||
:loading="loading"
|
||||
class="js-no-auto-disable"
|
||||
data-testid="submit-button"
|
||||
>{{ $options.i18n.submitButtonText }}</gl-button
|
||||
>{{ submitButtonText }}</gl-button
|
||||
>
|
||||
<gl-button :href="cancelPath">{{ $options.i18n.cancel }}</gl-button>
|
||||
</div>
|
||||
|
|
@ -72,4 +72,5 @@ export const OVERVIEW_TABS_ARCHIVED_PROJECTS_SORTING_ITEMS = [
|
|||
|
||||
export const FORM_FIELD_NAME = 'name';
|
||||
export const FORM_FIELD_PATH = 'path';
|
||||
export const FORM_FIELD_ID = 'id';
|
||||
export const FORM_FIELD_VISIBILITY_LEVEL = 'visibilityLevel';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlAccordion, GlAccordionItem, GlIcon } from '@gitlab/ui';
|
||||
import { GlAccordion, GlAccordionItem, GlIcon, GlLink } from '@gitlab/ui';
|
||||
|
||||
import { BULK_IMPORT_STATIC_ITEMS } from '~/import/constants';
|
||||
import { STATUSES } from '../constants';
|
||||
|
|
@ -11,9 +11,15 @@ export default {
|
|||
GlAccordion,
|
||||
GlAccordionItem,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
},
|
||||
|
||||
props: {
|
||||
failuresHref: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
stats: {
|
||||
type: Object,
|
||||
required: false,
|
||||
|
|
@ -63,7 +69,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<gl-accordion :header-level="3">
|
||||
<gl-accordion-item :title="__('Details')">
|
||||
<gl-accordion-item :title="__('View details')">
|
||||
<ul class="gl-p-0 gl-mb-3 gl-list-none gl-font-sm">
|
||||
<li v-for="key in Object.keys(stats)" :key="key" data-testid="import-stat-item">
|
||||
<div class="gl-display-flex gl-w-28 gl-align-items-center">
|
||||
|
|
@ -73,6 +79,9 @@ export default {
|
|||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<gl-link v-if="failuresHref" :href="failuresHref"
|
||||
>{{ s__('Import|Show errors') }} ></gl-link
|
||||
>
|
||||
</gl-accordion-item>
|
||||
</gl-accordion>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import { GlAccordion, GlAccordionItem, GlBadge, GlIcon, GlLink } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
import { STATISTIC_ITEMS } from '~/import/constants';
|
||||
import { STATUSES, STATUS_ICON_MAP } from '../constants';
|
||||
|
|
@ -99,9 +98,6 @@ export default {
|
|||
},
|
||||
|
||||
STATISTIC_ITEMS,
|
||||
i18n: {
|
||||
detailsLink: s__('Import|See failures'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -129,9 +125,9 @@ export default {
|
|||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<gl-link v-if="showDetails" :href="detailsPathForProject">{{
|
||||
$options.i18n.detailsLink
|
||||
}}</gl-link>
|
||||
<gl-link v-if="showDetails" :href="detailsPathForProject"
|
||||
>{{ s__('Import|Show errors') }} ></gl-link
|
||||
>
|
||||
</gl-accordion-item>
|
||||
</gl-accordion>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,5 +26,5 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-link :href="historyPathWithId">{{ __('View details') }}</gl-link>
|
||||
<gl-link :href="historyPathWithId">{{ s__('BulkImport|Migration details') }} ></gl-link>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -8,28 +8,17 @@ export default {
|
|||
GlLink,
|
||||
},
|
||||
|
||||
inject: {
|
||||
detailsPath: {
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
entityId: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
hasFailures: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
failuresHref: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
|
@ -48,20 +37,6 @@ export default {
|
|||
|
||||
return STATUS_ICON_MAP[this.status];
|
||||
},
|
||||
|
||||
showDetails() {
|
||||
return Boolean(this.detailsPathWithId) && this.hasFailures;
|
||||
},
|
||||
|
||||
detailsPathWithId() {
|
||||
if (!this.id || !this.entityId || !this.detailsPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.detailsPath
|
||||
.replace(':id', encodeURIComponent(this.id))
|
||||
.replace(':entity_id', encodeURIComponent(this.entityId));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -72,8 +47,8 @@ export default {
|
|||
{{ mappedStatus.text }}
|
||||
</gl-badge>
|
||||
|
||||
<div v-if="showDetails" class="gl-mt-2">
|
||||
<gl-link :href="detailsPathWithId">{{ s__('Import|See failures') }}</gl-link>
|
||||
<div v-if="failuresHref" class="gl-mt-2">
|
||||
<gl-link :href="failuresHref">{{ s__('Import|Show errors') }} ></gl-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -637,7 +637,6 @@ export default {
|
|||
gitlabLogo: window.gon.gitlab_logo,
|
||||
PAGE_SIZES,
|
||||
permissionsHelpPath: helpPagePath('user/permissions', { anchor: 'group-members-permissions' }),
|
||||
betaFeatureHelpPath: helpPagePath('policy/experiment-beta-support', { anchor: 'beta-features' }),
|
||||
popoverOptions: { title: __('What is listed here?') },
|
||||
i18n,
|
||||
LOCAL_STORAGE_KEY: 'gl-bulk-imports-status-page-size-v1',
|
||||
|
|
@ -803,23 +802,6 @@ export default {
|
|||
data-testid="import-projects-warning"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span class="gl-ml-3">
|
||||
<gl-icon name="information-o" :size="12" class="gl-text-blue-600" />
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(
|
||||
'BulkImport|Importing projects is a %{docsLinkStart}Beta%{docsLinkEnd} feature.',
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #docsLink="{ content }"
|
||||
><gl-link :href="$options.betaFeatureHelpPath" target="_blank">{{
|
||||
content
|
||||
}}</gl-link></template
|
||||
>
|
||||
</gl-sprintf>
|
||||
</span>
|
||||
</div>
|
||||
<gl-table
|
||||
ref="table"
|
||||
|
|
|
|||
|
|
@ -38,8 +38,9 @@ function parseDatasetToProps(data) {
|
|||
jiraIssueTransitionAutomatic,
|
||||
jiraIssueTransitionId,
|
||||
artifactRegistryPath,
|
||||
personalAccessTokensPath,
|
||||
workloadIdentityFederationPath,
|
||||
workloadIdentityFederationProjectNumber,
|
||||
workloadIdentityPoolId,
|
||||
wlifIssuer,
|
||||
redirectTo,
|
||||
upgradeSlackUrl,
|
||||
|
|
@ -74,7 +75,6 @@ function parseDatasetToProps(data) {
|
|||
testPath,
|
||||
resetPath,
|
||||
formPath,
|
||||
personalAccessTokensPath,
|
||||
triggerFieldsProps: {
|
||||
initialTriggerCommit: commitEvents,
|
||||
initialTriggerMergeRequest: mergeRequestEvents,
|
||||
|
|
@ -95,6 +95,8 @@ function parseDatasetToProps(data) {
|
|||
googleArtifactManagementProps: {
|
||||
artifactRegistryPath,
|
||||
workloadIdentityFederationPath,
|
||||
workloadIdentityFederationProjectNumber,
|
||||
workloadIdentityPoolId,
|
||||
},
|
||||
learnMorePath,
|
||||
aboutPricingUrl,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
<script>
|
||||
import { GlTooltipDirective, GlIcon } from '@gitlab/ui';
|
||||
import UserDate from '~/vue_shared/components/user_date.vue';
|
||||
|
||||
export default {
|
||||
components: { UserDate },
|
||||
components: { UserDate, GlIcon },
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
props: {
|
||||
member: {
|
||||
type: Object,
|
||||
|
|
@ -21,17 +25,35 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="userCreated">
|
||||
<strong>{{ s__('Members|User created') }}:</strong>
|
||||
<div class="gl-display-flex gl-flex-direction-column gl-gap-2">
|
||||
<div v-if="userCreated" class="gl-display-flex gl-gap-3">
|
||||
<gl-icon
|
||||
ref="userCreated"
|
||||
v-gl-tooltip.${userCreated}
|
||||
class="gl-ml-2 gl-mr-n2 gl-text-gray-500"
|
||||
name="assignee"
|
||||
:title="s__('Members|User created')"
|
||||
/>
|
||||
<user-date :date="userCreated" />
|
||||
</div>
|
||||
<div v-if="member.createdAt">
|
||||
<strong>{{ s__('Members|Access granted') }}:</strong>
|
||||
<div v-if="member.createdAt" class="gl-display-flex gl-gap-3">
|
||||
<gl-icon
|
||||
ref="memberCreatedAt"
|
||||
v-gl-tooltip.${memberCreatedAt}
|
||||
class="gl-text-gray-500"
|
||||
name="check"
|
||||
:title="s__('Members|Access granted')"
|
||||
/>
|
||||
<user-date :date="member.createdAt" />
|
||||
</div>
|
||||
<div v-if="lastActivity">
|
||||
<strong>{{ s__('Members|Last activity') }}:</strong>
|
||||
<div v-if="lastActivity" class="gl-display-flex gl-gap-3">
|
||||
<gl-icon
|
||||
ref="lastActivity"
|
||||
v-gl-tooltip.${lastActivity}
|
||||
class="gl-text-gray-500"
|
||||
name="hourglass"
|
||||
:title="s__('Members|Last activity')"
|
||||
/>
|
||||
<user-date :date="lastActivity" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
<script>
|
||||
import { GlEmptyState, GlPagination, GlLoadingIcon } from '@gitlab/ui';
|
||||
import { GlEmptyState, GlPagination, GlLoadingIcon, GlFilteredSearchToken } from '@gitlab/ui';
|
||||
import EMPTY_STATE_SVG_URL from '@gitlab/svgs/dist/illustrations/empty-state/empty-activity-md.svg?url';
|
||||
import { DEFAULT_PER_PAGE } from '~/api';
|
||||
import { __, s__ } from '~/locale';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { createAlert } from '~/alert';
|
||||
import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
|
||||
import ContributionEvents from '~/contribution_events/components/contribution_events.vue';
|
||||
import {
|
||||
CONTRIBUTION_TYPE_FILTER_TYPE,
|
||||
RECENT_SEARCHES_STORAGE_KEY,
|
||||
FILTERED_SEARCH_NAMESPACE,
|
||||
convertTokensToFilter,
|
||||
} from '../filters';
|
||||
|
||||
export default {
|
||||
name: 'OrganizationsActivityApp',
|
||||
|
|
@ -14,8 +22,10 @@ export default {
|
|||
eventsErrorMessage: s__(
|
||||
'Organization|An error occurred loading the activity. Please refresh the page to try again.',
|
||||
),
|
||||
contributionType: __('Contribution type'),
|
||||
},
|
||||
components: {
|
||||
FilteredSearch,
|
||||
ContributionEvents,
|
||||
GlEmptyState,
|
||||
GlPagination,
|
||||
|
|
@ -26,12 +36,21 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
organizationActivityEventTypes: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
organizationActivityAllEvent: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
events: [],
|
||||
eventsLoading: false,
|
||||
page: 1,
|
||||
eventFilter: this.organizationActivityAllEvent,
|
||||
hasNextPage: false,
|
||||
};
|
||||
},
|
||||
|
|
@ -46,6 +65,19 @@ export default {
|
|||
prevPage() {
|
||||
return this.page - 1;
|
||||
},
|
||||
availableTokens() {
|
||||
return [
|
||||
{
|
||||
title: this.$options.i18n.contributionType,
|
||||
icon: 'comparison',
|
||||
type: CONTRIBUTION_TYPE_FILTER_TYPE,
|
||||
token: GlFilteredSearchToken,
|
||||
unique: true,
|
||||
operators: OPERATORS_IS,
|
||||
options: this.organizationActivityEventTypes,
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.fetchEvents();
|
||||
|
|
@ -55,6 +87,10 @@ export default {
|
|||
// Offset is starts at 0, but pages start at page 1. We need to use -1 logic to generate offset
|
||||
return (page - 1) * DEFAULT_PER_PAGE;
|
||||
},
|
||||
onSearchFilter(tokens) {
|
||||
this.eventFilter = convertTokensToFilter(tokens) || this.organizationActivityAllEvent;
|
||||
this.fetchEvents();
|
||||
},
|
||||
async fetchEvents(page = 1) {
|
||||
this.eventsLoading = true;
|
||||
|
||||
|
|
@ -62,7 +98,11 @@ export default {
|
|||
const {
|
||||
data: { events, has_next_page: hasNextPage },
|
||||
} = await axios.get(this.organizationActivityPath, {
|
||||
params: { offset: this.calculateOffset(page), limit: DEFAULT_PER_PAGE },
|
||||
params: {
|
||||
offset: this.calculateOffset(page),
|
||||
limit: DEFAULT_PER_PAGE,
|
||||
event_filter: this.eventFilter,
|
||||
},
|
||||
});
|
||||
|
||||
this.hasNextPage = hasNextPage;
|
||||
|
|
@ -76,26 +116,39 @@ export default {
|
|||
},
|
||||
},
|
||||
EMPTY_STATE_SVG_URL,
|
||||
RECENT_SEARCHES_STORAGE_KEY,
|
||||
FILTERED_SEARCH_NAMESPACE,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="!showEmptyState">
|
||||
<contribution-events :events="events" />
|
||||
<gl-loading-icon v-if="eventsLoading" size="md" class="gl-mb-3" />
|
||||
<gl-pagination
|
||||
v-else
|
||||
:value="page"
|
||||
:prev-page="prevPage"
|
||||
:next-page="nextPage"
|
||||
align="center"
|
||||
class="gl-w-full"
|
||||
@input="fetchEvents"
|
||||
<div>
|
||||
<filtered-search
|
||||
:recent-searches-storage-key="$options.RECENT_SEARCHES_STORAGE_KEY"
|
||||
:namespace="$options.FILTERED_SEARCH_NAMESPACE"
|
||||
:tokens="availableTokens"
|
||||
terms-as-tokens
|
||||
@onFilter="onSearchFilter"
|
||||
/>
|
||||
|
||||
<template v-if="!showEmptyState">
|
||||
<contribution-events :events="events" />
|
||||
<gl-loading-icon v-if="eventsLoading" size="md" class="gl-mb-3" />
|
||||
<gl-pagination
|
||||
v-else
|
||||
:value="page"
|
||||
:prev-page="prevPage"
|
||||
:next-page="nextPage"
|
||||
align="center"
|
||||
class="gl-w-full"
|
||||
@input="fetchEvents"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<gl-empty-state
|
||||
v-else-if="showEmptyState"
|
||||
:title="$options.i18n.emptyStateTitle"
|
||||
:svg-path="$options.EMPTY_STATE_SVG_URL"
|
||||
/>
|
||||
</div>
|
||||
<gl-empty-state
|
||||
v-else-if="showEmptyState"
|
||||
:title="$options.i18n.emptyStateTitle"
|
||||
:svg-path="$options.EMPTY_STATE_SVG_URL"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import { processFilters } from '~/vue_shared/components/filtered_search_bar/filtered_search_utils';
|
||||
|
||||
export const CONTRIBUTION_TYPE_FILTER_TYPE = 'contribution_type';
|
||||
|
||||
export const RECENT_SEARCHES_STORAGE_KEY = 'recent-organizations-activity-filter-search';
|
||||
export const FILTERED_SEARCH_NAMESPACE = 'organizations-activity-filter-search';
|
||||
|
||||
export const convertTokensToFilter = (tokens) => {
|
||||
const processedFilters = processFilters(tokens);
|
||||
|
||||
if (!processedFilters[CONTRIBUTION_TYPE_FILTER_TYPE]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return processedFilters[CONTRIBUTION_TYPE_FILTER_TYPE][0]?.value;
|
||||
};
|
||||
|
|
@ -8,7 +8,11 @@ export const initOrganizationsActivity = () => {
|
|||
const {
|
||||
dataset: { appData },
|
||||
} = el;
|
||||
const { organizationActivityPath } = convertObjectPropsToCamelCase(JSON.parse(appData));
|
||||
const {
|
||||
organizationActivityPath,
|
||||
organizationActivityEventTypes,
|
||||
organizationActivityAllEvent,
|
||||
} = convertObjectPropsToCamelCase(JSON.parse(appData));
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
|
|
@ -17,6 +21,8 @@ export const initOrganizationsActivity = () => {
|
|||
return createElement(OrganizationsActivityApp, {
|
||||
props: {
|
||||
organizationActivityPath,
|
||||
organizationActivityEventTypes,
|
||||
organizationActivityAllEvent,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
<script>
|
||||
import { GlSprintf } from '@gitlab/ui';
|
||||
import NewEditForm from '~/groups/components/new_edit_form.vue';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
name: 'OrganizationGroupsEditApp',
|
||||
components: { GlSprintf },
|
||||
components: { GlSprintf, NewEditForm },
|
||||
i18n: {
|
||||
pageTitle: __('Edit group: %{group_name}'),
|
||||
submitButtonText: __('Save changes'),
|
||||
},
|
||||
inject: ['group'],
|
||||
inject: [
|
||||
'group',
|
||||
'basePath',
|
||||
'groupsAndProjectsOrganizationPath',
|
||||
'groupsOrganizationPath',
|
||||
'availableVisibilityLevels',
|
||||
'restrictedVisibilityLevels',
|
||||
'defaultVisibilityLevel',
|
||||
'pathMaxlength',
|
||||
'pathPattern',
|
||||
],
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -19,5 +31,16 @@ export default {
|
|||
<template #group_name>{{ group.fullName }}</template>
|
||||
</gl-sprintf>
|
||||
</h1>
|
||||
<new-edit-form
|
||||
:loading="false"
|
||||
:base-path="basePath"
|
||||
:path-maxlength="pathMaxlength"
|
||||
:path-pattern="pathPattern"
|
||||
:submit-button-text="$options.i18n.submitButtonText"
|
||||
:cancel-path="groupsAndProjectsOrganizationPath"
|
||||
:available-visibility-levels="availableVisibilityLevels"
|
||||
:restricted-visibility-levels="restrictedVisibilityLevels"
|
||||
:initial-form-values="group"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -11,13 +11,31 @@ export const initOrganizationsGroupsEdit = () => {
|
|||
const {
|
||||
dataset: { appData },
|
||||
} = el;
|
||||
const { group } = convertObjectPropsToCamelCase(JSON.parse(appData), { deep: true });
|
||||
const {
|
||||
group,
|
||||
basePath,
|
||||
groupsAndProjectsOrganizationPath,
|
||||
groupsOrganizationPath,
|
||||
availableVisibilityLevels,
|
||||
restrictedVisibilityLevels,
|
||||
defaultVisibilityLevel,
|
||||
pathMaxlength,
|
||||
pathPattern,
|
||||
} = convertObjectPropsToCamelCase(JSON.parse(appData), { deep: true });
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
name: 'OrganizationGroupsEditRoot',
|
||||
provide: {
|
||||
group,
|
||||
basePath,
|
||||
groupsAndProjectsOrganizationPath,
|
||||
groupsOrganizationPath,
|
||||
availableVisibilityLevels,
|
||||
restrictedVisibilityLevels,
|
||||
defaultVisibilityLevel,
|
||||
pathMaxlength,
|
||||
pathPattern,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(App);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { GlSprintf, GlLink } from '@gitlab/ui';
|
|||
import { s__, __, sprintf } from '~/locale';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import NewGroupForm from '~/groups/components/new_group_form.vue';
|
||||
import NewEditForm from '~/groups/components/new_edit_form.vue';
|
||||
import { FORM_FIELD_NAME, FORM_FIELD_PATH, FORM_FIELD_VISIBILITY_LEVEL } from '~/groups/constants';
|
||||
import { VISIBILITY_LEVELS_INTEGER_TO_STRING } from '~/visibility_level/constants';
|
||||
import { createAlert } from '~/alert';
|
||||
|
|
@ -29,13 +29,12 @@ export default {
|
|||
components: {
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
NewGroupForm,
|
||||
NewEditForm,
|
||||
},
|
||||
inject: [
|
||||
'basePath',
|
||||
'groupsAndProjectsOrganizationPath',
|
||||
'groupsOrganizationPath',
|
||||
'mattermostEnabled',
|
||||
'availableVisibilityLevels',
|
||||
'restrictedVisibilityLevels',
|
||||
'defaultVisibilityLevel',
|
||||
|
|
@ -106,7 +105,7 @@ export default {
|
|||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
<new-group-form
|
||||
<new-edit-form
|
||||
:loading="loading"
|
||||
:base-path="basePath"
|
||||
:path-maxlength="pathMaxlength"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ export const initOrganizationsGroupsNew = () => {
|
|||
basePath,
|
||||
groupsAndProjectsOrganizationPath,
|
||||
groupsOrganizationPath,
|
||||
mattermostEnabled,
|
||||
availableVisibilityLevels,
|
||||
restrictedVisibilityLevels,
|
||||
defaultVisibilityLevel,
|
||||
|
|
@ -37,7 +36,6 @@ export const initOrganizationsGroupsNew = () => {
|
|||
basePath,
|
||||
groupsAndProjectsOrganizationPath,
|
||||
groupsOrganizationPath,
|
||||
mattermostEnabled,
|
||||
availableVisibilityLevels,
|
||||
restrictedVisibilityLevels,
|
||||
defaultVisibilityLevel,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import PaginationBar from '~/vue_shared/components/pagination_bar/pagination_bar
|
|||
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
|
||||
|
||||
import { isImporting } from '../utils';
|
||||
import { isFailed, isImporting } from '../utils';
|
||||
import { DEFAULT_ERROR } from '../utils/error_messages';
|
||||
|
||||
const DEFAULT_PER_PAGE = 20;
|
||||
|
|
@ -59,7 +59,14 @@ export default {
|
|||
GlTooltip,
|
||||
},
|
||||
|
||||
inject: ['realtimeChangesPath'],
|
||||
inject: {
|
||||
detailsPath: {
|
||||
default: undefined,
|
||||
},
|
||||
realtimeChangesPath: {
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
|
||||
props: {
|
||||
id: {
|
||||
|
|
@ -211,6 +218,28 @@ export default {
|
|||
return !isEmpty(item.stats);
|
||||
},
|
||||
|
||||
showFailuresLinkInStatus(item) {
|
||||
if (isFailed(item.status)) {
|
||||
return true;
|
||||
}
|
||||
// Import has failures but no stats
|
||||
if (item.has_failures && !this.hasStats(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
failuresLinkHref(item) {
|
||||
if (!item.has_failures) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return this.detailsPath
|
||||
.replace(':id', encodeURIComponent(item.bulk_import_id))
|
||||
.replace(':entity_id', encodeURIComponent(item.id));
|
||||
},
|
||||
|
||||
getEntityTooltip(item) {
|
||||
switch (item.entity_type) {
|
||||
case WORKSPACE_PROJECT:
|
||||
|
|
@ -238,7 +267,7 @@ export default {
|
|||
<div>
|
||||
<h1 class="gl-font-size-h1 gl-my-0 gl-py-4 gl-display-flex gl-align-items-center gl-gap-3">
|
||||
<img :src="$options.gitlabLogo" :alt="__('GitLab Logo')" class="gl-w-6 gl-h-6" />
|
||||
<span>{{ s__('BulkImport|Direct transfer history') }}</span>
|
||||
<span>{{ s__('BulkImport|Migration history') }}</span>
|
||||
</h1>
|
||||
|
||||
<gl-loading-icon v-if="loading" size="lg" class="gl-mt-5" />
|
||||
|
|
@ -272,13 +301,13 @@ export default {
|
|||
<template #cell(status)="{ value, item }">
|
||||
<div>
|
||||
<import-status
|
||||
:id="item.bulk_import_id"
|
||||
:entity-id="item.id"
|
||||
:has-failures="item.has_failures"
|
||||
:failures-href="showFailuresLinkInStatus(item) ? failuresLinkHref(item) : null"
|
||||
:status="value"
|
||||
/>
|
||||
<import-stats
|
||||
v-if="hasStats(item)"
|
||||
:failures-href="failuresLinkHref(item)"
|
||||
:stats="item.stats"
|
||||
:stats-mapping="$options.BULK_IMPORT_STATIC_ITEMS"
|
||||
:status="value"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { STATUSES } from '~/import_entities/constants';
|
||||
|
||||
export function isFailed(status) {
|
||||
return status === STATUSES.FAILED;
|
||||
}
|
||||
|
||||
export function isImporting(status) {
|
||||
return [STATUSES.SCHEDULING, STATUSES.SCHEDULED, STATUSES.CREATED, STATUSES.STARTED].includes(
|
||||
status,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
mutation removeBlobs($projectPath: ID!, $blobOids: [String!]!) {
|
||||
projectBlobsRemove(input: { projectPath: $projectPath, blobOids: $blobOids }) {
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,20 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import RemoveBlobs from '~/projects/settings/repository/maintenance/remove_blobs.vue';
|
||||
|
||||
export default function mountRepositoryMaintenance() {
|
||||
const removeBlobsEl = document.querySelector('.js-maintenance-remove-blobs');
|
||||
if (!removeBlobsEl) return false;
|
||||
|
||||
const { projectPath, housekeepingPath } = removeBlobsEl.dataset;
|
||||
|
||||
return new Vue({
|
||||
el: removeBlobsEl,
|
||||
apolloProvider: new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
}),
|
||||
provide: { projectPath, housekeepingPath },
|
||||
render(createElement) {
|
||||
return createElement(RemoveBlobs);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
<script>
|
||||
import { GlButton, GlDrawer, GlLink, GlFormTextarea, GlModal } from '@gitlab/ui';
|
||||
import { GlButton, GlDrawer, GlLink, GlFormTextarea, GlModal, GlFormInput } from '@gitlab/ui';
|
||||
import { visitUrl } from '~/lib/utils/url_utility';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
|
||||
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
|
||||
import { s__ } from '~/locale';
|
||||
import { createAlert, VARIANT_WARNING } from '~/alert';
|
||||
import removeBlobsMutation from './graphql/mutations/remove_blobs.mutation.graphql';
|
||||
|
||||
export const BLOB_OID_LENGTH = 40;
|
||||
|
||||
const i18n = {
|
||||
removeBlobs: s__('ProjectMaintenance|Remove blobs'),
|
||||
|
|
@ -18,22 +23,52 @@ const i18n = {
|
|||
modalContent: s__(
|
||||
'ProjectMaintenance|Removing blobs by ID cannot be undone. Are you sure you want to continue?',
|
||||
),
|
||||
modalConfirm: s__('ProjectMaintenance|Enter the following to confirm:'),
|
||||
removeBlobsError: s__('ProjectMaintenance|Something went wrong while removing blobs.'),
|
||||
successAlertTitle: s__('ProjectMaintenance|Blobs removed'),
|
||||
successAlertContent: s__(
|
||||
'ProjectMaintenance|Run housekeeping to remove old versions from repository.',
|
||||
),
|
||||
successAlertButtonText: s__('ProjectMaintenance|Go to housekeeping'),
|
||||
};
|
||||
|
||||
export default {
|
||||
i18n,
|
||||
DRAWER_Z_INDEX,
|
||||
removeBlobsHelpLink: helpPagePath('/user/project/repository/reducing_the_repo_size_using_git'),
|
||||
removeBlobsHelpLink: helpPagePath('/user/project/repository/reducing_the_repo_size_using_git', {
|
||||
anchor: 'repository-cleanup',
|
||||
}),
|
||||
modalCancel: { text: i18n.modalCancelText },
|
||||
modalPrimary: { text: i18n.modalPrimaryText, attributes: { variant: 'danger' } },
|
||||
components: { GlButton, GlDrawer, GlLink, GlFormTextarea, GlModal },
|
||||
components: { GlButton, GlDrawer, GlLink, GlFormTextarea, GlModal, GlFormInput },
|
||||
inject: { projectPath: { default: '' }, housekeepingPath: { default: '' } },
|
||||
data() {
|
||||
return { isDrawerOpen: false, blobIDs: null, showConfirmationModal: false };
|
||||
return {
|
||||
isDrawerOpen: false,
|
||||
blobIDs: null,
|
||||
showConfirmationModal: false,
|
||||
confirmInput: null,
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getDrawerHeaderHeight() {
|
||||
return getContentWrapperHeight();
|
||||
},
|
||||
blobOids() {
|
||||
return this.blobIDs?.split('\n') || [];
|
||||
},
|
||||
isValid() {
|
||||
return this.blobOids.length && this.blobOids.every((s) => s.length >= BLOB_OID_LENGTH);
|
||||
},
|
||||
modalPrimary() {
|
||||
return {
|
||||
text: i18n.modalPrimaryText,
|
||||
attributes: { variant: 'danger', disabled: !this.isConfirmEnabled },
|
||||
};
|
||||
},
|
||||
isConfirmEnabled() {
|
||||
return this.confirmInput === this.projectPath;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openDrawer() {
|
||||
|
|
@ -47,8 +82,47 @@ export default {
|
|||
this.showConfirmationModal = true;
|
||||
},
|
||||
removeBlobsConfirm() {
|
||||
// TODO (follow-up MR): submit mutation + show alert/toast...
|
||||
this.closeDrawer();
|
||||
this.isLoading = true;
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: removeBlobsMutation,
|
||||
variables: {
|
||||
blobOids: this.blobOids,
|
||||
projectPath: this.projectPath,
|
||||
},
|
||||
})
|
||||
.then(({ data: { projectBlobsRemove: { errors } = {} } = {} }) => {
|
||||
this.isLoading = false;
|
||||
|
||||
if (errors?.length) {
|
||||
this.handleError();
|
||||
return;
|
||||
}
|
||||
|
||||
this.closeDrawer();
|
||||
this.generateSuccessAlert();
|
||||
})
|
||||
.catch(() => {
|
||||
this.isLoading = false;
|
||||
this.handleError();
|
||||
});
|
||||
},
|
||||
generateSuccessAlert() {
|
||||
createAlert({
|
||||
title: i18n.successAlertTitle,
|
||||
message: i18n.successAlertContent,
|
||||
variant: VARIANT_WARNING,
|
||||
primaryButton: {
|
||||
text: i18n.successAlertButtonText,
|
||||
clickHandler: () => this.navigateToHousekeeping(),
|
||||
},
|
||||
});
|
||||
},
|
||||
navigateToHousekeeping() {
|
||||
visitUrl(this.housekeepingPath);
|
||||
},
|
||||
handleError() {
|
||||
createAlert({ message: i18n.removeBlobsError, captureError: true });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -56,9 +130,14 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<gl-button class="gl-mb-6" data-testid="drawer-trigger" @click="openDrawer">{{
|
||||
$options.i18n.removeBlobs
|
||||
}}</gl-button>
|
||||
<gl-button
|
||||
class="gl-mb-6"
|
||||
category="secondary"
|
||||
variant="danger"
|
||||
data-testid="drawer-trigger"
|
||||
@click="openDrawer"
|
||||
>{{ $options.i18n.removeBlobs }}</gl-button
|
||||
>
|
||||
|
||||
<gl-drawer
|
||||
:header-height="getDrawerHeaderHeight"
|
||||
|
|
@ -82,6 +161,7 @@ export default {
|
|||
id="blobs"
|
||||
v-model.trim="blobIDs"
|
||||
class="!gl-font-monospace gl-mb-3"
|
||||
:disabled="isLoading"
|
||||
autofocus
|
||||
/>
|
||||
|
||||
|
|
@ -90,7 +170,8 @@ export default {
|
|||
<gl-button
|
||||
data-testid="remove-blobs"
|
||||
variant="danger"
|
||||
:disabled="!blobIDs"
|
||||
:disabled="!isValid"
|
||||
:loading="isLoading"
|
||||
@click="removeBlobs"
|
||||
>{{ $options.i18n.removeBlobs }}</gl-button
|
||||
>
|
||||
|
|
@ -102,10 +183,15 @@ export default {
|
|||
:title="$options.i18n.removeBlobs"
|
||||
modal-id="remove-blobs-confirmation-modal"
|
||||
:action-cancel="$options.modalCancel"
|
||||
:action-primary="$options.modalPrimary"
|
||||
:action-primary="modalPrimary"
|
||||
@primary="removeBlobsConfirm"
|
||||
>
|
||||
{{ $options.i18n.modalContent }}
|
||||
<p>{{ $options.i18n.modalContent }}</p>
|
||||
|
||||
<p class="gl-mb-0">{{ $options.i18n.modalConfirm }}</p>
|
||||
<code>{{ projectPath }}</code>
|
||||
|
||||
<gl-form-input v-model="confirmInput" class="gl-mt-2 gl-max-w-34" />
|
||||
</gl-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -463,6 +463,13 @@ export default {
|
|||
</section>
|
||||
<section :class="workItemBodyClass">
|
||||
<work-item-loading v-if="workItemLoading" />
|
||||
<gl-empty-state
|
||||
v-if="error"
|
||||
:title="$options.i18n.fetchErrorTitle"
|
||||
:description="error"
|
||||
:svg-path="noAccessSvgPath"
|
||||
:svg-height="null"
|
||||
/>
|
||||
<template v-else>
|
||||
<div class="gl-sm-display-none! gl-display-flex">
|
||||
<gl-button
|
||||
|
|
@ -644,13 +651,6 @@ export default {
|
|||
@has-notes="updateHasNotes"
|
||||
@openReportAbuse="openReportAbuseDrawer"
|
||||
/>
|
||||
<gl-empty-state
|
||||
v-if="error"
|
||||
:title="$options.i18n.fetchErrorTitle"
|
||||
:description="error"
|
||||
:svg-path="noAccessSvgPath"
|
||||
:svg-height="null"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -52,23 +52,14 @@ module Organizations
|
|||
|
||||
def organization_groups_new_app_data(organization)
|
||||
{
|
||||
base_path: root_url,
|
||||
groups_and_projects_organization_path:
|
||||
groups_and_projects_organization_path(organization, { display: 'groups' }),
|
||||
groups_organization_path: groups_organization_path(organization),
|
||||
mattermost_enabled: Gitlab.config.mattermost.enabled,
|
||||
available_visibility_levels: available_visibility_levels(Group),
|
||||
restricted_visibility_levels: restricted_visibility_levels,
|
||||
default_visibility_level: default_group_visibility,
|
||||
path_maxlength: ::Namespace::URL_MAX_LENGTH,
|
||||
path_pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS
|
||||
}.to_json
|
||||
default_visibility_level: default_group_visibility
|
||||
}.merge(shared_organization_groups_app_data(organization)).to_json
|
||||
end
|
||||
|
||||
def organization_groups_edit_app_data(group)
|
||||
def organization_groups_edit_app_data(organization, group)
|
||||
{
|
||||
group: group.slice(:full_name)
|
||||
}.to_json
|
||||
group: group.slice(:id, :full_name, :name, :visibility_level, :path)
|
||||
}.merge(shared_organization_groups_app_data(organization)).to_json
|
||||
end
|
||||
|
||||
def admin_organizations_index_app_data
|
||||
|
|
@ -85,7 +76,9 @@ module Organizations
|
|||
|
||||
def organization_activity_app_data(organization)
|
||||
{
|
||||
organization_activity_path: activity_organization_path(organization, { format: :json })
|
||||
organization_activity_path: activity_organization_path(organization, { format: :json }),
|
||||
organization_activity_event_types: organization_activity_event_types,
|
||||
organization_activity_all_event: EventFilter::ALL
|
||||
}.to_json
|
||||
end
|
||||
|
||||
|
|
@ -119,6 +112,19 @@ module Organizations
|
|||
}
|
||||
end
|
||||
|
||||
def shared_organization_groups_app_data(organization)
|
||||
{
|
||||
base_path: root_url,
|
||||
groups_and_projects_organization_path:
|
||||
groups_and_projects_organization_path(organization, { display: 'groups' }),
|
||||
groups_organization_path: groups_organization_path(organization),
|
||||
available_visibility_levels: available_visibility_levels(Group),
|
||||
restricted_visibility_levels: restricted_visibility_levels,
|
||||
path_maxlength: ::Namespace::URL_MAX_LENGTH,
|
||||
path_pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS
|
||||
}
|
||||
end
|
||||
|
||||
# See UsersHelper#admin_users_paths for inspiration to this method
|
||||
def organizations_users_paths
|
||||
{
|
||||
|
|
@ -133,5 +139,40 @@ module Organizations
|
|||
def association_counts(organization)
|
||||
Organizations::OrganizationAssociationCounter.new(organization: organization, current_user: current_user).execute
|
||||
end
|
||||
|
||||
def organization_activity_event_types
|
||||
[
|
||||
{
|
||||
title: _('Comments'),
|
||||
value: EventFilter::COMMENTS
|
||||
},
|
||||
{
|
||||
title: _('Designs'),
|
||||
value: EventFilter::DESIGNS
|
||||
},
|
||||
{
|
||||
title: _('Issue events'),
|
||||
value: EventFilter::ISSUE
|
||||
},
|
||||
{
|
||||
title: _('Merge events'),
|
||||
value: EventFilter::MERGED
|
||||
},
|
||||
{
|
||||
title: _('Push events'),
|
||||
value: EventFilter::PUSH
|
||||
},
|
||||
{
|
||||
title: _('Team'),
|
||||
value: EventFilter::TEAM
|
||||
},
|
||||
{
|
||||
title: _('Wiki'),
|
||||
value: EventFilter::WIKI
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Organizations::OrganizationHelper.prepend_mod_with('Organizations::OrganizationHelper')
|
||||
|
|
|
|||
|
|
@ -53,6 +53,24 @@ module VisibilityLevelHelper
|
|||
!form_model.visibility_level_allowed?(level)
|
||||
end
|
||||
|
||||
def disallowed_visibility_level_by_parent?(form_model, level)
|
||||
return false unless form_model.respond_to?(:visibility_level_allowed_by_parent?)
|
||||
|
||||
!form_model.visibility_level_allowed_by_parent?(level)
|
||||
end
|
||||
|
||||
def disallowed_visibility_level_by_projects?(form_model, level)
|
||||
return false unless form_model.respond_to?(:visibility_level_allowed_by_projects?)
|
||||
|
||||
!form_model.visibility_level_allowed_by_projects?(level)
|
||||
end
|
||||
|
||||
def disallowed_visibility_level_by_sub_groups?(form_model, level)
|
||||
return false unless form_model.respond_to?(:visibility_level_allowed_by_sub_groups?)
|
||||
|
||||
!form_model.visibility_level_allowed_by_sub_groups?(level)
|
||||
end
|
||||
|
||||
# Visibility level can be restricted in two ways:
|
||||
#
|
||||
# 1. The group permissions (e.g. a subgroup is private, which requires
|
||||
|
|
@ -69,6 +87,10 @@ module VisibilityLevelHelper
|
|||
[requested_level, max_allowed_visibility_level(form_model)].min
|
||||
end
|
||||
|
||||
def all_visibility_levels
|
||||
Gitlab::VisibilityLevel.values
|
||||
end
|
||||
|
||||
def available_visibility_levels(form_model)
|
||||
Gitlab::VisibilityLevel.values.reject do |level|
|
||||
disallowed_visibility_level?(form_model, level) ||
|
||||
|
|
@ -76,6 +98,15 @@ module VisibilityLevelHelper
|
|||
end
|
||||
end
|
||||
|
||||
def disabled_visibility_level?(form_model, level)
|
||||
disallowed_visibility_level?(form_model, level) ||
|
||||
restricted_visibility_level?(level)
|
||||
end
|
||||
|
||||
def restricted_visibility_level?(level)
|
||||
restricted_visibility_levels.include?(level)
|
||||
end
|
||||
|
||||
def snippets_selected_visibility_level(visibility_levels, selected)
|
||||
visibility_levels.find { |level| level == selected } || visibility_levels.min
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ module Members
|
|||
validates :new_access_level, presence: true
|
||||
validates :user, presence: true
|
||||
validates :member_namespace, presence: true
|
||||
validates :metadata, json_schema: { filename: "members_approval_request_metadata" }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class NamespaceSetting < ApplicationRecord
|
|||
cascading_attr :toggle_security_policy_custom_ci
|
||||
cascading_attr :math_rendering_limits_enabled
|
||||
|
||||
scope :for_namespaces, ->(namespaces) { where(namespace: namespaces) }
|
||||
|
||||
belongs_to :namespace, inverse_of: :namespace_settings
|
||||
|
||||
enum jobs_to_be_done: { basics: 0, move_repository: 1, code_storage: 2, exploring: 3, ci: 4, other: 5 }, _suffix: true
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ class Project < ApplicationRecord
|
|||
include CrossDatabaseIgnoredTables
|
||||
include UseSqlFunctionForPrimaryKeyLookups
|
||||
include Importable
|
||||
include SafelyChangeColumnDefault
|
||||
|
||||
columns_changing_default :organization_id
|
||||
|
||||
ignore_column :emails_disabled, remove_with: '16.3', remove_after: '2023-08-22'
|
||||
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ class ProjectPolicy < BasePolicy
|
|||
condition(:container_registry_disabled) do
|
||||
if user.is_a?(DeployToken)
|
||||
(!user.read_registry? && !user.write_registry?) ||
|
||||
user.revoked? ||
|
||||
!project.container_registry_enabled?
|
||||
user.revoked? ||
|
||||
!project.container_registry_enabled?
|
||||
else
|
||||
!access_allowed_to?(:container_registry)
|
||||
end
|
||||
|
|
@ -1103,7 +1103,7 @@ class ProjectPolicy < BasePolicy
|
|||
false
|
||||
when ProjectFeature::PRIVATE
|
||||
can?(:read_all_resources) ||
|
||||
can?(:read_all_organization_resources) ||
|
||||
can?(:read_all_organization_resources) ||
|
||||
team_access_level >= ProjectFeature.required_minimum_access_level(feature)
|
||||
else
|
||||
true
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module DeployKeys
|
|||
expose :deploy_keys_projects, using: DeployKeysProjectEntity do |deploy_key|
|
||||
deploy_key.deploy_keys_projects.select do |deploy_key_project|
|
||||
!deploy_key_project.project&.pending_delete? &&
|
||||
(allowed_to_read_project?(deploy_key_project.project) || options[:user].can_admin_all_resources?)
|
||||
(allowed_to_read_project?(deploy_key_project.project) || options[:user].can_admin_all_resources?)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ module Ci
|
|||
def can_create_downstream_pipeline?(target_ref)
|
||||
can?(current_user, :update_pipeline, project) &&
|
||||
can?(current_user, :create_pipeline, downstream_project) &&
|
||||
can_update_branch?(target_ref)
|
||||
can_update_branch?(target_ref)
|
||||
end
|
||||
|
||||
def can_update_branch?(target_ref)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ module Git
|
|||
strong_memoize(:commits_count) do
|
||||
next threshold_commits.count if
|
||||
strong_memoized?(:threshold_commits) &&
|
||||
threshold_commits.count <= PROCESS_COMMIT_LIMIT
|
||||
threshold_commits.count <= PROCESS_COMMIT_LIMIT
|
||||
|
||||
if creating_default_branch?
|
||||
project.repository.commit_count_for_ref(ref)
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ module Groups
|
|||
|
||||
def transfer_to_subgroup?
|
||||
@new_parent_group && \
|
||||
@group.self_and_descendants.pluck_primary_key.include?(@new_parent_group.id)
|
||||
@group.self_and_descendants.pluck_primary_key.include?(@new_parent_group.id)
|
||||
end
|
||||
|
||||
def valid_policies?
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ module Issues
|
|||
target_project = params.delete(:target_project)
|
||||
|
||||
return unless target_project &&
|
||||
issue.can_move?(current_user, target_project) &&
|
||||
target_project != issue.project
|
||||
issue.can_move?(current_user, target_project) &&
|
||||
target_project != issue.project
|
||||
|
||||
update(issue)
|
||||
Issues::MoveService.new(container: project, current_user: current_user).execute(issue, target_project)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Labels
|
|||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def execute(label)
|
||||
return unless project.group &&
|
||||
label.is_a?(ProjectLabel)
|
||||
label.is_a?(ProjectLabel)
|
||||
|
||||
ProjectLabel.transaction do
|
||||
# use the existing group label if it exists
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module Labels
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
link_ids = group_labels_applied_to_issues.pluck("label_links.id") +
|
||||
group_labels_applied_to_merge_requests.pluck("label_links.id")
|
||||
group_labels_applied_to_merge_requests.pluck("label_links.id")
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
|
||||
Label.transaction do
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ module Members
|
|||
raise Gitlab::Access::AccessDeniedError unless can_approve_access_requester?(access_requester)
|
||||
|
||||
if approving_member_with_owner_access_level?(access_requester) &&
|
||||
cannot_assign_owner_responsibilities_to_member_in_project?(access_requester)
|
||||
cannot_assign_owner_responsibilities_to_member_in_project?(access_requester)
|
||||
raise Gitlab::Access::AccessDeniedError
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"expires_at": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{
|
||||
"format": "date"
|
||||
},
|
||||
{
|
||||
"pattern": "^$"
|
||||
}
|
||||
]
|
||||
},
|
||||
"member_role_id": {
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
.settings-content
|
||||
= render 'account_and_limit'
|
||||
|
||||
= render_if_exists 'admin/application_settings/ai_powered'
|
||||
|
||||
%section.settings.as-import-export.no-animate#js-import-export-settings{ class: ('expanded' if expanded_by_default?), data: { testid: 'admin-import-export-settings' } }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
|
|
@ -120,6 +122,5 @@
|
|||
= render_if_exists 'admin/application_settings/add_license'
|
||||
= render 'admin/application_settings/jira_connect'
|
||||
= render 'admin/application_settings/slack'
|
||||
= render_if_exists 'admin/application_settings/ai_powered'
|
||||
= render 'admin/application_settings/security_txt', expanded: expanded_by_default?
|
||||
= render_if_exists 'admin/application_settings/analytics'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
- add_to_breadcrumbs _('New group'), new_group_path
|
||||
- add_to_breadcrumbs _('Import group'), new_group_path(anchor: 'import-group-pane')
|
||||
- add_to_breadcrumbs s_('BulkImport|Direct transfer history'), history_import_bulk_imports_path
|
||||
- add_to_breadcrumbs s_('BulkImport|Migration history'), history_import_bulk_imports_path
|
||||
- add_to_breadcrumbs @bulk_import.id, history_import_bulk_import_path(@bulk_import.id)
|
||||
- page_title format(s_('Import|Failures for %{id}'), id: @bulk_import_entity.full_path_with_fallback)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
- add_to_breadcrumbs _('New group'), new_group_path
|
||||
- add_to_breadcrumbs _('Import group'), new_group_path(anchor: 'import-group-pane')
|
||||
- if params[:id].present?
|
||||
- add_to_breadcrumbs s_('BulkImport|Direct transfer history'), history_import_bulk_imports_path
|
||||
- breadcrumb_title params[:id]
|
||||
- page_title s_('BulkImport|Direct transfer history')
|
||||
- if @bulk_import.present?
|
||||
- add_to_breadcrumbs s_('BulkImport|Migration history'), history_import_bulk_imports_path
|
||||
- breadcrumb_title @bulk_import.id
|
||||
- page_title s_('BulkImport|Migration history')
|
||||
|
||||
- add_page_specific_style 'page_bundles/import'
|
||||
|
||||
#import-history-mount-element{ data: { id: params[:id], details_path: failures_import_bulk_import_path(':id', ':entity_id'), realtime_changes_path: realtime_changes_import_bulk_imports_path(format: :json) } }
|
||||
#import-history-mount-element{ data: { id: @bulk_import&.id, details_path: failures_import_bulk_import_path(':id', ':entity_id'), realtime_changes_path: realtime_changes_import_bulk_imports_path(format: :json) } }
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
- add_to_breadcrumbs _('Groups and projects'), groups_and_projects_organization_path(@organization, { display: 'groups' })
|
||||
- add_to_breadcrumbs @group.name, group_path(@group)
|
||||
|
||||
#js-organizations-groups-edit{ data: { app_data: organization_groups_edit_app_data(@group) } }
|
||||
#js-organizations-groups-edit{ data: { app_data: organization_groups_edit_app_data(@organization, @group) } }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
%h5.gl-heading-4= s_('ProjectMaintenance|Remove blobs')
|
||||
%p.gl-text-secondary
|
||||
= s_('ProjectMaintenance|Provide a list of blob object IDs to be removed.')
|
||||
= link_to s_('ProjectMaintenance|How do I get a list of object IDs?'), help_page_path('user/project/repository/reducing_the_repo_size_using_git')
|
||||
= link_to s_('ProjectMaintenance|How do I get a list of object IDs?'), help_page_path('user/project/repository/reducing_the_repo_size_using_git', anchor: 'repository-cleanup')
|
||||
%p.gl-text-secondary
|
||||
= s_('ProjectMaintenance|Housekeeping will need to be triggered manually afterwards to remove old versions of the file.')
|
||||
|
||||
.js-maintenance-remove-blobs
|
||||
.js-maintenance-remove-blobs{ data: { project_path: @project.full_path, housekeeping_path: edit_project_path(@project, anchor: 'js-project-advanced-settings') } }
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
%p.gl-text-secondary.gl-pb-3
|
||||
= s_('ProjectMaintenance|Manage repository storage and cleanup.')
|
||||
.settings-content
|
||||
= render Pajamas::AlertComponent.new(variant: :default, alert_options: { class: 'gl-mb-5' }, dismissible: false) do |c|
|
||||
= render Pajamas::AlertComponent.new(variant: :danger, alert_options: { class: 'gl-mb-5' }, dismissible: false) do |c|
|
||||
- c.with_body do
|
||||
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
|
||||
- docs_link_start = link_start % { url: help_page_path('user/project/settings/import_export') }
|
||||
- link_end = '</a>'.html_safe
|
||||
= s_('ProjectMaintenance| To ensure that a full backup is available in case changes need to be restored, you should make an %{docs_link_start}export of the project%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end }
|
||||
= s_('ProjectMaintenance|To ensure that a full backup is available in case changes need to be restored, you should make an %{docs_link_start}export of the project%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end }
|
||||
|
||||
- if current_user.can?(:owner_access, @project) && Feature.enabled?(:rewrite_history_ui, @project)
|
||||
= render "projects/maintenance/remove_blobs"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
- available_visibility_levels = available_visibility_levels(form_model)
|
||||
- selected_level = snippets_selected_visibility_level(available_visibility_levels, selected_level)
|
||||
- all_visibility_levels.each do |level|
|
||||
- disabled_visibility_level_icon_with_popover = capture do
|
||||
- if disabled_visibility_level?(form_model, level)
|
||||
- popover_content = capture do
|
||||
- if restricted_visibility_level?(level)
|
||||
= s_('VisibilityLevel|This visibility level has been restricted by your administrator.')
|
||||
- elsif disallowed_visibility_level_by_parent?(form_model, level)
|
||||
= s_('VisibilityLevel|This visibility level is not allowed because the parent group has a more restrictive visibility level.')
|
||||
- elsif disallowed_visibility_level_by_projects?(form_model, level) || disallowed_visibility_level_by_sub_groups?(form_model, level)
|
||||
- learn_more_link_start = '<a href="https://docs.gitlab.com/ee/user/public_access" target="_blank" rel="noopener noreferrer">'.html_safe # rubocop:disable Gitlab/DocUrl -- Not referencing this rails application; it is referencing another doc
|
||||
- learn_more_link_end = '</a>'.html_safe
|
||||
= s_('VisibilityLevel|This visibility level is not allowed because a child of %{group_name} has a less restrictive visibility level. %{learn_more_link_start}Learn more%{learn_more_link_end}.').html_safe % { group_name: form_model.name, learn_more_link_start: learn_more_link_start, learn_more_link_end: learn_more_link_end }
|
||||
|
||||
- available_visibility_levels.each do |level|
|
||||
%span{
|
||||
data: {
|
||||
testid: 'visibility-level-not-allowed-popover',
|
||||
container: 'body',
|
||||
content: popover_content,
|
||||
html: 'true',
|
||||
title: _('Visibility level not allowed'),
|
||||
toggle: 'popover',
|
||||
triggers: 'hover' }
|
||||
}
|
||||
= sprite_icon('lock')
|
||||
|
||||
= form.gitlab_ui_radio_component model_method, level,
|
||||
"#{visibility_level_icon(level)} #{visibility_level_label(level)}".html_safe,
|
||||
help_text: '<span class="option-description">%{visibility_level_description}</span><span class="option-disabled-reason"></span>'.html_safe % { visibility_level_description: visibility_level_description(level, form_model)},
|
||||
radio_options: { checked: (selected_level == level), data: { track_label: "blank_project", track_action: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "" } },
|
||||
"#{visibility_level_icon(level)} #{visibility_level_label(level)} #{disabled_visibility_level_icon_with_popover}".html_safe,
|
||||
help_text: '<span class="option-description text-muted">%{visibility_level_description}</span><span class="option-disabled-reason">%{option_disabled_reason}</span>'.html_safe % { visibility_level_description: visibility_level_description(level, form_model), option_disabled_reason: 'Not allowed by administrators' },
|
||||
radio_options: { checked: (selected_level == level), disabled: disabled_visibility_level?(form_model, level), data: { track_label: "blank_project", track_action: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "" } },
|
||||
label_options: { class: 'js-visibility-level-radio' }
|
||||
|
||||
|
||||
.text-muted
|
||||
- if all_visibility_levels_restricted?
|
||||
= _('Visibility settings have been disabled by the administrator.')
|
||||
- elsif multiple_visibility_levels_restricted?
|
||||
= _('Other visibility settings have been disabled by the administrator.')
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: product_analytics_dashboards
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115177
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/398653
|
||||
milestone: '15.11'
|
||||
type: development
|
||||
group: group::product analytics
|
||||
default_enabled: true
|
||||
|
|
@ -517,6 +517,8 @@
|
|||
- 1
|
||||
- - ml_experiment_tracking_associate_ml_candidate_to_package
|
||||
- 1
|
||||
- - namespaces_cascade_duo_features_enabled
|
||||
- 1
|
||||
- - namespaces_free_user_cap_group_over_limit_notification
|
||||
- 1
|
||||
- - namespaces_process_sync_events
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ feature_categories:
|
|||
description: Contains periodically snapshotted database record counts.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62797
|
||||
milestone: '14.0'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
exempt_from_sharding: true # Cell local table storing instance level-aggregations
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
migration_job_name: BackfillBoardsEpicUserPreferencesGroupId
|
||||
description: Backfills sharding key `boards_epic_user_preferences.group_id` from `epics`.
|
||||
feature_category: portfolio_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153684
|
||||
milestone: '17.1'
|
||||
queued_migration_version: 20240521094917
|
||||
finalize_after: '2024-06-22'
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -19,3 +19,4 @@ desired_sharding_key:
|
|||
table: epics
|
||||
sharding_key: group_id
|
||||
belongs_to: epic
|
||||
desired_sharding_key_migration_job_name: BackfillBoardsEpicUserPreferencesGroupId
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ feature_categories:
|
|||
description: Contains data for calculating DevOps score.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/26dde5f55f1dac2e6bea4f7e1dfa51c72dc756cb
|
||||
milestone: '9.3'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
exempt_from_sharding: true # Cell local table storing instance DevOps metrics calculated from service ping
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IncreaseQuantityForGitlabcomDuoProTrials < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
milestone '17.1'
|
||||
|
||||
class AddOn < MigrationRecord
|
||||
self.table_name = :subscription_add_ons
|
||||
|
||||
enum name: {
|
||||
code_suggestions: 1
|
||||
}
|
||||
end
|
||||
|
||||
def up
|
||||
return unless Gitlab.com?
|
||||
|
||||
AddOn.reset_column_information
|
||||
|
||||
duo_pro_addon_id = AddOn.find_by(name: "code_suggestions")&.id
|
||||
return unless duo_pro_addon_id
|
||||
|
||||
today = Date.current
|
||||
|
||||
update_column_in_batches(:subscription_add_on_purchases, :quantity, 100) do |table, query|
|
||||
query.where(table[:subscription_add_on_id].eq(duo_pro_addon_id))
|
||||
.where(table[:trial].eq(true))
|
||||
.where(table[:expires_on].gteq(today))
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddEarlyAccessProgramParticipantToNamespaceSettings < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
|
||||
def change
|
||||
add_column :namespace_settings, :early_access_program_participant, :boolean, null: false, default: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddMetadataToMemberApprovals < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
enable_lock_retries!
|
||||
|
||||
def change
|
||||
add_column :member_approvals, :metadata, :jsonb, default: {}, null: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddGroupIdToBoardsEpicUserPreferences < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
|
||||
def change
|
||||
add_column :boards_epic_user_preferences, :group_id, :bigint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IndexBoardsEpicUserPreferencesOnGroupId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_boards_epic_user_preferences_on_group_id'
|
||||
|
||||
def up
|
||||
add_concurrent_index :boards_epic_user_preferences, :group_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :boards_epic_user_preferences, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddBoardsEpicUserPreferencesGroupIdFk < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :boards_epic_user_preferences, :namespaces, column: :group_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :boards_epic_user_preferences, column: :group_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddBoardsEpicUserPreferencesGroupIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :boards_epic_user_preferences,
|
||||
sharding_key: :group_id,
|
||||
parent_table: :epics,
|
||||
parent_sharding_key: :group_id,
|
||||
foreign_key: :epic_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :boards_epic_user_preferences,
|
||||
sharding_key: :group_id,
|
||||
parent_table: :epics,
|
||||
parent_sharding_key: :group_id,
|
||||
foreign_key: :epic_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillBoardsEpicUserPreferencesGroupId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
MIGRATION = "BackfillBoardsEpicUserPreferencesGroupId"
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 1000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:boards_epic_user_preferences,
|
||||
:id,
|
||||
:group_id,
|
||||
:epics,
|
||||
:group_id,
|
||||
:epic_id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(
|
||||
MIGRATION,
|
||||
:boards_epic_user_preferences,
|
||||
:id,
|
||||
[
|
||||
:group_id,
|
||||
:epics,
|
||||
:group_id,
|
||||
:epic_id
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ChangeProjectsOrganizationIdDefault < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
|
||||
enable_lock_retries!
|
||||
|
||||
def up
|
||||
change_column_default(:projects, :organization_id, nil)
|
||||
end
|
||||
|
||||
def down
|
||||
change_column_default(:projects, :organization_id, 1)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
79e99af8399b46b5804cdffd949583e6ffb312ee55edf94f2b0e2bb92afe8085
|
||||
|
|
@ -0,0 +1 @@
|
|||
209ef8ffed9a59acdd813b3feaa259231ec812733e58341dedd0a8b941d8a658
|
||||
|
|
@ -0,0 +1 @@
|
|||
cd61987ea28b86a0c4280c8e0c743ecef2e1c6a45842281b4c7814ebe6e87057
|
||||
|
|
@ -0,0 +1 @@
|
|||
46c5066752efaa024617a45dd76455f7ae478965067d12dc0022e8c29b90f596
|
||||
|
|
@ -0,0 +1 @@
|
|||
5a3f2851042d532a5b792a862cc8d6d8b359c02e26b73bbd0d17e0a1936df7f0
|
||||
|
|
@ -0,0 +1 @@
|
|||
3b31f18988a16c8d61eac4f669b8ae222a01b1e0f49716056737d735e3b81490
|
||||
|
|
@ -0,0 +1 @@
|
|||
beef1073839bd762120d6340f2f04de3836536d213abf5a07a21db1992498234
|
||||
|
|
@ -0,0 +1 @@
|
|||
dfac2d41003a3a1971656c47a2e32fac23692b2cfcc371b28bb5246a04dff2ab
|
||||
|
|
@ -0,0 +1 @@
|
|||
e9e8c4e5fe7108a7e82866d7a38330262af3090fabbb380a6d8aab3e5d03d5fe
|
||||
|
|
@ -243,7 +243,7 @@ CREATE TABLE projects (
|
|||
suggestion_commit_message character varying(255),
|
||||
project_namespace_id bigint,
|
||||
hidden boolean DEFAULT false NOT NULL,
|
||||
organization_id bigint DEFAULT 1
|
||||
organization_id bigint
|
||||
);
|
||||
|
||||
CREATE FUNCTION find_projects_by_id(projects_id bigint) RETURNS projects
|
||||
|
|
@ -865,6 +865,22 @@ RETURN NEW;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_8a38ce2327de() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."group_id" IS NULL THEN
|
||||
SELECT "group_id"
|
||||
INTO NEW."group_id"
|
||||
FROM "epics"
|
||||
WHERE "epics"."id" = NEW."epic_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_8ac78f164b2d() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -5928,7 +5944,8 @@ CREATE TABLE boards_epic_user_preferences (
|
|||
board_id bigint NOT NULL,
|
||||
user_id bigint NOT NULL,
|
||||
epic_id bigint NOT NULL,
|
||||
collapsed boolean DEFAULT false NOT NULL
|
||||
collapsed boolean DEFAULT false NOT NULL,
|
||||
group_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE boards_epic_user_preferences_id_seq
|
||||
|
|
@ -11247,7 +11264,8 @@ CREATE TABLE member_approvals (
|
|||
old_access_level integer,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
user_id bigint NOT NULL,
|
||||
member_role_id bigint
|
||||
member_role_id bigint,
|
||||
metadata jsonb DEFAULT '{}'::jsonb NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE member_approvals_id_seq
|
||||
|
|
@ -12280,6 +12298,7 @@ CREATE TABLE namespace_settings (
|
|||
lock_duo_features_enabled boolean DEFAULT false NOT NULL,
|
||||
disable_personal_access_tokens boolean DEFAULT false NOT NULL,
|
||||
enable_auto_assign_gitlab_duo_pro_seats boolean DEFAULT false NOT NULL,
|
||||
early_access_program_participant boolean DEFAULT false NOT NULL,
|
||||
remove_dormant_members boolean DEFAULT false NOT NULL,
|
||||
remove_dormant_members_period integer DEFAULT 90 NOT NULL,
|
||||
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255)),
|
||||
|
|
@ -25027,6 +25046,8 @@ CREATE UNIQUE INDEX index_boards_epic_user_preferences_on_board_user_epic_unique
|
|||
|
||||
CREATE INDEX index_boards_epic_user_preferences_on_epic_id ON boards_epic_user_preferences USING btree (epic_id);
|
||||
|
||||
CREATE INDEX index_boards_epic_user_preferences_on_group_id ON boards_epic_user_preferences USING btree (group_id);
|
||||
|
||||
CREATE INDEX index_boards_epic_user_preferences_on_user_id ON boards_epic_user_preferences USING btree (user_id);
|
||||
|
||||
CREATE INDEX index_boards_on_group_id ON boards USING btree (group_id);
|
||||
|
|
@ -30275,6 +30296,8 @@ CREATE TRIGGER trigger_56d49f4ed623 BEFORE INSERT OR UPDATE ON workspace_variabl
|
|||
|
||||
CREATE TRIGGER trigger_7a8b08eed782 BEFORE INSERT OR UPDATE ON boards_epic_board_positions FOR EACH ROW EXECUTE FUNCTION trigger_7a8b08eed782();
|
||||
|
||||
CREATE TRIGGER trigger_8a38ce2327de BEFORE INSERT OR UPDATE ON boards_epic_user_preferences FOR EACH ROW EXECUTE FUNCTION trigger_8a38ce2327de();
|
||||
|
||||
CREATE TRIGGER trigger_8ac78f164b2d BEFORE INSERT OR UPDATE ON design_management_repositories FOR EACH ROW EXECUTE FUNCTION trigger_8ac78f164b2d();
|
||||
|
||||
CREATE TRIGGER trigger_8e66b994e8f0 BEFORE INSERT OR UPDATE ON audit_events_streaming_event_type_filters FOR EACH ROW EXECUTE FUNCTION trigger_8e66b994e8f0();
|
||||
|
|
@ -31346,6 +31369,9 @@ ALTER TABLE ONLY environments
|
|||
ALTER TABLE p_ci_builds
|
||||
ADD CONSTRAINT fk_d3130c9a7f FOREIGN KEY (commit_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY boards_epic_user_preferences
|
||||
ADD CONSTRAINT fk_d32c3d693c FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_sources_pipelines
|
||||
ADD CONSTRAINT fk_d4e29af7d7 FOREIGN KEY (source_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -83,14 +83,21 @@ For example, if the backup directory name is `1714053314_2024_04_25_17.0.0-pre`,
|
|||
}
|
||||
```
|
||||
|
||||
## Limitations
|
||||
## Known issues
|
||||
|
||||
- The tool has only been tested on the [1K architecture](../reference_architectures/1k_users.md)
|
||||
and therefore only recommended to be used on relevant environments.
|
||||
- The initial version doesn't use the [copy strategy](backup_gitlab.md#backup-strategy-option),
|
||||
so as long as there is nothing changing existing files while you perform the backup, you should be fine.
|
||||
|
||||
For that reason, you need to either put the GitLab instance into [Maintenance Mode](../maintenance_mode/index.md),
|
||||
or ensure your instance is not being used by restricting traffic to the servers.
|
||||
When working with `gitlab-backup-cli`, you might encounter the following issues.
|
||||
|
||||
See [issue 428520](https://gitlab.com/gitlab-org/gitlab/-/issues/428520) where an alternative to the copy strategy is discussed.
|
||||
### Architecture compatibility
|
||||
|
||||
If you use the `gitlab-backup-cli` tool on architectures other than the [1K architecture](../reference_architectures/1k_users.md), you might experience issues. This tool is supported only on 1K architecture and is recommended only for relevant environments.
|
||||
|
||||
### Backup strategy
|
||||
|
||||
Changes to existing files during backup might cause issues on the GitLab instance. This issue occurs because the tool's initial version does not use the [copy strategy](backup_gitlab.md#backup-strategy-option).
|
||||
|
||||
A workaround of this issue, is either to:
|
||||
|
||||
- Transition the GitLab instance into [Maintenance Mode](../maintenance_mode/index.md).
|
||||
- Restrict traffic to the servers during backup to preserve instance resources.
|
||||
|
||||
We're investigating an alternative to the copy strategy, see [issue 428520](https://gitlab.com/gitlab-org/gitlab/-/issues/428520).
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ including:
|
|||
- Snippets
|
||||
- [Group wikis](../../user/project/wiki/group.md)
|
||||
- Project-level Secure Files ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121142) in GitLab 16.1)
|
||||
- Merge request diffs (Helm chart installation only)
|
||||
- External merge request diffs (GitLab Helm chart only. [Issue 438777](https://gitlab.com/gitlab-org/gitlab/-/issues/438777) proposes to backup local external MR diffs with the Linux package)
|
||||
|
||||
Backups do not include:
|
||||
|
||||
|
|
|
|||
|
|
@ -1007,7 +1007,7 @@ running [Prometheus](../monitoring/prometheus/index.md):
|
|||
],
|
||||
},
|
||||
{
|
||||
'job_name': 'node',
|
||||
'job_name': 'static-node',
|
||||
'static_configs' => [
|
||||
'targets' => ['1.1.1.1:9100', '1.1.1.2:9100', '1.1.1.3:9100', '1.1.1.4:9100', '1.1.1.5:9100'],
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
stage: AI-Powered
|
||||
group: Custom Models
|
||||
description: Configure your GitLab instance with Switchboard.
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Configure your GitLab Duo features
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed
|
||||
|
||||
To configure your GitLab instance to access the available large language models (LLMs) in your infrastructure:
|
||||
|
||||
1. Configure the self-hosted model.
|
||||
1. Configure the AI-powered features to use specific self-hosted models.
|
||||
|
||||
## Configure the self-hosted model
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator.
|
||||
|
||||
1. On the left sidebar, at the bottom, select **Admin Area**.
|
||||
1. Select **AI-Powered Features**.
|
||||
- If the **AI-Powered Features** menu item is not available, synchronize your subscription after purchase:
|
||||
1. On the left sidebar, select **Subscription**.
|
||||
1. In **Subscription details**, to the right of **Last sync**, select synchronize subscription (**{retry}**).
|
||||
1. Select **Models**.
|
||||
1. Set your model details by selecting **New Self-Hosted Model**. Complete the fields:
|
||||
- **Name the deployment (must be unique):** Enter the model name, for example, Mistral.
|
||||
- **Choose the model from the Model dropdown list:** Only GitLab-approved models are listed here.
|
||||
- **Endpoint:** The self-hosted model endpoint, for example, the server hosting the model.
|
||||
- **API token (if needed):** Optional. Complete if you need an API key to access the model.
|
||||
- Select **Create Self-Hosted Model** to save the model details.
|
||||
|
||||
## Configure the features to use specific models
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator.
|
||||
|
||||
1. On the left sidebar, at the bottom, select **Admin Area**.
|
||||
1. Select **AI-Powered Features**.
|
||||
- If the **AI-Powered Features** menu item is not available, synchronize your subscription after purchase:
|
||||
1. On the left sidebar, select **Subscription**.
|
||||
1. In **Subscription details**, to the right of **Last sync**, select synchronize subscription (**{retry}**).
|
||||
1. Select **Features**.
|
||||
1. Set your feature model by selecting **Edit** for the feature you want to set. For example, **Code Generation**.
|
||||
1. Select the Model Provider for the feature:
|
||||
- Select **Self-Hosted Model** in the list.
|
||||
- Choose the self-hosted model you would like to use, for example, Mistral.
|
||||
- Select **Save Changes** to set the feature to use this specific model.
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
stage: AI-Powered
|
||||
group: Custom Models
|
||||
description: Get started with Self-Hosted AI Models.
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Deploy a self-hosted large language model
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed
|
||||
|
||||
Deploying a self-hosted large language model (LLM) allows customers to:
|
||||
|
||||
- Manage the end-to-end transmission of requests to enterprise-hosted LLM backends for GitLab Duo features.
|
||||
- Keep all of these requests within their enterprise network, ensuring no calls to external architecture.
|
||||
|
||||
Self-hosted models serve sophisticated customers capable of managing their own LLM infrastructure. GitLab provides the option to connect supported models to LLM features. Model-specific prompts and GitLab Duo feature support is provided by the self-hosted models feature. For more information about this offering, see the [subscription page](../../subscriptions/self_managed/index.md).
|
||||
|
||||
## Advantages
|
||||
|
||||
- Choice of GitLab-approved LLM models.
|
||||
- Ability to keep all data and request/response logs within their own domain.
|
||||
- Ability to select specific GitLab Duo Features for their users.
|
||||
- Non-reliance on the GitLab shared AI Gateway.
|
||||
|
||||
## Self Hosted models vs the default GitLab AI Vendor architecture
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant GitLab
|
||||
participant AIGateway as AI Gateway
|
||||
participant SelfHostedModel as Self Hosted Model
|
||||
participant GitLabAIVendor as GitLab AI Vendor
|
||||
|
||||
User ->> GitLab: Send request
|
||||
GitLab ->> GitLab: Check if self-hosted model is configured
|
||||
alt Self-hosted model configured
|
||||
GitLab ->> AIGateway: Create prompt and send request
|
||||
AIGateway ->> SelfHostedModel: Perform API request to AI model
|
||||
SelfHostedModel -->> AIGateway: Respond to the prompt
|
||||
AIGateway -->> GitLab: Forward AI response
|
||||
else
|
||||
GitLab ->> AIGateway: Create prompt and send request
|
||||
AIGateway ->> GitLabAIVendor: Perform API request to AI model
|
||||
GitLabAIVendor -->> AIGateway: Respond to the prompt
|
||||
AIGateway -->> GitLab: Forward AI response
|
||||
end
|
||||
GitLab -->> User: Forward AI response
|
||||
```
|
||||
|
||||
With AI self-hosted models, your GitLab instance, AI Gateway, and self-hosted AI model are fully isolated within your own environment. This setup ensures complete privacy and high security for using AI features, with no reliance on public services.
|
||||
|
||||
## Get started
|
||||
|
||||
To deploy a self-hosted large language model:
|
||||
|
||||
1. [Install your self-hosted model deployment infrastructure](../../administration/self_hosted_models/install_infrastructure.md) and connect it to your GitLab instance.
|
||||
1. [Configure your self-hosted model deployment](../../administration/self_hosted_models/configure_duo_features.md) using instance and group level settings.
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
---
|
||||
stage: AI-Powered
|
||||
group: Custom Models
|
||||
description: Setup your Self-Hosted Model Deployment infrastructure
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Set up your self-hosted model deployment infrastructure
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed
|
||||
|
||||
By self-hosting the model, AI gateway, and GitLab instance, there are no calls to external architecture, ensuring maximum levels of security.
|
||||
|
||||
To set up your self-hosted model deployment infrastructure:
|
||||
|
||||
1. Install the large language model (LLM) serving infrastructure.
|
||||
1. Install the GitLab AI Gateway.
|
||||
|
||||
## Step 1: Install LLM serving infrastructure
|
||||
|
||||
Install one of the following GitLab-approved LLM models:
|
||||
|
||||
- [Mistral-7B-v0.1](https://huggingface.co/mistralai/Mistral-7B-v0.1).
|
||||
- [Mixtral-8x7B-instruct](https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1).
|
||||
- [Mixtral 8x22B](https://huggingface.co/mistral-community/Mixtral-8x22B-v0.1).
|
||||
- [CodeGemma 7B IT](https://huggingface.co/google/codegemma-7b-it).
|
||||
- [CodeGemma 2B](https://huggingface.co/google/codegemma-2b).
|
||||
|
||||
### Recommended serving architectures
|
||||
|
||||
For Mistral, you should use one of the following architectures:
|
||||
|
||||
- [vLLM](https://docs.vllm.ai/en/stable/)
|
||||
- [TensorRT-LLM](https://docs.mistral.ai/deployment/self-deployment/overview/)
|
||||
|
||||
## Step 2: Install the GitLab AI Gateway
|
||||
|
||||
### Install using Docker
|
||||
|
||||
The GitLab AI Gateway Docker image contains all necessary code and dependencies in a single container.
|
||||
|
||||
Find the GitLab official Docker image at:
|
||||
|
||||
- [AI Gateway Docker image on Container Registry](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/container_registry/).
|
||||
- [Release process for self-hosted AI Gateway](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/main/docs/release.md).
|
||||
|
||||
WARNING:
|
||||
Docker for Windows is not officially supported. There are known issues with volume
|
||||
permissions, and potentially other unknown issues. If you are trying to run on Docker
|
||||
for Windows, see the [getting help page](https://about.gitlab.com/get-help/) for links
|
||||
to community resources (such as IRC or forums) to seek help from other users.
|
||||
|
||||
#### Set up the volumes location
|
||||
|
||||
Create a directory where the logs will reside on the Docker host. It can be under your user's home directory (for example
|
||||
`~/gitlab-agw`), or in a directory like `/srv/gitlab-agw`. To create that directory, run:
|
||||
|
||||
```shell
|
||||
sudo mkdir -p /srv/gitlab-agw
|
||||
```
|
||||
|
||||
If you're running Docker with a user other than `root`, ensure appropriate
|
||||
permissions have been granted to that directory.
|
||||
|
||||
#### Find the AI Gateway Release
|
||||
|
||||
In a production environment, you should pin your deployment to a specific
|
||||
GitLab AI Gateway release. Find the release to use in [GitLab AI Gateway Releases](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/releases), for example: `7d5f58e1` where `7d5f58e1` is the AI Gateway released version.
|
||||
|
||||
To pin your deployment to the latest stable release, use the `latest` tag to run the latest stable release:
|
||||
|
||||
```shell
|
||||
docker run -p 5000:500 registry.gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/model-gateway:latest`
|
||||
```
|
||||
|
||||
NOTE:
|
||||
We do not yet support multi-arch image, only `linux/amd64`. If you try to run this on Apple chip, adding `--platform linux/amd64` to the `docker run` command will help.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
To use the GitLab Docker images:
|
||||
|
||||
- You must [install Docker](https://docs.docker.com/engine/install/#server).
|
||||
- You should use a valid hostname accessible within your network. Do not use `localhost`.
|
||||
|
||||
#### Install using Docker Engine
|
||||
|
||||
1. For the AI Gateway to know where the GitLab instance is located so it can access the API, set the environment variable `AIGW_GITLAB_API_URL`.
|
||||
|
||||
For example, run:
|
||||
|
||||
```shell
|
||||
AIGW_GITLAB_API_URL=https://YOUR_GITLAB_DOMAIN/api/v4/
|
||||
```
|
||||
|
||||
1. For the GitLab instance to know where AI Gateway is located so it can access the gateway, set the environment variable `AI_GATEWAY_URL`
|
||||
inside your GitLab instance environment variables.
|
||||
|
||||
For example, run:
|
||||
|
||||
```shell
|
||||
AI_GATEWAY_URL=https://YOUR_AI_GATEWAY_DOMAIN
|
||||
```
|
||||
|
||||
1. After you've set up the environment variables, run the image. For example:
|
||||
|
||||
```shell
|
||||
docker run -p 5000:500 registry.gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/model-gateway:latest
|
||||
```
|
||||
|
||||
This command downloads and starts a AI Gateway container, and
|
||||
[publishes ports](https://docs.docker.com/network/#published-ports) needed to
|
||||
access SSH, HTTP and HTTPS.
|
||||
|
||||
1. Track the initialization process:
|
||||
|
||||
```shell
|
||||
sudo docker logs -f gitlab-aigw
|
||||
```
|
||||
|
||||
After starting the container, visit `gitlab-aigw.example.com`. It might take
|
||||
a while before the Docker container starts to respond to queries.
|
||||
|
||||
#### Upgrade
|
||||
|
||||
To upgrade the AI Gateway, download the newest Docker image tag.
|
||||
|
||||
1. Stop the running container:
|
||||
|
||||
```shell
|
||||
sudo docker stop gitlab-aigw
|
||||
```
|
||||
|
||||
1. Remove the existing container:
|
||||
|
||||
```shell
|
||||
sudo docker rm gitlab-aigw
|
||||
```
|
||||
|
||||
1. Pull the new image:
|
||||
|
||||
```shell
|
||||
docker run -p 5000:500 registry.gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/model-gateway:latest
|
||||
```
|
||||
|
||||
1. Ensure that the environment variables are all set correctly
|
||||
|
||||
### Alternative installation methods
|
||||
|
||||
For information on alternative ways to install the AI Gateway, see [issue 463773](https://gitlab.com/gitlab-org/gitlab/-/issues/463773).
|
||||
|
|
@ -39,18 +39,12 @@ To enable the export of
|
|||
|
||||
## Enable migration of groups and projects by direct transfer
|
||||
|
||||
DETAILS:
|
||||
**Status:** Beta
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383268) in GitLab 15.8.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/461326) in GitLab 17.1.
|
||||
|
||||
WARNING:
|
||||
In GitLab 16.1 and earlier, you should **not** use direct transfer with [scheduled scan execution policies](../../user/application_security/policies/scan-execution-policies.md). If using direct transfer, first upgrade to GitLab 16.2 and ensure security policy bots are enabled in the projects you are enforcing.
|
||||
|
||||
WARNING:
|
||||
This feature is in [beta](../../policy/experiment-beta-support.md#beta) and subject to change without notice.
|
||||
This feature is not ready for production use.
|
||||
|
||||
Migration of groups and projects by direct transfer is disabled by default.
|
||||
To enable migration of groups and projects by direct transfer:
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ DETAILS:
|
|||
With the group migration by direct transfer API, you can start and view the progress of migrations initiated with
|
||||
[group migration by direct transfer](../user/group/import/index.md).
|
||||
|
||||
WARNING:
|
||||
Migrating projects with this API is in [beta](../policy/experiment-beta-support.md#beta). This feature is not
|
||||
ready for production use.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
For information on prerequisites for group migration by direct transfer API, see
|
||||
|
|
@ -31,7 +27,7 @@ prerequisites for [migrating groups by direct transfer](../user/group/import/ind
|
|||
Use this endpoint to start a new group or project migration. Specify:
|
||||
|
||||
- `entities[group_entity]` to migrate a group.
|
||||
- `entities[project_entity]` to migrate a project. (**Status:** Beta)
|
||||
- `entities[project_entity]` to migrate a project.
|
||||
|
||||
```plaintext
|
||||
POST /bulk_imports
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ DETAILS:
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/415581) in GitLab 16.2 [with a flag](../administration/feature_flags.md) named `code_suggestions_completion_api`. Disabled by default. This feature is an experiment.
|
||||
> - Requirement to generate a JWT before calling this endpoint was [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127863) in GitLab 16.3.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/416371) in GitLab 16.8. [Feature flag `code_suggestions_completion_api`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138174) removed.
|
||||
> - `context` and `user_instruction` attributes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/462750) in GitLab 17.1 [with a flag](../administration/feature_flags.md) named `code_suggestions_context`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
The availability of the `context` and `user_instruction` attributes is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
These attributes are available for testing, but are not ready for production use.
|
||||
|
||||
```plaintext
|
||||
POST /code_suggestions/completions
|
||||
|
|
@ -31,12 +37,14 @@ Requests to this endpoint are proxied to the
|
|||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|----------------|---------|----------|-------------|
|
||||
| `current_file` | hash | yes | Attributes of file for which code suggestions are being generated. See [File attributes](#file-attributes) for a list of strings this attribute accepts. |
|
||||
| `intent` | string | no | The intent of the completion request. Options: `completion` or `generation`. |
|
||||
| `stream` | boolean | no | Whether to stream the response as smaller chunks as they are ready (if applicable). Default: `false`. |
|
||||
| `project_path` | string | no | The path of the project. |
|
||||
| Attribute | Type | Required | Description |
|
||||
|--------------------|---------|----------|-------------|
|
||||
| `current_file` | hash | yes | Attributes of file for which Code Suggestions are being generated. See [File attributes](#file-attributes) for a list of strings this attribute accepts. |
|
||||
| `intent` | string | no | The intent of the completion request. This can be either `completion` or `generation`. |
|
||||
| `stream` | boolean | no | Whether to stream the response as smaller chunks as they are ready (if applicable). Default: `false`. |
|
||||
| `project_path` | string | no | The path of the project. |
|
||||
| `context` | array | no | Additional context to be used for Code Suggestions. See [Context attributes](#context-attributes) for a list of parameters this attribute accepts. |
|
||||
| `user_instruction` | string | no | A user's instructions for Code Suggestions. |
|
||||
|
||||
### File attributes
|
||||
|
||||
|
|
@ -46,6 +54,14 @@ The `current_file` attribute accepts the following strings:
|
|||
- `content_above_cursor` - The content of the file above the current cursor position. Required.
|
||||
- `content_below_cursor` - The content of the file below the current cursor position. Optional.
|
||||
|
||||
### Context attributes
|
||||
|
||||
The `context` attribute accepts a list of elements with the following attributes:
|
||||
|
||||
- `type` - The type of the context element. This can be either `file` or `snippet`.
|
||||
- `name` - The name of the context element. A name of the file or a code snippet.
|
||||
- `content` - The content of the context element. The body of the file or a function.
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -961,6 +961,20 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="queryselfmanagedaddoneligibleusersaddontype"></a>`addOnType` | [`GitlabSubscriptionsAddOnType!`](#gitlabsubscriptionsaddontype) | Type of add on to filter the eligible users by. |
|
||||
| <a id="queryselfmanagedaddoneligibleuserssearch"></a>`search` | [`String`](#string) | Search the user list. |
|
||||
|
||||
### `Query.selfManagedUsersQueuedForRolePromotion`
|
||||
|
||||
Fields related to users within a self-managed instance that are pending role promotion approval.
|
||||
|
||||
DETAILS:
|
||||
**Introduced** in GitLab 17.1.
|
||||
**Status**: Experiment.
|
||||
|
||||
Returns [`UsersQueuedForRolePromotionConnection`](#usersqueuedforrolepromotionconnection).
|
||||
|
||||
This field returns a [connection](#connections). It accepts the
|
||||
four standard [pagination arguments](#pagination-arguments):
|
||||
`before: String`, `after: String`, `first: Int`, and `last: Int`.
|
||||
|
||||
### `Query.snippets`
|
||||
|
||||
Find Snippets visible to the current user.
|
||||
|
|
@ -1134,7 +1148,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="queryvulnerabilitieshasremediations"></a>`hasRemediations` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have remediations. |
|
||||
| <a id="queryvulnerabilitieshasresolution"></a>`hasResolution` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have been resolved on default branch. |
|
||||
| <a id="queryvulnerabilitiesimage"></a>`image` | [`[String!]`](#string) | Filter vulnerabilities by location image. When this filter is present, the response only matches entries for a `reportType` that includes `container_scanning`, `cluster_image_scanning`. |
|
||||
| <a id="queryvulnerabilitiesowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. |
|
||||
| <a id="queryvulnerabilitiesowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. Wildcard value "NONE" also supported when feature flag `owasp_top_10_null_filtering` is enabled. "NONE" wildcard cannot be combined with other OWASP top 10 values. |
|
||||
| <a id="queryvulnerabilitiesprojectid"></a>`projectId` | [`[ID!]`](#id) | Filter vulnerabilities by project. |
|
||||
| <a id="queryvulnerabilitiesreporttype"></a>`reportType` | [`[VulnerabilityReportType!]`](#vulnerabilityreporttype) | Filter vulnerabilities by report type. |
|
||||
| <a id="queryvulnerabilitiesscanner"></a>`scanner` | [`[String!]`](#string) | Filter vulnerabilities by VulnerabilityScanner.externalId. |
|
||||
|
|
@ -9472,7 +9486,7 @@ Input type: `VerifiedNamespaceCreateInput`
|
|||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationverifiednamespacecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationverifiednamespacecreatenamespacepath"></a>`namespacePath` | [`ID!`](#id) | Root namespace path. |
|
||||
| <a id="mutationverifiednamespacecreateverificationlevel"></a>`verificationLevel` | [`String!`](#string) | Verification level used to indicate the verification for namespace given by Gitlab. |
|
||||
| <a id="mutationverifiednamespacecreateverificationlevel"></a>`verificationLevel` | [`CiCatalogResourceVerificationLevel!`](#cicatalogresourceverificationlevel) | Verification level used to indicate the verification for namespace given by Gitlab. |
|
||||
|
||||
#### Fields
|
||||
|
||||
|
|
@ -15334,6 +15348,30 @@ The edge type for [`UserCore`](#usercore).
|
|||
| <a id="usercoreedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| <a id="usercoreedgenode"></a>`node` | [`UserCore`](#usercore) | The item at the end of the edge. |
|
||||
|
||||
#### `UsersQueuedForRolePromotionConnection`
|
||||
|
||||
The connection type for [`UsersQueuedForRolePromotion`](#usersqueuedforrolepromotion).
|
||||
|
||||
##### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usersqueuedforrolepromotionconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
|
||||
| <a id="usersqueuedforrolepromotionconnectionedges"></a>`edges` | [`[UsersQueuedForRolePromotionEdge]`](#usersqueuedforrolepromotionedge) | A list of edges. |
|
||||
| <a id="usersqueuedforrolepromotionconnectionnodes"></a>`nodes` | [`[UsersQueuedForRolePromotion]`](#usersqueuedforrolepromotion) | A list of nodes. |
|
||||
| <a id="usersqueuedforrolepromotionconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
||||
#### `UsersQueuedForRolePromotionEdge`
|
||||
|
||||
The edge type for [`UsersQueuedForRolePromotion`](#usersqueuedforrolepromotion).
|
||||
|
||||
##### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usersqueuedforrolepromotionedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| <a id="usersqueuedforrolepromotionedgenode"></a>`node` | [`UsersQueuedForRolePromotion`](#usersqueuedforrolepromotion) | The item at the end of the edge. |
|
||||
|
||||
#### `ValueStreamConnection`
|
||||
|
||||
The connection type for [`ValueStream`](#valuestream).
|
||||
|
|
@ -22597,7 +22635,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="groupvulnerabilitieshasremediations"></a>`hasRemediations` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have remediations. |
|
||||
| <a id="groupvulnerabilitieshasresolution"></a>`hasResolution` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have been resolved on default branch. |
|
||||
| <a id="groupvulnerabilitiesimage"></a>`image` | [`[String!]`](#string) | Filter vulnerabilities by location image. When this filter is present, the response only matches entries for a `reportType` that includes `container_scanning`, `cluster_image_scanning`. |
|
||||
| <a id="groupvulnerabilitiesowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. |
|
||||
| <a id="groupvulnerabilitiesowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. Wildcard value "NONE" also supported when feature flag `owasp_top_10_null_filtering` is enabled. "NONE" wildcard cannot be combined with other OWASP top 10 values. |
|
||||
| <a id="groupvulnerabilitiesprojectid"></a>`projectId` | [`[ID!]`](#id) | Filter vulnerabilities by project. |
|
||||
| <a id="groupvulnerabilitiesreporttype"></a>`reportType` | [`[VulnerabilityReportType!]`](#vulnerabilityreporttype) | Filter vulnerabilities by report type. |
|
||||
| <a id="groupvulnerabilitiesscanner"></a>`scanner` | [`[String!]`](#string) | Filter vulnerabilities by VulnerabilityScanner.externalId. |
|
||||
|
|
@ -22653,7 +22691,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
|
|||
| <a id="groupvulnerabilityseveritiescounthasremediations"></a>`hasRemediations` | [`Boolean`](#boolean) | Filter vulnerabilities that do or do not have remediations. |
|
||||
| <a id="groupvulnerabilityseveritiescounthasresolution"></a>`hasResolution` | [`Boolean`](#boolean) | Filter vulnerabilities that do or do not have a resolution. |
|
||||
| <a id="groupvulnerabilityseveritiescountimage"></a>`image` | [`[String!]`](#string) | Filter vulnerabilities by location image. When this filter is present, the response only matches entries for a `reportType` that includes `container_scanning`, `cluster_image_scanning`. |
|
||||
| <a id="groupvulnerabilityseveritiescountowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. |
|
||||
| <a id="groupvulnerabilityseveritiescountowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. Wildcard value "NONE" also supported when feature flag `owasp_top_10_null_filtering` is enabled. "NONE" wildcard cannot be combined with other OWASP top 10 values. |
|
||||
| <a id="groupvulnerabilityseveritiescountprojectid"></a>`projectId` | [`[ID!]`](#id) | Filter vulnerabilities by project. |
|
||||
| <a id="groupvulnerabilityseveritiescountreporttype"></a>`reportType` | [`[VulnerabilityReportType!]`](#vulnerabilityreporttype) | Filter vulnerabilities by report type. |
|
||||
| <a id="groupvulnerabilityseveritiescountscanner"></a>`scanner` | [`[String!]`](#string) | Filter vulnerabilities by scanner. |
|
||||
|
|
@ -23289,7 +23327,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
|
|||
| <a id="instancesecuritydashboardvulnerabilityseveritiescounthasremediations"></a>`hasRemediations` | [`Boolean`](#boolean) | Filter vulnerabilities that do or do not have remediations. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescounthasresolution"></a>`hasResolution` | [`Boolean`](#boolean) | Filter vulnerabilities that do or do not have a resolution. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescountimage"></a>`image` | [`[String!]`](#string) | Filter vulnerabilities by location image. When this filter is present, the response only matches entries for a `reportType` that includes `container_scanning`, `cluster_image_scanning`. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescountowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescountowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. Wildcard value "NONE" also supported when feature flag `owasp_top_10_null_filtering` is enabled. "NONE" wildcard cannot be combined with other OWASP top 10 values. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescountprojectid"></a>`projectId` | [`[ID!]`](#id) | Filter vulnerabilities by project. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescountreporttype"></a>`reportType` | [`[VulnerabilityReportType!]`](#vulnerabilityreporttype) | Filter vulnerabilities by report type. |
|
||||
| <a id="instancesecuritydashboardvulnerabilityseveritiescountscanner"></a>`scanner` | [`[String!]`](#string) | Filter vulnerabilities by scanner. |
|
||||
|
|
@ -28823,7 +28861,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="projectvulnerabilitieshasremediations"></a>`hasRemediations` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have remediations. |
|
||||
| <a id="projectvulnerabilitieshasresolution"></a>`hasResolution` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have been resolved on default branch. |
|
||||
| <a id="projectvulnerabilitiesimage"></a>`image` | [`[String!]`](#string) | Filter vulnerabilities by location image. When this filter is present, the response only matches entries for a `reportType` that includes `container_scanning`, `cluster_image_scanning`. |
|
||||
| <a id="projectvulnerabilitiesowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. |
|
||||
| <a id="projectvulnerabilitiesowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. Wildcard value "NONE" also supported when feature flag `owasp_top_10_null_filtering` is enabled. "NONE" wildcard cannot be combined with other OWASP top 10 values. |
|
||||
| <a id="projectvulnerabilitiesprojectid"></a>`projectId` | [`[ID!]`](#id) | Filter vulnerabilities by project. |
|
||||
| <a id="projectvulnerabilitiesreporttype"></a>`reportType` | [`[VulnerabilityReportType!]`](#vulnerabilityreporttype) | Filter vulnerabilities by report type. |
|
||||
| <a id="projectvulnerabilitiesscanner"></a>`scanner` | [`[String!]`](#string) | Filter vulnerabilities by VulnerabilityScanner.externalId. |
|
||||
|
|
@ -28866,7 +28904,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
|
|||
| <a id="projectvulnerabilityseveritiescounthasremediations"></a>`hasRemediations` | [`Boolean`](#boolean) | Filter vulnerabilities that do or do not have remediations. |
|
||||
| <a id="projectvulnerabilityseveritiescounthasresolution"></a>`hasResolution` | [`Boolean`](#boolean) | Filter vulnerabilities that do or do not have a resolution. |
|
||||
| <a id="projectvulnerabilityseveritiescountimage"></a>`image` | [`[String!]`](#string) | Filter vulnerabilities by location image. When this filter is present, the response only matches entries for a `reportType` that includes `container_scanning`, `cluster_image_scanning`. |
|
||||
| <a id="projectvulnerabilityseveritiescountowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. |
|
||||
| <a id="projectvulnerabilityseveritiescountowasptopten"></a>`owaspTopTen` | [`[VulnerabilityOwaspTop10!]`](#vulnerabilityowasptop10) | Filter vulnerabilities by OWASP Top 10 category. Wildcard value "NONE" also supported when feature flag `owasp_top_10_null_filtering` is enabled. "NONE" wildcard cannot be combined with other OWASP top 10 values. |
|
||||
| <a id="projectvulnerabilityseveritiescountprojectid"></a>`projectId` | [`[ID!]`](#id) | Filter vulnerabilities by project. |
|
||||
| <a id="projectvulnerabilityseveritiescountreporttype"></a>`reportType` | [`[VulnerabilityReportType!]`](#vulnerabilityreporttype) | Filter vulnerabilities by report type. |
|
||||
| <a id="projectvulnerabilityseveritiescountscanner"></a>`scanner` | [`[String!]`](#string) | Filter vulnerabilities by scanner. |
|
||||
|
|
@ -31308,6 +31346,17 @@ fields relate to interactions between the two entities.
|
|||
| <a id="userstatusmessage"></a>`message` | [`String`](#string) | User status message. |
|
||||
| <a id="userstatusmessagehtml"></a>`messageHtml` | [`String`](#string) | HTML of the user status message. |
|
||||
|
||||
### `UsersQueuedForRolePromotion`
|
||||
|
||||
Represents a Pending Member Approval Queued for Role Promotion.
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usersqueuedforrolepromotionnewaccesslevel"></a>`newAccessLevel` | [`AccessLevel`](#accesslevel) | Highest New GitLab::Access level requested for the member. |
|
||||
| <a id="usersqueuedforrolepromotionuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member approval object. |
|
||||
|
||||
### `ValueStream`
|
||||
|
||||
#### Fields
|
||||
|
|
@ -34522,6 +34571,8 @@ Possible filter types for remote development cluster agents in a namespace.
|
|||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="namespaceclusteragentfilteravailable"></a>`AVAILABLE` | Cluster agents in the namespace that can be used for hosting workspaces. |
|
||||
| <a id="namespaceclusteragentfilterdirectly_mapped"></a>`DIRECTLY_MAPPED` | Cluster agents that are directly mapped to the given namespace. |
|
||||
| <a id="namespaceclusteragentfilterunmapped"></a>`UNMAPPED` | Cluster agents within a namespace that are not directly mapped to it. |
|
||||
|
||||
### `NamespaceProjectSort`
|
||||
|
||||
|
|
@ -35536,6 +35587,7 @@ OwaspTop10 category of the vulnerability.
|
|||
| <a id="vulnerabilityowasptop10a8_2021"></a>`A8_2021` | A8:2021-Software and Data Integrity Failures, OWASP top 10 category. |
|
||||
| <a id="vulnerabilityowasptop10a9_2017"></a>`A9_2017` | A9:2017-Using Components with Known Vulnerabilities, OWASP top 10 category. |
|
||||
| <a id="vulnerabilityowasptop10a9_2021"></a>`A9_2021` | A9:2021-Security Logging and Monitoring Failures, OWASP top 10 category. |
|
||||
| <a id="vulnerabilityowasptop10none"></a>`NONE` | No OWASP top 10 category. |
|
||||
|
||||
### `VulnerabilityReportType`
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,7 @@ DETAILS:
|
|||
> - `cube_api_proxy` removed and replaced with `product_analytics_internal_preview` in GitLab 15.10.
|
||||
> - `product_analytics_internal_preview` replaced with `product_analytics_dashboards` in GitLab 15.11.
|
||||
> - `product_analytics_dashboards` [enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/398653) by default in GitLab 16.11.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab and GitLab Dedicated, by default this feature is not available. To make it available per project or for your entire instance, an administrator can [enable the feature flag](../administration/feature_flags.md) named `cube_api_proxy`.
|
||||
On GitLab.com, this feature is available.
|
||||
This feature is not ready for production use.
|
||||
> - Feature flag `product_analytics_dashboards` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/454059) in GitLab 17.1.
|
||||
|
||||
NOTE:
|
||||
Make sure to define the `cube_api_base_url` and `cube_api_key` application settings first using [the API](settings.md).
|
||||
|
|
|
|||
|
|
@ -851,7 +851,7 @@ Administrators can monitor usage of these API clients by
|
|||
|
||||
### Rust
|
||||
|
||||
- [`gitlab` crate](https://crates.io/crates/gitlab)
|
||||
- [`gitlab` crate](https://crates.io/crates/gitlab/)
|
||||
|
||||
### Swift
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
status: proposed
|
||||
creation-date: "2024-05-27"
|
||||
authors: [ "@bsandlin" ]
|
||||
coach: "@ntepluhina"
|
||||
approvers: [ "@dhershkovitch", "@marknuzzo" ]
|
||||
owning-stage: "~devops::verify"
|
||||
participating-stages: []
|
||||
---
|
||||
|
||||
<!-- Blueprints often contain forward-looking statements -->
|
||||
<!-- vale gitlab.FutureTense = NO -->
|
||||
|
||||
# Pipeline Mini Graph
|
||||
|
||||
This blueprint serves as living documentation for the Pipeline Mini Graph. The Pipeline Mini Graph is used in various places throughout the platform to communicate to users the status of the relevant pipeline. Users are able to re-run jobs directly from the component or drilldown into said jobs and linked pipelines for further investigation.
|
||||
|
||||
## Motivation
|
||||
|
||||
While the Pipeline Mini Graph primarily functions via REST, we are updating the component to support GraphQL and subsequently migrating all instances of this component to GraphQL. This documentation will serve as the SSOT for this refactor. Developers have expressed difficulty contributing to this component as the two APIs co-exist, so we need to make this code easier to update while also supporting both REST and GraphQL. This refactor lives behind a feature flag called `ci_graphql_pipeline_mini_graph`.
|
||||
|
||||
### Goals
|
||||
|
||||
- Improved maintainability
|
||||
- Backwards compatibility
|
||||
- Improved query performance
|
||||
- Deprecation of REST support
|
||||
|
||||
### Non-Goals
|
||||
|
||||
- Redesign of the Pipeline Mini Graph UI
|
||||
|
||||
## Proposal
|
||||
|
||||
To break down implementation, we are taking the following steps:
|
||||
|
||||
1. Separate the REST version and the GraphQL version of the component into 2 directories called `pipeline_mini_graph` and `legacy_pipeline_mini_graph`. This way, developers can contribute with more ease and we can easily remove the REST version once all apps are using GraphQL.
|
||||
1. Finish updating the newer component to fully support GraphQL by adding a query for the stage dropdown.
|
||||
1. Optimize GraphQL query structure to be more performant.
|
||||
1. Roll out `ci_graphql_pipeline_mini_graph` to globally enable GraphQL instances of the component.
|
||||
|
|
@ -225,7 +225,7 @@ Some key details about runners:
|
|||
- You can use the [`tags` keyword](../runners/configure_runners.md#control-jobs-that-a-runner-can-run)
|
||||
for finer control, and associate runners with specific jobs. For example, you can use a tag for jobs that
|
||||
require dedicated, more powerful, or specific hardware.
|
||||
- GitLab has [autoscaling for runners](https://docs.gitlab.com/runner/runner_autoscale).
|
||||
- GitLab has [autoscaling for runners](https://docs.gitlab.com/runner/runner_autoscale/).
|
||||
Use autoscaling to provision runners only when needed and scale down when not needed.
|
||||
|
||||
### TeamCity build features & plugins
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ like `:hover` and others ([Chrome](https://developer.chrome.com/docs/devtools/cs
|
|||
- Account for states dependent on data size ([empty](https://design.gitlab.com/patterns/empty-states),
|
||||
some data, and lots of data).
|
||||
- Account for states dependent on user role, user preferences, and subscription.
|
||||
- Consider animations and transitions, and follow their [guidelines](https://design.gitlab.com/product-foundations/motion/).
|
||||
- Consider animations and transitions, and follow their [guidelines](https://design.gitlab.com/brand-design/motion).
|
||||
|
||||
### Responsive
|
||||
|
||||
|
|
|
|||
|
|
@ -188,5 +188,5 @@ flowchart LR;
|
|||
|
||||
## Data Privacy
|
||||
|
||||
GitLab only receives event counts or similarly aggregated information from self-managed instances. User identifiers for individual events on the SaaS version of GitLab are [pseudonymized](https://metrics.gitlab.com/identifiers).
|
||||
GitLab only receives event counts or similarly aggregated information from self-managed instances. User identifiers for individual events on the SaaS version of GitLab are [pseudonymized](https://metrics.gitlab.com/identifiers/).
|
||||
An exact description on what kind of data is being collected through the Internal Analytics system is given in our [handbook](https://handbook.gitlab.com/handbook/legal/privacy/customer-product-usage-information/).
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ track_event(
|
|||
|
||||
Any frontend tracking call automatically passes the values `user.id`, `namespace.id`, and `project.id` from the current context of the page.
|
||||
|
||||
If you need to pass any further properties, such as `extra`, `context`, `label`, `property`, and `value`, you can use the [deprecated snowplow implementation](https://docs.gitlab.com/16.4/ee/development/internal_analytics/snowplow/implementation.html). In this case, let us know about your specific use-case in our [feedback issue for Internal Events](https://gitlab.com/gitlab-org/analytics-section/analytics-instrumentation/internal/-/issues/690).
|
||||
If you need to pass any further properties, such as `extra`, `context`, `label`, `property`, and `value`, you can use the [deprecated snowplow implementation](https://archives.docs.gitlab.com/16.4/ee/development/internal_analytics/snowplow/implementation.html). In this case, let us know about your specific use-case in our [feedback issue for Internal Events](https://gitlab.com/gitlab-org/analytics-section/analytics-instrumentation/internal/-/issues/690).
|
||||
|
||||
#### Vue components
|
||||
|
||||
|
|
|
|||
|
|
@ -729,7 +729,7 @@ We must add [the VPC IP Address Range (CIDR)](https://docs.aws.amazon.com/elasti
|
|||
|
||||
### Proxy Protocol
|
||||
|
||||
If Proxy protocol is enabled in the [load balancer](#load-balancer) we created earlier, we must also [enable](https://docs.gitlab.com/omnibus/settings/nginx.md#configuring-the-proxy-protocol) this on the `gitlab.rb` file.
|
||||
If Proxy protocol is enabled in the [load balancer](#load-balancer) we created earlier, we must also [enable](https://docs.gitlab.com/omnibus/settings/nginx.html#configuring-the-proxy-protocol) this on the `gitlab.rb` file.
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb`:
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ If the highest number stable branch is unclear, check the [GitLab blog](https://
|
|||
| [RubyGems](#3-rubygems) | `3.5.x` | A specific RubyGems version is not required, but you should update to benefit from some known performance improvements. |
|
||||
| [Go](#4-go) | `1.20.x` | From GitLab 16.4, Go 1.20 or later is required. |
|
||||
| [Git](#git) | `2.42.x` | From GitLab 16.5, Git 2.42.x and later is required. You should use the [Git version provided by Gitaly](#git). |
|
||||
| [Node.js](#5-node) | `18.17.x` | From GitLab 16.3, Node.js 18.17 or later is required. |
|
||||
| [Node.js](#5-node) | `20.13.x` | From GitLab 17.0, Node.js 20.13 or later is required. |
|
||||
|
||||
## GitLab directory structure
|
||||
|
||||
|
|
@ -266,8 +266,8 @@ GitLab requires the use of Node to compile JavaScript
|
|||
assets, and Yarn to manage JavaScript dependencies. The current minimum
|
||||
requirements for these are:
|
||||
|
||||
- `node` 18.x releases (v18.17.0 or later).
|
||||
[Other LTS versions of Node.js](https://github.com/nodejs/release#release-schedule) might be able to build assets, but we only guarantee Node.js 18.x.
|
||||
- `node` 20.x releases (v20.13.0 or later).
|
||||
[Other LTS versions of Node.js](https://github.com/nodejs/release#release-schedule) might be able to build assets, but we only guarantee Node.js 20.x.
|
||||
- `yarn` = v1.22.x (Yarn 2 is not supported yet)
|
||||
|
||||
In many distributions,
|
||||
|
|
@ -275,8 +275,8 @@ the versions provided by the official package repositories are out of date, so
|
|||
we must install through the following commands:
|
||||
|
||||
```shell
|
||||
# install node v18.x
|
||||
curl --location "https://deb.nodesource.com/setup_18.x" | sudo bash -
|
||||
# install node v20.x
|
||||
curl --location "https://deb.nodesource.com/setup_20.x" | sudo bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
npm install --global yarn
|
||||
|
|
|
|||
|
|
@ -424,4 +424,4 @@ accDescr: Sequence of actions that happen when a user authenticates to GitLab th
|
|||
For help and support around your GitLab Mattermost deployment, see:
|
||||
|
||||
- [Troubleshooting Mattermost issues](https://docs.mattermost.com/install/troubleshooting.html).
|
||||
- [Mattermost GitLab Issues Support Handbook](https://docs.mattermost.com/process/support.html?highlight=omnibus#gitlab-issues).
|
||||
- [Mattermost forum](https://forum.mattermost.com/search?q=gitlab).
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
|
|
@ -1249,7 +1249,7 @@ Do not override the `reports.html.destination` or `reports.html.outputLocation`
|
|||
|
||||
### Python projects
|
||||
|
||||
Extra care needs to be taken when using the [`PIP_EXTRA_INDEX_URL`](https://pipenv.pypa.io/en/latest/cli/#envvar-PIP_EXTRA_INDEX_URL)
|
||||
Extra care needs to be taken when using the [`PIP_EXTRA_INDEX_URL`](https://pipenv.pypa.io/en/latest/indexes.html)
|
||||
environment variable due to a possible exploit documented by [CVE-2018-20225](https://nvd.nist.gov/vuln/detail/CVE-2018-20225):
|
||||
|
||||
> An issue was discovered in pip (all versions) because it installs the version with the highest version number, even if the user had
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue