Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7ca4444627
commit
9c0f4306f6
|
|
@ -16,7 +16,6 @@ import {
|
|||
import * as Sentry from '@sentry/browser';
|
||||
import { isEmpty, omit } from 'lodash';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import {
|
||||
integrationTypes,
|
||||
integrationSteps,
|
||||
|
|
@ -60,7 +59,6 @@ export default {
|
|||
directives: {
|
||||
GlModal: GlModalDirective,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
inject: {
|
||||
generic: {
|
||||
default: {},
|
||||
|
|
@ -163,12 +161,7 @@ export default {
|
|||
};
|
||||
},
|
||||
showMappingBuilder() {
|
||||
return (
|
||||
this.multiIntegrations &&
|
||||
this.glFeatures.multipleHttpIntegrationsCustomMapping &&
|
||||
this.isHttp &&
|
||||
this.alertFields?.length
|
||||
);
|
||||
return this.multiIntegrations && this.isHttp && this.alertFields?.length;
|
||||
},
|
||||
hasSamplePayload() {
|
||||
return this.isValidNonEmptyJSON(this.currentIntegration?.payloadExample);
|
||||
|
|
@ -234,12 +227,10 @@ export default {
|
|||
},
|
||||
submit() {
|
||||
const { name, apiUrl } = this.integrationForm;
|
||||
const customMappingVariables = this.glFeatures.multipleHttpIntegrationsCustomMapping
|
||||
? {
|
||||
payloadAttributeMappings: this.mapping,
|
||||
payloadExample: this.samplePayload.json || '{}',
|
||||
}
|
||||
: {};
|
||||
const customMappingVariables = {
|
||||
payloadAttributeMappings: this.mapping,
|
||||
payloadExample: this.samplePayload.json || '{}',
|
||||
};
|
||||
|
||||
const variables =
|
||||
this.selectedIntegration === typeSet.http
|
||||
|
|
|
|||
|
|
@ -63,10 +63,7 @@ export default (el) => {
|
|||
render(createElement) {
|
||||
return createElement('alert-settings-wrapper', {
|
||||
props: {
|
||||
alertFields:
|
||||
gon.features?.multipleHttpIntegrationsCustomMapping && parseBoolean(multiIntegrations)
|
||||
? JSON.parse(alertFields)
|
||||
: null,
|
||||
alertFields: parseBoolean(multiIntegrations) ? JSON.parse(alertFields) : null,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { buildApiUrl } from './api_utils';
|
|||
import { DEFAULT_PER_PAGE } from './constants';
|
||||
|
||||
const GROUPS_PATH = '/api/:version/groups.json';
|
||||
const GROUPS_MEMBERS_SINGLE_PATH = '/api/:version/groups/:group_id/members/:id';
|
||||
|
||||
export function getGroups(query, options, callback = () => {}) {
|
||||
const url = buildApiUrl(GROUPS_PATH);
|
||||
|
|
@ -21,11 +20,3 @@ export function getGroups(query, options, callback = () => {}) {
|
|||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
export function removeMemberFromGroup(groupId, memberId, options) {
|
||||
const url = buildApiUrl(GROUPS_MEMBERS_SINGLE_PATH)
|
||||
.replace(':group_id', groupId)
|
||||
.replace(':id', memberId);
|
||||
|
||||
return axios.delete(url, { params: { ...options } });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,12 +79,12 @@ export default {
|
|||
<form>
|
||||
<div class="gl-display-flex">
|
||||
<gl-toggle
|
||||
data-qa-selector="allow_duplicates_checkbox"
|
||||
data-qa-selector="allow_duplicates_toggle"
|
||||
:value="mavenDuplicatesAllowed"
|
||||
@change="update($options.modelNames.MAVEN_DUPLICATES_ALLOWED, $event)"
|
||||
/>
|
||||
<div class="gl-ml-5">
|
||||
<div data-testid="toggle-label">
|
||||
<div data-testid="toggle-label" data-qa-selector="allow_duplicates_label">
|
||||
<gl-sprintf :message="enabledButtonLabel">
|
||||
<template #bold="{ content }">
|
||||
<strong>{{ content }}</strong>
|
||||
|
|
|
|||
|
|
@ -237,7 +237,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
[
|
||||
*::ApplicationSettingsHelper.visible_attributes,
|
||||
*::ApplicationSettingsHelper.external_authorization_service_attributes,
|
||||
*ApplicationSetting.repository_storages_weighted_attributes,
|
||||
*ApplicationSetting.kroki_formats_attributes.keys.map { |key| "kroki_formats_#{key}".to_sym },
|
||||
:lets_encrypt_notification_email,
|
||||
:lets_encrypt_terms_of_service_accepted,
|
||||
|
|
@ -248,8 +247,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
:default_branch_name,
|
||||
disabled_oauth_sign_in_sources: [],
|
||||
import_sources: [],
|
||||
repository_storages: [],
|
||||
restricted_visibility_levels: []
|
||||
restricted_visibility_levels: [],
|
||||
repository_storages_weighted: {}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,6 @@ module Projects
|
|||
before_action :authorize_admin_operations!
|
||||
before_action :authorize_read_prometheus_alerts!, only: [:reset_alerting_token]
|
||||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:multiple_http_integrations_custom_mapping, @project)
|
||||
end
|
||||
|
||||
respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]
|
||||
|
||||
helper_method :error_tracking_setting
|
||||
|
|
|
|||
|
|
@ -37,13 +37,8 @@ module ApplicationSettingsHelper
|
|||
end
|
||||
|
||||
def storage_weights
|
||||
ApplicationSetting.repository_storages_weighted_attributes.map do |attribute|
|
||||
storage = attribute.to_s.delete_prefix('repository_storages_weighted_')
|
||||
{
|
||||
name: attribute,
|
||||
label: storage,
|
||||
value: @application_setting.repository_storages_weighted[storage] || 0
|
||||
}
|
||||
Gitlab.config.repositories.storages.keys.each_with_object(OpenStruct.new) do |storage, weights|
|
||||
weights[storage.to_sym] = @application_setting.repository_storages_weighted[storage] || 0
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ module DiffHelper
|
|||
def mark_inline_diffs(old_line, new_line)
|
||||
old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_line, new_line).inline_diffs
|
||||
|
||||
marked_old_line = Gitlab::Diff::InlineDiffMarker.new(old_line).mark(old_diffs, mode: :deletion)
|
||||
marked_new_line = Gitlab::Diff::InlineDiffMarker.new(new_line).mark(new_diffs, mode: :addition)
|
||||
marked_old_line = Gitlab::Diff::InlineDiffMarker.new(old_line).mark(old_diffs)
|
||||
marked_new_line = Gitlab::Diff::InlineDiffMarker.new(new_line).mark(new_diffs)
|
||||
|
||||
[marked_old_line, marked_new_line]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ class ApplicationSetting < ApplicationRecord
|
|||
alias_attribute :instance_group_id, :instance_administrators_group_id
|
||||
alias_attribute :instance_administrators_group, :instance_group
|
||||
|
||||
def self.repository_storages_weighted_attributes
|
||||
@repository_storages_weighted_atributes ||= Gitlab.config.repositories.storages.keys.map { |k| "repository_storages_weighted_#{k}".to_sym }.freeze
|
||||
end
|
||||
|
||||
def self.kroki_formats_attributes
|
||||
{
|
||||
blockdiag: {
|
||||
|
|
@ -44,7 +40,6 @@ class ApplicationSetting < ApplicationRecord
|
|||
end
|
||||
|
||||
store_accessor :kroki_formats, *ApplicationSetting.kroki_formats_attributes.keys, prefix: true
|
||||
store_accessor :repository_storages_weighted, *Gitlab.config.repositories.storages.keys, prefix: true
|
||||
|
||||
# Include here so it can override methods from
|
||||
# `add_authentication_token_field`
|
||||
|
|
@ -503,6 +498,7 @@ class ApplicationSetting < ApplicationRecord
|
|||
inclusion: { in: [true, false], message: _('must be a boolean value') }
|
||||
|
||||
before_validation :ensure_uuid!
|
||||
before_validation :coerce_repository_storages_weighted, if: :repository_storages_weighted_changed?
|
||||
|
||||
before_save :ensure_runners_registration_token
|
||||
before_save :ensure_health_check_access_token
|
||||
|
|
@ -583,12 +579,6 @@ class ApplicationSetting < ApplicationRecord
|
|||
recaptcha_enabled || login_recaptcha_protection_enabled
|
||||
end
|
||||
|
||||
repository_storages_weighted_attributes.each do |attribute|
|
||||
define_method :"#{attribute}=" do |value|
|
||||
super(value.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
kroki_formats_attributes.keys.each do |key|
|
||||
define_method :"kroki_formats_#{key}=" do |value|
|
||||
super(::Gitlab::Utils.to_boolean(value))
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ module ApplicationSettingImplementation
|
|||
raw_blob_request_limit: 300,
|
||||
recaptcha_enabled: false,
|
||||
repository_checks_enabled: true,
|
||||
repository_storages_weighted: { default: 100 },
|
||||
repository_storages_weighted: { 'default' => 100 },
|
||||
repository_storages: ['default'],
|
||||
require_admin_approval_after_user_signup: true,
|
||||
require_two_factor_authentication: false,
|
||||
|
|
@ -298,10 +298,6 @@ module ApplicationSettingImplementation
|
|||
Array(read_attribute(:repository_storages))
|
||||
end
|
||||
|
||||
def repository_storages_weighted
|
||||
read_attribute(:repository_storages_weighted)
|
||||
end
|
||||
|
||||
def commit_email_hostname
|
||||
super.presence || self.class.default_commit_email_hostname
|
||||
end
|
||||
|
|
@ -333,9 +329,10 @@ module ApplicationSettingImplementation
|
|||
|
||||
def normalized_repository_storage_weights
|
||||
strong_memoize(:normalized_repository_storage_weights) do
|
||||
weights_total = repository_storages_weighted.values.reduce(:+)
|
||||
repository_storages_weights = repository_storages_weighted.slice(*Gitlab.config.repositories.storages.keys)
|
||||
weights_total = repository_storages_weights.values.reduce(:+)
|
||||
|
||||
repository_storages_weighted.transform_values do |w|
|
||||
repository_storages_weights.transform_values do |w|
|
||||
next w if weights_total == 0
|
||||
|
||||
w.to_f / weights_total
|
||||
|
|
@ -473,16 +470,20 @@ module ApplicationSettingImplementation
|
|||
invalid.empty?
|
||||
end
|
||||
|
||||
def coerce_repository_storages_weighted
|
||||
repository_storages_weighted.transform_values!(&:to_i)
|
||||
end
|
||||
|
||||
def check_repository_storages_weighted
|
||||
invalid = repository_storages_weighted.keys - Gitlab.config.repositories.storages.keys
|
||||
errors.add(:repository_storages_weighted, "can't include: %{invalid_storages}" % { invalid_storages: invalid.join(", ") }) unless
|
||||
errors.add(:repository_storages_weighted, _("can't include: %{invalid_storages}") % { invalid_storages: invalid.join(", ") }) unless
|
||||
invalid.empty?
|
||||
|
||||
repository_storages_weighted.each do |key, val|
|
||||
next unless val.present?
|
||||
|
||||
errors.add(:"repository_storages_weighted_#{key}", "value must be an integer") unless val.is_a?(Integer)
|
||||
errors.add(:"repository_storages_weighted_#{key}", "value must be between 0 and 100") unless val.between?(0, 100)
|
||||
errors.add(:repository_storages_weighted, _("value for '%{storage}' must be an integer") % { storage: key }) unless val.is_a?(Integer)
|
||||
errors.add(:repository_storages_weighted, _("value for '%{storage}' must be between 0 and 100") % { storage: key }) unless val.between?(0, 100)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ class PipelineSerializer < BaseSerializer
|
|||
[
|
||||
:cancelable_statuses,
|
||||
:latest_statuses_ordered_by_stage,
|
||||
:latest_builds_report_results,
|
||||
:retryable_builds,
|
||||
:stages,
|
||||
:latest_statuses,
|
||||
|
|
|
|||
|
|
@ -125,8 +125,8 @@ module SystemNotes
|
|||
|
||||
old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_title, new_title).inline_diffs
|
||||
|
||||
marked_old_title = Gitlab::Diff::InlineDiffMarkdownMarker.new(old_title).mark(old_diffs, mode: :deletion)
|
||||
marked_new_title = Gitlab::Diff::InlineDiffMarkdownMarker.new(new_title).mark(new_diffs, mode: :addition)
|
||||
marked_old_title = Gitlab::Diff::InlineDiffMarkdownMarker.new(old_title).mark(old_diffs)
|
||||
marked_new_title = Gitlab::Diff::InlineDiffMarkdownMarker.new(new_title).mark(new_diffs)
|
||||
|
||||
body = "changed title from **#{marked_old_title}** to **#{marked_new_title}**"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"title": "Security::Scan#info schema",
|
||||
"description": "The schema validates the content of the Security::Scan#info attribute",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"message"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,8 +18,9 @@
|
|||
= _('Enter weights for storages for new repositories.')
|
||||
= link_to sprite_icon('question-o'), help_page_path('administration/repository_storage_paths')
|
||||
.form-check
|
||||
- storage_weights.each do |attribute|
|
||||
= f.text_field attribute[:name], class: 'form-text-input', value: attribute[:value]
|
||||
= f.label attribute[:label], attribute[:label], class: 'label-bold form-check-label'
|
||||
%br
|
||||
= f.fields_for :repository_storages_weighted, storage_weights do |storage_form|
|
||||
- Gitlab.config.repositories.storages.keys.each do |storage|
|
||||
= storage_form.text_field storage, class: 'form-text-input'
|
||||
= storage_form.label storage, storage, class: 'label-bold form-check-label'
|
||||
%br
|
||||
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
|
||||
|
|
|
|||
|
|
@ -30,5 +30,5 @@
|
|||
= render_if_exists 'import/github/ci_cd_only'
|
||||
|
||||
.form-actions.d-flex.justify-content-end
|
||||
= link_to _('Cancel'), new_project_path, class: 'btn'
|
||||
= submit_tag _('Authenticate'), class: 'btn btn-success ml-2', data: { qa_selector: 'authenticate_button' }
|
||||
= link_to _('Cancel'), new_project_path, class: 'gl-button btn btn-default'
|
||||
= submit_tag _('Authenticate'), class: 'gl-button btn btn-confirm ml-2', data: { qa_selector: 'authenticate_button' }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Introduce `info` column for the `security_scans` table"
|
||||
merge_request: 55983
|
||||
author:
|
||||
type: added
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow saving repository weights after a storage has been removed
|
||||
merge_request: 55689
|
||||
author:
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Apply new GitLab UI for buttons on GitHub Import page
|
||||
merge_request: 56096
|
||||
author: Yogi (@yo)
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove latest_builds_report_results preloading in pipeline serializer
|
||||
merge_request: 56181
|
||||
author:
|
||||
type: performance
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: multiple_http_integrations_custom_mapping
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46437
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273573
|
||||
milestone: '13.6'
|
||||
name: introduce_marker_ranges
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55669
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324068
|
||||
milestone: '13.10'
|
||||
type: development
|
||||
group: group::monitor
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddInfoColumnIntoSecurityScansTable < ActiveRecord::Migration[6.0]
|
||||
DOWNTIME = false
|
||||
|
||||
def change
|
||||
add_column :security_scans, :info, :jsonb, null: false, default: {}
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
a81f3555d0e1159569687d4967edcd2b5706cdafd5defb8dc725e295eb969861
|
||||
|
|
@ -17244,7 +17244,8 @@ CREATE TABLE security_scans (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
build_id bigint NOT NULL,
|
||||
scan_type smallint NOT NULL
|
||||
scan_type smallint NOT NULL,
|
||||
info jsonb DEFAULT '{}'::jsonb NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE security_scans_id_seq
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ Where:
|
|||
| `enabled` | `true` or `false`. Enables the Registry in GitLab. By default this is `false`. |
|
||||
| `host` | The host URL under which the Registry runs and users can use. |
|
||||
| `port` | The port the external Registry domain listens on. |
|
||||
| `api_url` | The internal API URL under which the Registry is exposed. It defaults to `http://localhost:5000`. |
|
||||
| `api_url` | The internal API URL under which the Registry is exposed. It defaults to `http://localhost:5000`. Do not change this unless you are setting up an [external Docker registry](#use-an-external-container-registry-with-gitlab-as-an-auth-endpoint). |
|
||||
| `key` | The private key location that is a pair of Registry's `rootcertbundle`. Read the [token auth configuration documentation](https://docs.docker.com/registry/configuration/#token). |
|
||||
| `path` | This should be the same directory like specified in Registry's `rootdirectory`. Read the [storage configuration documentation](https://docs.docker.com/registry/configuration/#storage). This path needs to be readable by the GitLab user, the web-server user and the Registry user. Read more in [#configure-storage-for-the-container-registry](#configure-storage-for-the-container-registry). |
|
||||
| `issuer` | This should be the same value as configured in Registry's `issuer`. Read the [token auth configuration documentation](https://docs.docker.com/registry/configuration/#token). |
|
||||
|
|
@ -630,18 +630,18 @@ You can use GitLab as an auth endpoint with an external container registry.
|
|||
|
||||
```ruby
|
||||
gitlab_rails['registry_enabled'] = true
|
||||
gitlab_rails['registry_api_url'] = "http://localhost:5000"
|
||||
gitlab_rails['registry_api_url'] = "https://<external_registry_host>:5000"
|
||||
gitlab_rails['registry_issuer'] = "gitlab-issuer"
|
||||
```
|
||||
|
||||
`gitlab_rails['registry_enabled'] = true` is needed to enable GitLab
|
||||
Container Registry features and authentication endpoint. The GitLab bundled
|
||||
Container Registry service does not start, even with this enabled.
|
||||
|
||||
`gitlab_rails['registry_api_url'] = "http://localhost:5000"` can
|
||||
carry a different hostname and port depending on where the external registry
|
||||
is hosted. It must also specify `https` if the external registry is
|
||||
configured to use TLS.
|
||||
- `gitlab_rails['registry_enabled'] = true` is needed to enable GitLab
|
||||
Container Registry features and authentication endpoint. The GitLab bundled
|
||||
Container Registry service does not start, even with this enabled.
|
||||
- `gitlab_rails['registry_api_url'] = "http://<external_registry_host>:5000"`
|
||||
must be changed to match the host where Registry is installed.
|
||||
It must also specify `https` if the external registry is
|
||||
configured to use TLS. Read more on the
|
||||
[Docker registry documentation](https://docs.docker.com/registry/deploying/).
|
||||
|
||||
1. A certificate-key pair is required for GitLab and the external container
|
||||
registry to communicate securely. You need to create a certificate-key
|
||||
|
|
@ -688,12 +688,14 @@ You can use GitLab as an auth endpoint with an external container registry.
|
|||
enabled: true
|
||||
host: "registry.gitlab.example.com"
|
||||
port: "5005"
|
||||
api_url: "http://localhost:5000"
|
||||
path: /var/opt/gitlab/gitlab-rails/shared/registry
|
||||
key: /var/opt/gitlab/gitlab-rails/certificate.key
|
||||
api_url: "https://<external_registry_host>:5000"
|
||||
path: /var/lib/registry
|
||||
key: /path/to/keyfile
|
||||
issuer: gitlab-issuer
|
||||
```
|
||||
|
||||
[Read more](#enable-the-container-registry) about what these parameters mean.
|
||||
|
||||
1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
|
||||
|
||||
## Configure Container Registry notifications
|
||||
|
|
|
|||
|
|
@ -5190,6 +5190,7 @@ All possible ways to specify the API surface for an API fuzzing scan.
|
|||
| ----- | ----------- |
|
||||
| `HAR` | The API surface is specified by a HAR file. |
|
||||
| `OPENAPI` | The API surface is specified by a OPENAPI file. |
|
||||
| `POSTMAN` | The API surface is specified by a POSTMAN file. |
|
||||
|
||||
### `AvailabilityEnum`
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ For more details, please refer to our [full architecture documentation](https://
|
|||
|
||||
The setup process involves a few steps to enable GitOps deployments:
|
||||
|
||||
1. [Install the Agent server](#install-the-kubernetes-agent-server).
|
||||
1. [Install the Agent server](#install-the-kubernetes-agent-server) for your GitLab instance.
|
||||
1. [Define a configuration repository](#define-a-configuration-repository).
|
||||
1. [Create an Agent record in GitLab](#create-an-agent-record-in-gitlab).
|
||||
1. [Generate and copy a Secret token used to connect to the Agent](#create-the-kubernetes-secret).
|
||||
|
|
@ -91,14 +91,19 @@ Upgrade your agent installations together with GitLab upgrades. To decide which
|
|||
The available `agentk` and `kas` versions can be found in
|
||||
[the container registry](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/container_registry/).
|
||||
|
||||
### Install the Kubernetes Agent Server
|
||||
### Install the Kubernetes Agent Server **(FREE SELF)**
|
||||
|
||||
The GitLab Kubernetes Agent Server (KAS) can be deployed using [Omnibus GitLab](https://docs.gitlab.com/omnibus/) or the
|
||||
[GitLab chart](https://gitlab.com/gitlab-org/charts/gitlab). If you don't already have
|
||||
GitLab installed, please refer to our [installation documentation](../../../install/index.md).
|
||||
[Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.10,
|
||||
the GitLab Kubernetes Agent Server (KAS) is available on GitLab.com under `wss://kas.gitlab.com`.
|
||||
If you are a GitLab.com user, skip this step and directly
|
||||
[set up the configuration repository](#define-a-configuration-repository)
|
||||
for your agent.
|
||||
|
||||
NOTE:
|
||||
GitLab plans to include the KAS on [GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/3834).
|
||||
The GitLab Kubernetes Agent Server (KAS) can be deployed using [Omnibus
|
||||
GitLab](https://docs.gitlab.com/omnibus/) or the [GitLab
|
||||
chart](https://gitlab.com/gitlab-org/charts/gitlab). If you don't already have
|
||||
GitLab installed, please refer to our [installation
|
||||
documentation](https://docs.gitlab.com/ee/install/README.html).
|
||||
|
||||
#### Install with Omnibus
|
||||
|
||||
|
|
@ -230,6 +235,9 @@ the Agent in subsequent steps. You can create an Agent record either:
|
|||
|
||||
Next, install the in-cluster component of the Agent.
|
||||
|
||||
NOTE:
|
||||
For GitLab.com users, the KAS is available at `wss://kas.gitlab.com`.
|
||||
|
||||
#### One-liner installation
|
||||
|
||||
Replace the value of `agent-token` below with the token received from the previous step. Also, replace `kas-address` with the configured access of the Kubernetes Agent Server:
|
||||
|
|
|
|||
|
|
@ -91,8 +91,6 @@ module API
|
|||
end
|
||||
|
||||
params :optional_update_params_ee do
|
||||
optional :issues_template, type: String, desc: 'Default description for Issues'
|
||||
optional :merge_requests_template, type: String, desc: 'Default description for Merge Requests'
|
||||
end
|
||||
|
||||
params :optional_update_params do
|
||||
|
|
@ -130,10 +128,8 @@ module API
|
|||
:emails_disabled,
|
||||
:forking_access_level,
|
||||
:issues_access_level,
|
||||
:issues_template,
|
||||
:lfs_enabled,
|
||||
:merge_requests_access_level,
|
||||
:merge_requests_template,
|
||||
:merge_method,
|
||||
:name,
|
||||
:only_allow_merge_if_all_discussions_are_resolved,
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ module Banzai
|
|||
end
|
||||
|
||||
def autolink_filter(text)
|
||||
Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_PATTERN) do |link, left:, right:|
|
||||
Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_PATTERN) do |link, left:, right:, mode:|
|
||||
autolink_match(link).html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ module Banzai
|
|||
end
|
||||
|
||||
def spaced_link_filter(text)
|
||||
Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_OR_IMAGE_PATTERN) do |link, left:, right:|
|
||||
Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_OR_IMAGE_PATTERN) do |link, left:, right:, mode:|
|
||||
spaced_link_match(link).html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ module Gitlab
|
|||
highlighted_lines.map!.with_index do |rich_line, i|
|
||||
marker = StringRegexMarker.new((plain_lines[i].chomp! || plain_lines[i]), rich_line.html_safe)
|
||||
|
||||
marker.mark(regex, group: :name) do |text, left:, right:|
|
||||
marker.mark(regex, group: :name) do |text, left:, right:, mode:|
|
||||
url = yield(text)
|
||||
url ? link_tag(text, url) : text
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module Gitlab
|
|||
|
||||
i, j = match.offset(:name)
|
||||
marker = StringRangeMarker.new(plain_line, rich_line.html_safe)
|
||||
marker.mark([i..(j - 1)]) do |text, left:, right:|
|
||||
marker.mark([i..(j - 1)]) do |text, left:, right:, mode:|
|
||||
url = package_url(text, match[:version])
|
||||
url ? link_tag(text, url) : text
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module Gitlab
|
|||
i2, j2 = match.offset(:checksum)
|
||||
|
||||
marker = StringRangeMarker.new(plain_line, rich_line.html_safe)
|
||||
marker.mark([i0..(j0 - 1), i2..(j2 - 1)]) do |text, left:, right:|
|
||||
marker.mark([i0..(j0 - 1), i2..(j2 - 1)]) do |text, left:, right:, mode:|
|
||||
if left
|
||||
url = package_url(text, match[:version])
|
||||
url ? link_tag(text, url) : text
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ module Gitlab
|
|||
end
|
||||
|
||||
if action == :delete
|
||||
old_diffs << (old_pointer..(old_pointer + content_size - 1))
|
||||
old_diffs << MarkerRange.new(old_pointer, old_pointer + content_size - 1, mode: MarkerRange::DELETION)
|
||||
old_pointer += content_size
|
||||
end
|
||||
|
||||
if action == :insert
|
||||
new_diffs << (new_pointer..(new_pointer + content_size - 1))
|
||||
new_diffs << MarkerRange.new(new_pointer, new_pointer + content_size - 1, mode: MarkerRange::ADDITION)
|
||||
new_pointer += content_size
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@
|
|||
module Gitlab
|
||||
module Diff
|
||||
class Highlight
|
||||
attr_reader :diff_file, :diff_lines, :raw_lines, :repository
|
||||
attr_reader :diff_file, :diff_lines, :raw_lines, :repository, :project
|
||||
|
||||
delegate :old_path, :new_path, :old_sha, :new_sha, to: :diff_file, prefix: :diff
|
||||
|
||||
def initialize(diff_lines, repository: nil)
|
||||
@repository = repository
|
||||
@project = repository&.project
|
||||
|
||||
if diff_lines.is_a?(Gitlab::Diff::File)
|
||||
@diff_file = diff_lines
|
||||
|
|
@ -30,6 +31,12 @@ module Gitlab
|
|||
|
||||
if line_inline_diffs = inline_diffs[i]
|
||||
begin
|
||||
# MarkerRange objects are converted to Ranges to keep the previous behavior
|
||||
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324068
|
||||
if Feature.disabled?(:introduce_marker_ranges, project, default_enabled: :yaml)
|
||||
line_inline_diffs = line_inline_diffs.map { |marker_range| marker_range.to_range }
|
||||
end
|
||||
|
||||
rich_line = InlineDiffMarker.new(diff_line.text, rich_line).mark(line_inline_diffs)
|
||||
# This should only happen when the encoding of the diff doesn't
|
||||
# match the blob, which is a bug. But we shouldn't fail to render
|
||||
|
|
|
|||
|
|
@ -69,7 +69,12 @@ module Gitlab
|
|||
|
||||
def key
|
||||
strong_memoize(:redis_key) do
|
||||
['highlighted-diff-files', diffable.cache_key, VERSION, diff_options].join(":")
|
||||
[
|
||||
'highlighted-diff-files',
|
||||
diffable.cache_key, VERSION,
|
||||
diff_options,
|
||||
Feature.enabled?(:introduce_marker_ranges, diffable.project, default_enabled: :yaml)
|
||||
].join(":")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ module Gitlab
|
|||
deletion: "-"
|
||||
}.freeze
|
||||
|
||||
def mark(line_inline_diffs, mode: nil)
|
||||
super(line_inline_diffs) do |text, left:, right:|
|
||||
def mark(line_inline_diffs)
|
||||
super(line_inline_diffs) do |text, left:, right:, mode:|
|
||||
symbol = MARKDOWN_SYMBOLS[mode]
|
||||
"{#{symbol}#{text}#{symbol}}"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ module Gitlab
|
|||
super(line, rich_line || line)
|
||||
end
|
||||
|
||||
def mark(line_inline_diffs, mode: nil)
|
||||
super(line_inline_diffs) do |text, left:, right:|
|
||||
def mark(line_inline_diffs)
|
||||
super(line_inline_diffs) do |text, left:, right:, mode:|
|
||||
%{<span class="#{html_class_names(left, right, mode)}">#{text}</span>}.html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# It is a Range object extended with `mode` attribute
|
||||
# MarkerRange not only keeps information about changed characters, but also
|
||||
# the type of changes
|
||||
module Gitlab
|
||||
class MarkerRange < Range
|
||||
DELETION = :deletion
|
||||
ADDITION = :addition
|
||||
|
||||
# Converts Range object to MarkerRange class
|
||||
def self.from_range(range)
|
||||
return range if range.is_a?(self)
|
||||
|
||||
new(range.begin, range.end, exclude_end: range.exclude_end?)
|
||||
end
|
||||
|
||||
def initialize(first, last, exclude_end: false, mode: nil)
|
||||
super(first, last, exclude_end)
|
||||
@mode = mode
|
||||
end
|
||||
|
||||
def to_range
|
||||
Range.new(self.begin, self.end, self.exclude_end?)
|
||||
end
|
||||
|
||||
attr_reader :mode
|
||||
end
|
||||
end
|
||||
|
|
@ -15,8 +15,10 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def mark(marker_ranges)
|
||||
return rich_line unless marker_ranges&.any?
|
||||
def mark(ranges)
|
||||
return rich_line unless ranges&.any?
|
||||
|
||||
marker_ranges = ranges.map { |range| Gitlab::MarkerRange.from_range(range) }
|
||||
|
||||
if html_escaped
|
||||
rich_marker_ranges = []
|
||||
|
|
@ -24,7 +26,7 @@ module Gitlab
|
|||
# Map the inline-diff range based on the raw line to character positions in the rich line
|
||||
rich_positions = position_mapping[range].flatten
|
||||
# Turn the array of character positions into ranges
|
||||
rich_marker_ranges.concat(collapse_ranges(rich_positions))
|
||||
rich_marker_ranges.concat(collapse_ranges(rich_positions, range.mode))
|
||||
end
|
||||
else
|
||||
rich_marker_ranges = marker_ranges
|
||||
|
|
@ -36,7 +38,7 @@ module Gitlab
|
|||
offset_range = (range.begin + offset)..(range.end + offset)
|
||||
original_text = rich_line[offset_range]
|
||||
|
||||
text = yield(original_text, left: i == 0, right: i == rich_marker_ranges.length - 1)
|
||||
text = yield(original_text, left: i == 0, right: i == rich_marker_ranges.length - 1, mode: range.mode)
|
||||
|
||||
rich_line[offset_range] = text
|
||||
|
||||
|
|
@ -90,21 +92,21 @@ module Gitlab
|
|||
end
|
||||
|
||||
# Takes an array of integers, and returns an array of ranges covering the same integers
|
||||
def collapse_ranges(positions)
|
||||
def collapse_ranges(positions, mode)
|
||||
return [] if positions.empty?
|
||||
|
||||
ranges = []
|
||||
|
||||
start = prev = positions[0]
|
||||
range = start..prev
|
||||
range = MarkerRange.new(start, prev, mode: mode)
|
||||
positions[1..-1].each do |pos|
|
||||
if pos == prev + 1
|
||||
range = start..pos
|
||||
range = MarkerRange.new(start, pos, mode: mode)
|
||||
prev = pos
|
||||
else
|
||||
ranges << range
|
||||
start = prev = pos
|
||||
range = start..prev
|
||||
range = MarkerRange.new(start, prev, mode: mode)
|
||||
end
|
||||
end
|
||||
ranges << range
|
||||
|
|
|
|||
|
|
@ -1483,6 +1483,9 @@ msgstr ""
|
|||
msgid "APIFuzzing|Ex: $TestUsername"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz.har"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1507,6 +1510,9 @@ msgstr ""
|
|||
msgid "APIFuzzing|Password for basic authentication"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Postman collections are a group of saved requests you can organize into folders."
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Scan mode"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3224,6 +3230,9 @@ msgstr ""
|
|||
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
|
||||
msgstr ""
|
||||
|
||||
msgid "An assignee list displays issues assigned to the selected user"
|
||||
msgstr ""
|
||||
|
||||
msgid "An email notification was recently sent from the admin panel. Please wait %{wait_time_in_words} before attempting to send another message."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9413,6 +9422,9 @@ msgstr ""
|
|||
msgid "DastProfiles|Authentication URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "DastProfiles|Branch missing"
|
||||
msgstr ""
|
||||
|
||||
msgid "DastProfiles|Could not create the scanner profile. Please try again."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9584,6 +9596,9 @@ msgstr ""
|
|||
msgid "DastProfiles|Scanner name"
|
||||
msgstr ""
|
||||
|
||||
msgid "DastProfiles|Select branch"
|
||||
msgstr ""
|
||||
|
||||
msgid "DastProfiles|Show debug messages"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12629,6 +12644,9 @@ msgstr ""
|
|||
msgid "Failed to install."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to load assignees."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to load assignees. Please try again."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22817,6 +22835,9 @@ msgstr ""
|
|||
msgid "Policy project doesn't exists"
|
||||
msgstr ""
|
||||
|
||||
msgid "Postman collection"
|
||||
msgstr ""
|
||||
|
||||
msgid "Pre-defined push rules."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26413,6 +26434,9 @@ msgstr ""
|
|||
msgid "Search an environment spec"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search assignees"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search authors"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -35100,6 +35124,9 @@ msgstr ""
|
|||
msgid "can't be enabled because signed commits are required for this project"
|
||||
msgstr ""
|
||||
|
||||
msgid "can't include: %{invalid_storages}"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannot be a date in the past"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36506,6 +36533,12 @@ msgstr ""
|
|||
msgid "v%{version} published %{timeAgo}"
|
||||
msgstr ""
|
||||
|
||||
msgid "value for '%{storage}' must be an integer"
|
||||
msgstr ""
|
||||
|
||||
msgid "value for '%{storage}' must be between 0 and 100"
|
||||
msgstr ""
|
||||
|
||||
msgid "verify ownership"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -12,18 +12,28 @@ module QA
|
|||
end
|
||||
|
||||
view 'app/assets/javascripts/packages_and_registries/settings/group/components/maven_settings.vue' do
|
||||
element :allow_duplicates_checkbox
|
||||
element :allow_duplicates_toggle
|
||||
element :allow_duplicates_label
|
||||
end
|
||||
|
||||
def set_allow_duplicates_disabled
|
||||
expand_content :package_registry_settings_content do
|
||||
uncheck_element :allow_duplicates_checkbox
|
||||
click_element(:allow_duplicates_toggle) if duplicates_enabled?
|
||||
end
|
||||
end
|
||||
|
||||
def has_allow_duplicates_enabled?
|
||||
expand_content :package_registry_settings_content
|
||||
!find_element(:allow_duplicates_checkbox).checked?
|
||||
def set_allow_duplicates_enabled
|
||||
expand_content :package_registry_settings_content do
|
||||
click_element(:allow_duplicates_toggle) if duplicates_disabled?
|
||||
end
|
||||
end
|
||||
|
||||
def duplicates_enabled?
|
||||
has_element?(:allow_duplicates_label, text: 'Allow duplicates')
|
||||
end
|
||||
|
||||
def duplicates_disabled?
|
||||
has_element?(:allow_duplicates_label, text: 'Do not allow duplicates')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -223,9 +223,7 @@ module QA
|
|||
project.group.visit!
|
||||
|
||||
Page::Group::Menu.perform(&:go_to_package_settings)
|
||||
Page::Group::Settings::PackageRegistries.perform do |settings|
|
||||
expect(settings).to have_allow_duplicates_enabled
|
||||
end
|
||||
Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
|
||||
end
|
||||
|
||||
it 'allows users to publish duplicate Maven packages at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1722' do
|
||||
|
|
|
|||
|
|
@ -144,10 +144,10 @@ RSpec.describe Admin::ApplicationSettingsController do
|
|||
end
|
||||
|
||||
it 'updates repository_storages_weighted setting' do
|
||||
put :update, params: { application_setting: { repository_storages_weighted_default: 75 } }
|
||||
put :update, params: { application_setting: { repository_storages_weighted: { default: 75 } } }
|
||||
|
||||
expect(response).to redirect_to(general_admin_application_settings_path)
|
||||
expect(ApplicationSetting.current.repository_storages_weighted_default).to eq(75)
|
||||
expect(ApplicationSetting.current.repository_storages_weighted).to eq('default' => 75)
|
||||
end
|
||||
|
||||
it 'updates kroki_formats setting' do
|
||||
|
|
|
|||
|
|
@ -384,7 +384,20 @@ RSpec.describe 'Admin updates settings' do
|
|||
click_button 'Save changes'
|
||||
end
|
||||
|
||||
expect(current_settings.repository_storages_weighted_default).to be 50
|
||||
expect(current_settings.repository_storages_weighted).to eq('default' => 50)
|
||||
end
|
||||
|
||||
it 'still saves when settings are outdated' do
|
||||
current_settings.update_attribute :repository_storages_weighted, { 'default' => 100, 'outdated' => 100 }
|
||||
|
||||
visit repository_admin_application_settings_path
|
||||
|
||||
page.within('.as-repository-storage') do
|
||||
fill_in 'application_setting_repository_storages_weighted_default', with: 50
|
||||
click_button 'Save changes'
|
||||
end
|
||||
|
||||
expect(current_settings.repository_storages_weighted).to eq('default' => 50)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ RSpec.describe 'Alert integrations settings form', :js do
|
|||
describe 'when viewing alert integrations as a maintainer' do
|
||||
context 'with the default page permissions' do
|
||||
before do
|
||||
stub_feature_flags(multiple_http_integrations_custom_mapping: false)
|
||||
visit project_settings_operations_path(project, anchor: 'js-alert-management-settings')
|
||||
wait_for_requests
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,12 +12,7 @@ describe('AlertsSettingsForm', () => {
|
|||
let wrapper;
|
||||
const mockToastShow = jest.fn();
|
||||
|
||||
const createComponent = ({
|
||||
data = {},
|
||||
props = {},
|
||||
multipleHttpIntegrationsCustomMapping = false,
|
||||
multiIntegrations = true,
|
||||
} = {}) => {
|
||||
const createComponent = ({ data = {}, props = {}, multiIntegrations = true } = {}) => {
|
||||
wrapper = mount(AlertsSettingsForm, {
|
||||
data() {
|
||||
return { ...data };
|
||||
|
|
@ -29,7 +24,6 @@ describe('AlertsSettingsForm', () => {
|
|||
},
|
||||
provide: {
|
||||
...defaultAlertSettingsConfig,
|
||||
glFeatures: { multipleHttpIntegrationsCustomMapping },
|
||||
multiIntegrations,
|
||||
},
|
||||
mocks: {
|
||||
|
|
@ -142,27 +136,8 @@ describe('AlertsSettingsForm', () => {
|
|||
|
||||
describe('submitting integration form', () => {
|
||||
describe('HTTP', () => {
|
||||
it('create', async () => {
|
||||
createComponent();
|
||||
|
||||
const integrationName = 'Test integration';
|
||||
await selectOptionAtIndex(1);
|
||||
enableIntegration(0, integrationName);
|
||||
|
||||
const submitBtn = findSubmitButton();
|
||||
expect(submitBtn.exists()).toBe(true);
|
||||
expect(submitBtn.text()).toBe('Save integration');
|
||||
|
||||
findForm().trigger('submit');
|
||||
|
||||
expect(wrapper.emitted('create-new-integration')[0]).toEqual([
|
||||
{ type: typeSet.http, variables: { name: integrationName, active: true } },
|
||||
]);
|
||||
});
|
||||
|
||||
it('create with custom mapping', async () => {
|
||||
createComponent({
|
||||
multipleHttpIntegrationsCustomMapping: true,
|
||||
multiIntegrations: true,
|
||||
props: { alertFields },
|
||||
});
|
||||
|
|
@ -208,9 +183,19 @@ describe('AlertsSettingsForm', () => {
|
|||
|
||||
findForm().trigger('submit');
|
||||
|
||||
expect(wrapper.emitted('update-integration')[0]).toEqual([
|
||||
{ type: typeSet.http, variables: { name: updatedIntegrationName, active: true } },
|
||||
]);
|
||||
expect(wrapper.emitted('update-integration')[0]).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
type: typeSet.http,
|
||||
variables: {
|
||||
name: updatedIntegrationName,
|
||||
active: true,
|
||||
payloadAttributeMappings: [],
|
||||
payloadExample: '{}',
|
||||
},
|
||||
},
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -301,7 +286,6 @@ describe('AlertsSettingsForm', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
multipleHttpIntegrationsCustomMapping: true,
|
||||
data: {
|
||||
currentIntegration: {
|
||||
type: typeSet.http,
|
||||
|
|
@ -408,22 +392,18 @@ describe('AlertsSettingsForm', () => {
|
|||
|
||||
describe('Mapping builder section', () => {
|
||||
describe.each`
|
||||
alertFieldsProvided | multiIntegrations | featureFlag | integrationOption | visible
|
||||
${true} | ${true} | ${true} | ${1} | ${true}
|
||||
${true} | ${true} | ${true} | ${2} | ${false}
|
||||
${true} | ${true} | ${false} | ${1} | ${false}
|
||||
${true} | ${true} | ${false} | ${2} | ${false}
|
||||
${true} | ${false} | ${true} | ${1} | ${false}
|
||||
${false} | ${true} | ${true} | ${1} | ${false}
|
||||
`('', ({ alertFieldsProvided, multiIntegrations, featureFlag, integrationOption, visible }) => {
|
||||
alertFieldsProvided | multiIntegrations | integrationOption | visible
|
||||
${true} | ${true} | ${1} | ${true}
|
||||
${true} | ${true} | ${2} | ${false}
|
||||
${true} | ${false} | ${1} | ${false}
|
||||
${false} | ${true} | ${1} | ${false}
|
||||
`('', ({ alertFieldsProvided, multiIntegrations, integrationOption, visible }) => {
|
||||
const visibleMsg = visible ? 'is rendered' : 'is not rendered';
|
||||
const featureFlagMsg = featureFlag ? 'is enabled' : 'is disabled';
|
||||
const alertFieldsMsg = alertFieldsProvided ? 'are provided' : 'are not provided';
|
||||
const integrationType = integrationOption === 1 ? typeSet.http : typeSet.prometheus;
|
||||
|
||||
it(`${visibleMsg} when multipleHttpIntegrationsCustomMapping feature flag ${featureFlagMsg} and integration type is ${integrationType} and alert fields ${alertFieldsMsg}`, async () => {
|
||||
it(`${visibleMsg} when integration type is ${integrationType} and alert fields ${alertFieldsMsg}`, async () => {
|
||||
createComponent({
|
||||
multipleHttpIntegrationsCustomMapping: featureFlag,
|
||||
multiIntegrations,
|
||||
props: {
|
||||
alertFields: alertFieldsProvided ? alertFields : [],
|
||||
|
|
|
|||
|
|
@ -130,20 +130,15 @@ RSpec.describe ApplicationSettingsHelper do
|
|||
before do
|
||||
helper.instance_variable_set(:@application_setting, application_setting)
|
||||
stub_storage_settings({ 'default': {}, 'storage_1': {}, 'storage_2': {} })
|
||||
allow(ApplicationSetting).to receive(:repository_storages_weighted_attributes).and_return(
|
||||
[:repository_storages_weighted_default,
|
||||
:repository_storages_weighted_storage_1,
|
||||
:repository_storages_weighted_storage_2])
|
||||
|
||||
stub_application_setting(repository_storages_weighted: { 'default' => 100, 'storage_1' => 50, 'storage_2' => nil })
|
||||
end
|
||||
|
||||
it 'returns storages correctly' do
|
||||
expect(helper.storage_weights).to eq([
|
||||
{ name: :repository_storages_weighted_default, label: 'default', value: 100 },
|
||||
{ name: :repository_storages_weighted_storage_1, label: 'storage_1', value: 50 },
|
||||
{ name: :repository_storages_weighted_storage_2, label: 'storage_2', value: 0 }
|
||||
])
|
||||
expect(helper.storage_weights).to eq(OpenStruct.new(
|
||||
default: 100,
|
||||
storage_1: 50,
|
||||
storage_2: 0
|
||||
))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,17 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do
|
|||
subject { cache.key }
|
||||
|
||||
it 'returns cache key' do
|
||||
is_expected.to start_with("highlighted-diff-files:#{cache.diffable.cache_key}:2")
|
||||
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:true")
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(introduce_marker_ranges: false)
|
||||
end
|
||||
|
||||
it 'returns the original version of the cache' do
|
||||
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:false")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,11 +50,23 @@ RSpec.describe Gitlab::Diff::Highlight do
|
|||
end
|
||||
|
||||
it 'highlights and marks added lines' do
|
||||
code = %Q{+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
|
||||
code = %Q{+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left addition">RuntimeError</span></span><span class="p"><span class="idiff addition">,</span></span><span class="idiff right addition"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
end
|
||||
|
||||
context 'when introduce_marker_ranges is false' do
|
||||
before do
|
||||
stub_feature_flags(introduce_marker_ranges: false)
|
||||
end
|
||||
|
||||
it 'keeps the old bevavior (without mode classes)' do
|
||||
code = %Q{+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no diff_refs' do
|
||||
before do
|
||||
allow(diff_file).to receive(:diff_refs).and_return(nil)
|
||||
|
|
@ -93,7 +105,7 @@ RSpec.describe Gitlab::Diff::Highlight do
|
|||
end
|
||||
|
||||
it 'marks added lines' do
|
||||
code = %q{+ raise <span class="idiff left right">RuntimeError, </span>"System commands must be given as an array of strings"}
|
||||
code = %q{+ raise <span class="idiff left right addition">RuntimeError, </span>"System commands must be given as an array of strings"}
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
expect(subject[5].rich_text).to be_html_safe
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::Diff::InlineDiffMarkdownMarker do
|
||||
describe '#mark' do
|
||||
let(:raw) { "abc 'def'" }
|
||||
let(:inline_diffs) { [2..5] }
|
||||
let(:subject) { described_class.new(raw).mark(inline_diffs, mode: :deletion) }
|
||||
let(:inline_diffs) { [Gitlab::MarkerRange.new(2, 5, mode: Gitlab::MarkerRange::DELETION)] }
|
||||
let(:subject) { described_class.new(raw).mark(inline_diffs) }
|
||||
|
||||
it 'does not escape html etities and marks the range' do
|
||||
expect(subject).to eq("ab{-c 'd-}ef'")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'fast_spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::MarkerRange do
|
||||
subject(:marker_range) { described_class.new(first, last, mode: mode) }
|
||||
|
||||
let(:first) { 1 }
|
||||
let(:last) { 10 }
|
||||
let(:mode) { nil }
|
||||
|
||||
it { is_expected.to eq(first..last) }
|
||||
|
||||
it 'behaves like a Range' do
|
||||
is_expected.to be_kind_of(Range)
|
||||
end
|
||||
|
||||
describe '#mode' do
|
||||
subject { marker_range.mode }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
|
||||
context 'when mode is provided' do
|
||||
let(:mode) { :deletion }
|
||||
|
||||
it { is_expected.to eq(mode) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_range' do
|
||||
subject { marker_range.to_range }
|
||||
|
||||
it { is_expected.to eq(first..last) }
|
||||
|
||||
context 'when mode is provided' do
|
||||
let(:mode) { :deletion }
|
||||
|
||||
it 'is omitted during transformation' do
|
||||
is_expected.not_to respond_to(:mode)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.from_range' do
|
||||
subject { described_class.from_range(range) }
|
||||
|
||||
let(:range) { 1..3 }
|
||||
|
||||
it 'converts Range to MarkerRange object' do
|
||||
is_expected.to be_a(described_class)
|
||||
end
|
||||
|
||||
it 'keeps correct range' do
|
||||
is_expected.to eq(range)
|
||||
end
|
||||
|
||||
context 'when range excludes end' do
|
||||
let(:range) { 1...3 }
|
||||
|
||||
it 'keeps correct range' do
|
||||
is_expected.to eq(range)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when range is already a MarkerRange' do
|
||||
let(:range) { marker_range }
|
||||
|
||||
it { is_expected.to be(marker_range) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -8,7 +8,7 @@ RSpec.describe Gitlab::StringRangeMarker do
|
|||
raw = 'abc <def>'
|
||||
inline_diffs = [2..5]
|
||||
|
||||
described_class.new(raw, rich).mark(inline_diffs) do |text, left:, right:|
|
||||
described_class.new(raw, rich).mark(inline_diffs) do |text, left:, right:, mode:|
|
||||
"LEFT#{text}RIGHT".html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ RSpec.describe Gitlab::StringRegexMarker do
|
|||
let(:rich) { %{<span class="key">"name"</span><span class="punctuation">: </span><span class="value">"AFNetworking"</span>}.html_safe }
|
||||
|
||||
subject do
|
||||
described_class.new(raw, rich).mark(/"[^"]+":\s*"(?<name>[^"]+)"/, group: :name) do |text, left:, right:|
|
||||
described_class.new(raw, rich).mark(/"[^"]+":\s*"(?<name>[^"]+)"/, group: :name) do |text, left:, right:, mode:|
|
||||
%{<a href="#">#{text}</a>}.html_safe
|
||||
end
|
||||
end
|
||||
|
|
@ -25,7 +25,7 @@ RSpec.describe Gitlab::StringRegexMarker do
|
|||
let(:rich) { %{a <b> <c> d}.html_safe }
|
||||
|
||||
subject do
|
||||
described_class.new(raw, rich).mark(/<[a-z]>/) do |text, left:, right:|
|
||||
described_class.new(raw, rich).mark(/<[a-z]>/) do |text, left:, right:, mode:|
|
||||
%{<strong>#{text}</strong>}.html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -105,14 +105,14 @@ RSpec.describe ApplicationSetting do
|
|||
|
||||
it { is_expected.not_to allow_value(false).for(:hashed_storage_enabled) }
|
||||
|
||||
it { is_expected.not_to allow_value(101).for(:repository_storages_weighted_default) }
|
||||
it { is_expected.to allow_value('90').for(:repository_storages_weighted_default) }
|
||||
it { is_expected.not_to allow_value(-1).for(:repository_storages_weighted_default) }
|
||||
it { is_expected.to allow_value(100).for(:repository_storages_weighted_default) }
|
||||
it { is_expected.to allow_value(0).for(:repository_storages_weighted_default) }
|
||||
it { is_expected.to allow_value(50).for(:repository_storages_weighted_default) }
|
||||
it { is_expected.to allow_value(nil).for(:repository_storages_weighted_default) }
|
||||
it { is_expected.not_to allow_value({ default: 100, shouldntexist: 50 }).for(:repository_storages_weighted) }
|
||||
it { is_expected.to allow_value('default' => 0).for(:repository_storages_weighted) }
|
||||
it { is_expected.to allow_value('default' => 50).for(:repository_storages_weighted) }
|
||||
it { is_expected.to allow_value('default' => 100).for(:repository_storages_weighted) }
|
||||
it { is_expected.to allow_value('default' => '90').for(:repository_storages_weighted) }
|
||||
it { is_expected.to allow_value('default' => nil).for(:repository_storages_weighted) }
|
||||
it { is_expected.not_to allow_value('default' => -1).for(:repository_storages_weighted).with_message("value for 'default' must be between 0 and 100") }
|
||||
it { is_expected.not_to allow_value('default' => 101).for(:repository_storages_weighted).with_message("value for 'default' must be between 0 and 100") }
|
||||
it { is_expected.not_to allow_value('default' => 100, shouldntexist: 50).for(:repository_storages_weighted).with_message("can't include: shouldntexist") }
|
||||
|
||||
it { is_expected.to allow_value(400).for(:notes_create_limit) }
|
||||
it { is_expected.not_to allow_value('two').for(:notes_create_limit) }
|
||||
|
|
@ -984,12 +984,6 @@ RSpec.describe ApplicationSetting do
|
|||
|
||||
it_behaves_like 'application settings examples'
|
||||
|
||||
describe 'repository_storages_weighted_attributes' do
|
||||
it 'returns the keys for repository_storages_weighted' do
|
||||
expect(subject.class.repository_storages_weighted_attributes).to eq([:repository_storages_weighted_default])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'kroki_format_supported?' do
|
||||
it 'returns true when Excalidraw is enabled' do
|
||||
subject.kroki_formats_excalidraw = true
|
||||
|
|
@ -1033,11 +1027,4 @@ RSpec.describe ApplicationSetting do
|
|||
expect(subject.kroki_formats_excalidraw).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not allow to set weight for non existing storage' do
|
||||
setting.repository_storages_weighted = { invalid_storage: 100 }
|
||||
|
||||
expect(setting).not_to be_valid
|
||||
expect(setting.errors.messages[:repository_storages_weighted]).to match_array(["can't include: invalid_storage"])
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ RSpec.shared_examples 'application settings examples' do
|
|||
|
||||
describe '#pick_repository_storage' do
|
||||
before do
|
||||
allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(%w(default backup))
|
||||
allow(setting).to receive(:repository_storages_weighted).and_return({ 'default' => 20, 'backup' => 80 })
|
||||
end
|
||||
|
||||
|
|
@ -304,15 +305,19 @@ RSpec.shared_examples 'application settings examples' do
|
|||
describe '#normalized_repository_storage_weights' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:storages, :normalized) do
|
||||
{ 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 }
|
||||
{ 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 }
|
||||
{ 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 }
|
||||
{ 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 }
|
||||
where(:config_storages, :storages, :normalized) do
|
||||
%w(default backup) | { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 }
|
||||
%w(default backup) | { 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 }
|
||||
%w(default backup) | { 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 }
|
||||
%w(default backup) | { 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 }
|
||||
%w(default) | { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0 }
|
||||
%w(default) | { 'default' => 100, 'backup' => 100 } | { 'default' => 1.0 }
|
||||
%w(default) | { 'default' => 20, 'backup' => 80 } | { 'default' => 1.0 }
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(config_storages)
|
||||
allow(setting).to receive(:repository_storages_weighted).and_return(storages)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,34 +3,49 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'admin/application_settings/_repository_storage.html.haml' do
|
||||
let(:app_settings) { create(:application_setting) }
|
||||
let(:repository_storages_weighted_attributes) { [:repository_storages_weighted_default, :repository_storages_weighted_mepmep, :repository_storages_weighted_foobar]}
|
||||
let(:repository_storages_weighted) do
|
||||
{
|
||||
"default" => 100,
|
||||
"mepmep" => 50
|
||||
}
|
||||
end
|
||||
let(:app_settings) { build(:application_setting, repository_storages_weighted: repository_storages_weighted) }
|
||||
|
||||
before do
|
||||
allow(app_settings).to receive(:repository_storages_weighted).and_return(repository_storages_weighted)
|
||||
allow(app_settings).to receive(:repository_storages_weighted_mepmep).and_return(100)
|
||||
allow(app_settings).to receive(:repository_storages_weighted_foobar).and_return(50)
|
||||
stub_storage_settings({ 'default': {}, 'mepmep': {}, 'foobar': {} })
|
||||
assign(:application_setting, app_settings)
|
||||
allow(ApplicationSetting).to receive(:repository_storages_weighted_attributes).and_return(repository_storages_weighted_attributes)
|
||||
end
|
||||
|
||||
context 'when multiple storages are available' do
|
||||
context 'additional storage config' do
|
||||
let(:repository_storages_weighted) do
|
||||
{
|
||||
'default' => 100,
|
||||
'mepmep' => 50
|
||||
}
|
||||
end
|
||||
|
||||
it 'lists them all' do
|
||||
render
|
||||
|
||||
# lists storages that are saved with weights
|
||||
repository_storages_weighted.each do |storage_name, storage_weight|
|
||||
Gitlab.config.repositories.storages.keys.each do |storage_name|
|
||||
expect(rendered).to have_content(storage_name)
|
||||
end
|
||||
|
||||
# lists storage not saved with weight
|
||||
expect(rendered).to have_content('foobar')
|
||||
end
|
||||
end
|
||||
|
||||
context 'fewer storage configs' do
|
||||
let(:repository_storages_weighted) do
|
||||
{
|
||||
'default' => 100,
|
||||
'mepmep' => 50,
|
||||
'something_old' => 100
|
||||
}
|
||||
end
|
||||
|
||||
it 'lists only configured storages' do
|
||||
render
|
||||
|
||||
Gitlab.config.repositories.storages.keys.each do |storage_name|
|
||||
expect(rendered).to have_content(storage_name)
|
||||
end
|
||||
|
||||
expect(rendered).not_to have_content('something_old')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue