Commit 3e49ae15 authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 77d49e6a
<script>
import { GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import createFlash from '~/flash';
import uploadDesignMutation from '../../graphql/mutations/upload_design.mutation.graphql';
import { UPLOAD_DESIGN_INVALID_FILETYPE_ERROR } from '../../utils/error_messages';
import { isValidDesignFile } from '../../utils/design_management_utils';
......@@ -56,7 +56,7 @@ export default {
const { files } = dataTransfer;
if (!this.isValidUpload(Array.from(files))) {
createFlash(UPLOAD_DESIGN_INVALID_FILETYPE_ERROR);
createFlash({ message: UPLOAD_DESIGN_INVALID_FILETYPE_ERROR });
return;
}
......
import { propertyOf } from 'lodash';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import createFlash, { FLASH_TYPES } from '~/flash';
import { s__ } from '~/locale';
import getDesignListQuery from '../graphql/queries/get_design_list.query.graphql';
import allVersionsMixin from './all_versions';
......@@ -36,20 +36,20 @@ export default {
},
result() {
if (this.$route.query.version && !this.hasValidVersion) {
createFlash(
s__(
createFlash({
message: s__(
'DesignManagement|Requested design version does not exist. Showing latest version instead',
),
);
});
this.$router.replace({ name: DESIGNS_ROUTE_NAME, query: { version: undefined } });
}
if (this.designCollection.copyState === 'ERROR') {
createFlash(
s__(
createFlash({
message: s__(
'DesignManagement|There was an error moving your designs. Please upload your designs below.',
),
'warning',
);
type: FLASH_TYPES.WARNING,
});
}
},
},
......
......@@ -2,7 +2,7 @@
import Mousetrap from 'mousetrap';
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import { ApolloMutation } from 'vue-apollo';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import createFlash from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import allVersionsMixin from '../../mixins/all_versions';
import Toolbar from '../../components/toolbar/index.vue';
......@@ -230,7 +230,7 @@ export default {
onQueryError(message) {
// because we redirect user to /designs (the issue page),
// we want to create these flashes on the issue page
createFlash(message);
createFlash({ message });
this.$router.push({ name: this.$options.DESIGNS_ROUTE_NAME });
},
onError(message, e) {
......
<script>
import { GlLoadingIcon, GlButton, GlAlert } from '@gitlab/ui';
import VueDraggable from 'vuedraggable';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import createFlash, { FLASH_TYPES } from '~/flash';
import { s__, sprintf } from '~/locale';
import { getFilename } from '~/lib/utils/file_upload';
import UploadButton from '../components/upload/button.vue';
......@@ -139,8 +139,8 @@ export default {
if (!this.canCreateDesign) return false;
if (files.length > MAXIMUM_FILE_UPLOAD_LIMIT) {
createFlash(
sprintf(
createFlash({
message: sprintf(
s__(
'DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again.',
),
......@@ -148,7 +148,7 @@ export default {
upload_limit: MAXIMUM_FILE_UPLOAD_LIMIT,
},
),
);
});
return false;
}
......@@ -191,7 +191,7 @@ export default {
const skippedFiles = res?.data?.designManagementUpload?.skippedDesigns || [];
const skippedWarningMessage = designUploadSkippedWarning(this.filesToBeSaved, skippedFiles);
if (skippedWarningMessage) {
createFlash(skippedWarningMessage, 'warning');
createFlash({ message: skippedWarningMessage, types: FLASH_TYPES.WARNING });
}
// if this upload resulted in a new version being created, redirect user to the latest version
......@@ -214,7 +214,7 @@ export default {
},
onUploadDesignError() {
this.resetFilesToBeSaved();
createFlash(UPLOAD_DESIGN_ERROR);
createFlash({ message: UPLOAD_DESIGN_ERROR });
},
changeSelectedDesigns(filename) {
if (this.isDesignSelected(filename)) {
......@@ -245,18 +245,18 @@ export default {
},
onDesignDeleteError() {
const errorMessage = designDeletionError({ singular: this.selectedDesigns.length === 1 });
createFlash(errorMessage);
createFlash({ message: errorMessage });
},
onExistingDesignDropzoneChange(files, existingDesignFilename) {
const filesArr = Array.from(files);
if (filesArr.length > 1) {
createFlash(EXISTING_DESIGN_DROP_MANY_FILES_MESSAGE);
createFlash({ message: EXISTING_DESIGN_DROP_MANY_FILES_MESSAGE });
return;
}
if (!filesArr.some(({ name }) => existingDesignFilename === name)) {
createFlash(EXISTING_DESIGN_DROP_INVALID_FILENAME_MESSAGE);
createFlash({ message: EXISTING_DESIGN_DROP_INVALID_FILENAME_MESSAGE });
return;
}
......@@ -307,7 +307,7 @@ export default {
optimisticResponse: moveDesignOptimisticResponse(this.reorderedDesigns),
})
.catch(() => {
createFlash(MOVE_DESIGN_ERROR);
createFlash({ message: MOVE_DESIGN_ERROR });
})
.finally(() => {
this.isReorderingInProgress = false;
......
......@@ -2,7 +2,7 @@
import { differenceBy } from 'lodash';
import produce from 'immer';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import createFlash from '~/flash';
import { extractCurrentDiscussion, extractDesign, extractDesigns } from './design_management_utils';
import {
ADD_IMAGE_DIFF_NOTE_ERROR,
......@@ -237,7 +237,7 @@ export const deletePendingTodoFromStore = (store, todoMarkDone, query, queryVari
};
const onError = (data, message) => {
createFlash(message);
createFlash({ message });
throw new Error(data.errors);
};
......@@ -286,7 +286,7 @@ export const updateStoreAfterUploadDesign = (store, data, query) => {
export const updateDesignsOnStoreAfterReorder = (store, data, query) => {
if (hasErrors(data)) {
createFlash(data.errors[0]);
createFlash({ message: data.errors[0] });
} else {
moveDesignInStore(store, data, query);
}
......
<script>
import { GlFormGroup, GlDeprecatedDropdown, GlDeprecatedDropdownItem } from '@gitlab/ui';
import { GlFormGroup, GlDropdown, GlDropdownItem } from '@gitlab/ui';
export default {
components: {
GlFormGroup,
GlDeprecatedDropdown,
GlDeprecatedDropdownItem,
GlDropdown,
GlDropdownItem,
},
props: {
name: {
......@@ -41,16 +41,13 @@ export default {
</script>
<template>
<gl-form-group :label="label">
<gl-deprecated-dropdown
toggle-class="dropdown-menu-toggle"
:text="text || s__('Metrics|Select a value')"
>
<gl-deprecated-dropdown-item
<gl-dropdown toggle-class="dropdown-menu-toggle" :text="text || s__('Metrics|Select a value')">
<gl-dropdown-item
v-for="val in options.values"
:key="val.value"
@click="onUpdate(val.value)"
>{{ val.text }}</gl-deprecated-dropdown-item
>{{ val.text }}</gl-dropdown-item
>
</gl-deprecated-dropdown>
</gl-dropdown>
</gl-form-group>
</template>
import $ from 'jquery';
import setHighlightClass from 'ee_else_ce/search/highlight_blob_search_result';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import { deprecatedCreateFlash as Flash } from '~/flash';
import Api from '~/api';
......@@ -6,7 +7,6 @@ import { __ } from '~/locale';
import Project from '~/pages/projects/project';
import { visitUrl } from '~/lib/utils/url_utility';
import refreshCounts from './refresh_counts';
import setHighlightClass from './highlight_blob_search_result';
export default class Search {
constructor() {
......
<script>
/* eslint-disable vue/no-v-html */
import { groupBy } from 'lodash';
import { GlIcon, GlLoadingIcon } from '@gitlab/ui';
import tooltip from '~/vue_shared/directives/tooltip';
import { GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import { glEmojiTag } from '../../emoji';
import { __, sprintf } from '~/locale';
......@@ -15,7 +14,7 @@ export default {
GlLoadingIcon,
},
directives: {
tooltip,
GlTooltip: GlTooltipDirective,
},
props: {
awards: {
......@@ -154,10 +153,9 @@ export default {
<button
v-for="awardList in groupedAwards"
:key="awardList.name"
v-tooltip
v-gl-tooltip.viewport
:class="awardList.classes"
:title="awardList.title"
data-boundary="viewport"
data-testid="award-button"
class="btn award-control"
type="button"
......@@ -168,12 +166,11 @@ export default {
</button>
<div v-if="canAwardEmoji" class="award-menu-holder">
<button
v-tooltip
v-gl-tooltip.viewport
:class="addButtonClass"
class="award-control btn js-add-award"
title="Add reaction"
:aria-label="__('Add reaction')"
data-boundary="viewport"
type="button"
>
<span class="award-control-icon award-control-icon-neutral">
......
......@@ -38,11 +38,7 @@ class Measurement < ApplicationRecord
scope :with_identifier, -> (identifier) { where(identifier: identifier) }
def self.measurement_identifier_values
if Feature.enabled?(:store_ci_pipeline_counts_by_status, default_enabled: true)
identifiers.values
else
identifiers.values - EXPERIMENTAL_IDENTIFIERS.map { |identifier| identifiers[identifier] }
end
identifiers.values
end
end
end
......
......@@ -45,6 +45,10 @@ def persistable_store
def get_store_class(store)
@stores ||= {}
# Can't memoize this because the feature flag may alter this
return fog_store_class.new if store.to_sym == :fog
@stores[store] ||= "Ci::BuildTraceChunks::#{store.capitalize}".constantize.new
end
......@@ -74,6 +78,14 @@ def finalize_fast_destroy(keys)
def metadata_attributes
attribute_names - %w[raw_data]
end
def fog_store_class
if Feature.enabled?(:ci_trace_new_fog_store)
Ci::BuildTraceChunks::Fog
else
Ci::BuildTraceChunks::LegacyFog
end
end
end
def data
......
......@@ -8,13 +8,17 @@ def available?
end
def data(model)
connection.get_object(bucket_name, key(model))[:body]
files.get(key(model))&.body
rescue Excon::Error::NotFound
# If the object does not exist in the object storage, this method returns nil.
end
def set_data(model, new_data)
connection.put_object(bucket_name, key(model), new_data)
# TODO: Support AWS S3 server side encryption
files.create({
key: key(model),
body: new_data
})
end
def append_data(model, new_data, offset)
......@@ -43,7 +47,7 @@ def keys(relation)
def delete_keys(keys)
keys.each do |key|
connection.delete_object(bucket_name, key_raw(*key))
files.destroy(key_raw(*key))
end
end
......@@ -69,6 +73,14 @@ def connection
@connection ||= ::Fog::Storage.new(object_store.connection.to_hash.deep_symbolize_keys)
end
def fog_directory
@fog_directory ||= connection.directories.new(key: bucket_name)
end
def files
@files ||= fog_directory.files
end
def object_store
Gitlab.config.artifacts.object_store
end
......
# frozen_string_literal: true
module Ci
module BuildTraceChunks
class LegacyFog
def available?
object_store.enabled
end
def data(model)
connection.get_object(bucket_name, key(model))[:body]
rescue Excon::Error::NotFound
# If the object does not exist in the object storage, this method returns nil.
end
def set_data(model, new_data)
connection.put_object(bucket_name, key(model), new_data)
end
def append_data(model, new_data, offset)
if offset > 0
truncated_data = data(model).to_s.byteslice(0, offset)
new_data = truncated_data + new_data
end
set_data(model, new_data)
new_data.bytesize
end
def size(model)
data(model).to_s.bytesize
end
def delete_data(model)
delete_keys([[model.build_id, model.chunk_index]])
end
def keys(relation)
return [] unless available?
relation.pluck(:build_id, :chunk_index)
end
def delete_keys(keys)
keys.each do |key|
connection.delete_object(bucket_name, key_raw(*key))
end
end
private
def key(model)
key_raw(model.build_id, model.chunk_index)
end
def key_raw(build_id, chunk_index)
"tmp/builds/#{build_id.to_i}/chunks/#{chunk_index.to_i}.log"
end
def bucket_name
return unless available?
object_store.remote_directory
end
def connection
return unless available?
@connection ||= ::Fog::Storage.new(object_store.connection.to_hash.deep_symbolize_keys)
end
def object_store
Gitlab.config.artifacts.object_store
end
end
end
end
......@@ -16,8 +16,8 @@ def log_error(message, params = {})
def build_message(message, params = {})
{
service_class: self.class.name,
project_id: project.id,
project_path: project.full_path,
project_id: project&.id,
project_path: project&.full_path,
message: message
}.merge(params)
end
......
......@@ -6,7 +6,7 @@
- if verification_enabled && domain_presenter.unverified?
= content_for :flash_message do
.alert.alert-warning
.gl-alert.gl-alert-warning
.container-fluid.container-limited
= _("This domain is not verified. You will need to verify ownership before access is enabled.")
......
......@@ -7,4 +7,4 @@
= search_blob_title(project, path)
- if blob.data
.file-content.code.term{ data: { qa_selector: 'file_text_content' } }
= render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link
= render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, highlight_line: blob.highlight_line
#blob-content.file-content.code.js-syntax-highlight
- offset = defined?(first_line_number) ? first_line_number : 1
.line-numbers
- if blob.data.present?
- link_icon = sprite_icon('link', size: 12)
- link = blob_link if defined?(blob_link)
- blob.data.each_line.each_with_index do |_, index|
- offset = defined?(first_line_number) ? first_line_number : 1
- i = index + offset
-# We're not using `link_to` because it is too slow once we get to thousands of lines.
%a.diff-line-num{ href: "#{link}#L#{i}", id: "L#{i}", 'data-line-number' => i }
= link_icon
= i
.blob-content{ data: { blob_id: blob.id, path: blob.path } }
- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
.blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight } }
%pre.code.highlight
%code
= blob.present.highlight
---
title: Fix exception when saving Jira integration info for an instance
merge_request: 45718
author:
type: fixed
---
title: Allow user snippets to be indexed by search crawlers
merge_request: 45793
author:
type: changed
---
title: Replace-GlDeprecatedDropdown-with-GlDropdown-in-app/assets/javascripts/monitoring
merge_request: 41422
author: nuwe1
type: other
---
title: Download LFS files when importing from Bitbucket Server
merge_request: 45908
author:
type: fixed
---
title: Migrate tooltip in app/assets/javascripts/vue_shared/components/awards_list.vue
merge_request: 46171
author:
type: other
---
name: store_ci_pipeline_counts_by_status
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43027
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/254721
name: ci_trace_new_fog_store
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46209
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273405
type: development
group: group::analytics
default_enabled: true
group: group::testing
default_enabled: false
......@@ -2,7 +2,7 @@
PRODUCT_ANALYTICS_CHANGED_FILES_MESSAGE = <<~MSG
For the following files, a review from the [Data team and Product Analytics team](https://gitlab.com/groups/gitlab-org/growth/product_analytics/engineers/-/group_members?with_inherited_permissions=exclude) is recommended
Please check the ~"product analytics(telemetry)" [guide](https://docs.gitlab.com/ee/development/product_analytics/usage_ping.html) and reach out to %<product_analytics_engineers_group>s group for a review.
Please check the ~"product analytics" [guide](https://docs.gitlab.com/ee/development/product_analytics/usage_ping.html) and reach out to %<product_analytics_engineers_group>s group for a review.
%<changed_files>s
......@@ -41,8 +41,8 @@ if changed_files.any?
warn format(PRODUCT_ANALYTICS_CHANGED_FILES_MESSAGE, changed_files: helper.markdown_list(changed_files), product_analytics_engineers_group: mention)
warn format(UPDATE_METRICS_DEFINITIONS_MESSAGE) unless helper.changed_files(/usage_ping\.md/).any?
product_analytics_labels = ['product analytics(telemetry)']
product_analytics_labels << 'product analytics(telemetry)::review pending' unless helper.mr_has_labels?('product analytics(telemetry)::reviewed')
product_analytics_labels = ['product analytics']
product_analytics_labels << 'product analytics::review pending' unless helper.mr_has_labels?('product analytics::reviewed')
markdown(helper.prepare_labels_for_mr(product_analytics_labels))
end
......@@ -14,5 +14,5 @@ link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#alert
level: error
scope: raw
raw:
- '((NOTE|TIP|CAUTION|DANGER): \*\*.*\*\*.+)|'
- '(\n(NOTE|TIP|CAUTION|DANGER): \*\*.*\*\*.+)|'
- '((\n[> ]*(\*){1,2}(NOTE|Note|note|TIP|Tip|tip|CAUTION|Caution|caution|DANGER|Danger|danger):(\*){1,2}))'
......@@ -5,9 +5,10 @@
#
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: substitution