Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-03-10 18:09:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-03-10 18:09:11 +0300
commitd2091d1e924e2887eb9db4fad761965a24d024f1 (patch)
tree482fe37d97a4169895ae3ddf6d6f42e6f632cbb9 /app
parent152b3268d701b54cac9b615a0e29e0e5726bfd99 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/access_tokens/components/projects_token_selector.vue14
-rw-r--r--app/assets/javascripts/experimentation/constants.js1
-rw-r--r--app/assets/javascripts/experimentation/experiment_tracking.js (renamed from app/assets/javascripts/experiment_tracking.js)11
-rw-r--r--app/assets/javascripts/experimentation/utils.js10
-rw-r--r--app/assets/javascripts/graphql_shared/utils.js34
-rw-r--r--app/assets/javascripts/lib/utils/experimentation.js3
-rw-r--r--app/assets/javascripts/projects/upload_file_experiment.js2
-rw-r--r--app/assets/javascripts/tracking.js8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue36
-rw-r--r--app/experiments/application_experiment.rb10
-rw-r--r--app/models/merge_request.rb30
-rw-r--r--app/models/project.rb18
-rw-r--r--app/models/project_services/discord_service.rb3
-rw-r--r--app/workers/all_queues.yml12
-rw-r--r--app/workers/archive_trace_worker.rb2
-rw-r--r--app/workers/build_finished_worker.rb1
-rw-r--r--app/workers/chat_notification_worker.rb1
-rw-r--r--app/workers/expire_build_instance_artifacts_worker.rb1
18 files changed, 133 insertions, 64 deletions
diff --git a/app/assets/javascripts/access_tokens/components/projects_token_selector.vue b/app/assets/javascripts/access_tokens/components/projects_token_selector.vue
index 37ef3f28236..cc5532696c7 100644
--- a/app/assets/javascripts/access_tokens/components/projects_token_selector.vue
+++ b/app/assets/javascripts/access_tokens/components/projects_token_selector.vue
@@ -8,7 +8,7 @@ import {
} from '@gitlab/ui';
import produce from 'immer';
-import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils';
+import { convertToGraphQLIds, convertNodeIdsFromGraphQLIds } from '~/graphql_shared/utils';
import getProjectsQuery from '../graphql/queries/get_projects.query.graphql';
@@ -51,7 +51,7 @@ export default {
},
update({ projects }) {
return {
- list: this.formatProjectNodes(projects),
+ list: convertNodeIdsFromGraphQLIds(projects.nodes),
pageInfo: projects.pageInfo,
};
},
@@ -64,7 +64,7 @@ export default {
query: getProjectsQuery,
variables() {
return {
- ids: this.initialProjectIds.map((id) => convertToGraphQLId(GRAPHQL_ENTITY_TYPE, id)),
+ ids: convertToGraphQLIds(GRAPHQL_ENTITY_TYPE, this.initialProjectIds),
};
},
manual: true,
@@ -72,7 +72,7 @@ export default {
return !this.initialProjectIds.length;
},
result({ data: { projects } }) {
- this.$emit('input', this.formatProjectNodes(projects));
+ this.$emit('input', convertNodeIdsFromGraphQLIds(projects.nodes));
},
},
},
@@ -88,12 +88,6 @@ export default {
};
},
methods: {
- formatProjectNodes(projects) {
- return projects.nodes.map((project) => ({
- ...project,
- id: getIdFromGraphQLId(project.id),
- }));
- },
handleSearch(query) {
this.isSearching = true;
this.searchQuery = query;
diff --git a/app/assets/javascripts/experimentation/constants.js b/app/assets/javascripts/experimentation/constants.js
new file mode 100644
index 00000000000..b7e61d43b11
--- /dev/null
+++ b/app/assets/javascripts/experimentation/constants.js
@@ -0,0 +1 @@
+export const TRACKING_CONTEXT_SCHEMA = 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0';
diff --git a/app/assets/javascripts/experiment_tracking.js b/app/assets/javascripts/experimentation/experiment_tracking.js
index 2a725886679..c721828036e 100644
--- a/app/assets/javascripts/experiment_tracking.js
+++ b/app/assets/javascripts/experimentation/experiment_tracking.js
@@ -1,16 +1,15 @@
-import { get } from 'lodash';
import Tracking from '~/tracking';
-
-const TRACKING_CONTEXT_SCHEMA = 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0';
+import { TRACKING_CONTEXT_SCHEMA } from './constants';
+import { getExperimentData } from './utils';
export default class ExperimentTracking {
constructor(experimentName, trackingArgs = {}) {
this.trackingArgs = trackingArgs;
- this.experimentData = get(window, ['gon', 'global', 'experiment', experimentName]);
+ this.data = getExperimentData(experimentName);
}
event(action) {
- if (!this.experimentData) {
+ if (!this.data) {
return false;
}
@@ -18,7 +17,7 @@ export default class ExperimentTracking {
...this.trackingArgs,
context: {
schema: TRACKING_CONTEXT_SCHEMA,
- data: this.experimentData,
+ data: this.data,
},
});
}
diff --git a/app/assets/javascripts/experimentation/utils.js b/app/assets/javascripts/experimentation/utils.js
new file mode 100644
index 00000000000..d3e7800f643
--- /dev/null
+++ b/app/assets/javascripts/experimentation/utils.js
@@ -0,0 +1,10 @@
+// This file only applies to use of experiments through https://gitlab.com/gitlab-org/gitlab-experiment
+import { get } from 'lodash';
+
+export function getExperimentData(experimentName) {
+ return get(window, ['gon', 'experiment', experimentName]);
+}
+
+export function isExperimentVariant(experimentName, variantName) {
+ return getExperimentData(experimentName)?.variant === variantName;
+}
diff --git a/app/assets/javascripts/graphql_shared/utils.js b/app/assets/javascripts/graphql_shared/utils.js
index 4715bbc94f6..e64e8009a5f 100644
--- a/app/assets/javascripts/graphql_shared/utils.js
+++ b/app/assets/javascripts/graphql_shared/utils.js
@@ -1,3 +1,5 @@
+import { isArray } from 'lodash';
+
/**
* Ids generated by GraphQL endpoints are usually in the format
* gid://gitlab/Environments/123. This method extracts Id number
@@ -52,3 +54,35 @@ export const convertToGraphQLId = (type, id) => {
* @returns {Array}
*/
export const convertToGraphQLIds = (type, ids) => ids.map((id) => convertToGraphQLId(type, id));
+
+/**
+ * Ids generated by GraphQL endpoints are usually in the format
+ * gid://gitlab/Groups/123. This method takes an array of
+ * GraphQL Ids and converts them to a number.
+ *
+ * @param {Array} ids An array of GraphQL IDs
+ * @returns {Array}
+ */
+export const convertFromGraphQLIds = (ids) => {
+ if (!isArray(ids)) {
+ throw new TypeError(`ids must be an array; got ${typeof ids}`);
+ }
+
+ return ids.map((id) => getIdFromGraphQLId(id));
+};
+
+/**
+ * Ids generated by GraphQL endpoints are usually in the format
+ * gid://gitlab/Groups/123. This method takes an array of nodes
+ * and converts the `id` properties from a GraphQL Id to a number.
+ *
+ * @param {Array} nodes An array of nodes with an `id` property
+ * @returns {Array}
+ */
+export const convertNodeIdsFromGraphQLIds = (nodes) => {
+ if (!isArray(nodes)) {
+ throw new TypeError(`nodes must be an array; got ${typeof nodes}`);
+ }
+
+ return nodes.map((node) => (node.id ? { ...node, id: getIdFromGraphQLId(node.id) } : node));
+};
diff --git a/app/assets/javascripts/lib/utils/experimentation.js b/app/assets/javascripts/lib/utils/experimentation.js
deleted file mode 100644
index 555e76055e0..00000000000
--- a/app/assets/javascripts/lib/utils/experimentation.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export function isExperimentEnabled(experimentKey) {
- return Boolean(window.gon?.experiments?.[experimentKey]);
-}
diff --git a/app/assets/javascripts/projects/upload_file_experiment.js b/app/assets/javascripts/projects/upload_file_experiment.js
index e4e4c609f0a..7d61df36a75 100644
--- a/app/assets/javascripts/projects/upload_file_experiment.js
+++ b/app/assets/javascripts/projects/upload_file_experiment.js
@@ -1,4 +1,4 @@
-import ExperimentTracking from '~/experiment_tracking';
+import ExperimentTracking from '~/experimentation/experiment_tracking';
function trackEvent(eventName) {
const isEmpty = Boolean(document.querySelector('.project-home-panel.empty-project'));
diff --git a/app/assets/javascripts/tracking.js b/app/assets/javascripts/tracking.js
index 008eda5e505..01de034417e 100644
--- a/app/assets/javascripts/tracking.js
+++ b/app/assets/javascripts/tracking.js
@@ -1,4 +1,6 @@
-import { omitBy, isUndefined, get } from 'lodash';
+import { omitBy, isUndefined } from 'lodash';
+import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
+import { getExperimentData } from '~/experimentation/utils';
const standardContext = { ...window.gl?.snowplowStandardContext };
@@ -32,8 +34,8 @@ const createEventPayload = (el, { suffix = '' } = {}) => {
let context = el.dataset.trackContext;
if (el.dataset.trackExperiment) {
- const data = get(window, ['gon', 'global', 'experiment', el.dataset.trackExperiment]);
- if (data) context = { schema: 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0', data };
+ const data = getExperimentData(el.dataset.trackExperiment);
+ if (data) context = { schema: TRACKING_CONTEXT_SCHEMA, data };
}
const data = {
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
index f0259a975db..01e0b91bd4a 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
@@ -1,12 +1,15 @@
<script>
/* eslint-disable vue/no-v-html */
-import { GlButton } from '@gitlab/ui';
+import { GlButton, GlSprintf, GlLink } from '@gitlab/ui';
import emptyStateSVG from 'icons/_mr_widget_empty_state.svg';
+import { helpPagePath } from '~/helpers/help_page_helper';
export default {
name: 'MRWidgetNothingToMerge',
components: {
GlButton,
+ GlSprintf,
+ GlLink,
},
props: {
mr: {
@@ -17,6 +20,7 @@ export default {
data() {
return { emptyStateSVG };
},
+ ciHelpPage: helpPagePath('/ci/quick_start/index.html'),
};
</script>
@@ -30,25 +34,20 @@ export default {
</div>
<div class="text col-md-7 order-md-first col-12">
<p class="highlight">
- {{
- s__(
- 'mrWidgetNothingToMerge|Merge requests are a place to propose changes you have made to a project and discuss those changes with others.',
- )
- }}
+ {{ s__('mrWidgetNothingToMerge|This merge request contains no changes.') }}
</p>
<p>
- {{
- s__(
- 'mrWidgetNothingToMerge|Interested parties can even contribute by pushing commits if they want to.',
- )
- }}
- </p>
- <p>
- {{
- s__(
- "mrWidgetNothingToMerge|Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch.",
- )
- }}
+ <gl-sprintf
+ :message="
+ s__(
+ 'mrWidgetNothingToMerge|Use merge requests to propose changes to your project and discuss them with your team. To make changes, push a commit or edit this merge request to use a different branch. With %{linkStart}CI/CD%{linkEnd}, automatically test your changes before merging.',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="$options.ciHelpPage" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
</p>
<div>
<gl-button
@@ -56,6 +55,7 @@ export default {
:href="mr.newBlobPath"
category="secondary"
variant="success"
+ data-testid="createFileButton"
>
{{ __('Create file') }}
</gl-button>
diff --git a/app/experiments/application_experiment.rb b/app/experiments/application_experiment.rb
index ec73382ed3b..6ba851fbc8b 100644
--- a/app/experiments/application_experiment.rb
+++ b/app/experiments/application_experiment.rb
@@ -11,7 +11,9 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp
def publish(_result)
track(:assignment) # track that we've assigned a variant for this context
- Gon.global.push({ experiment: { name => signature } }, true) # push the experiment data to the client
+
+ # push the experiment data to the client
+ Gon.push({ experiment: { name => signature } }, true) if in_request_cycle?
end
def track(action, **event_args)
@@ -47,6 +49,12 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp
name.tr('/', '_')
end
+ def in_request_cycle?
+ # Gon is only accessible when having a request. This will be fixed with
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/323352
+ context.instance_variable_defined?(:@request)
+ end
+
def resolve_variant_name
case rollout_strategy
when :round_robin
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index ba09c0a9dd8..3fe31a64984 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -310,10 +310,28 @@ class MergeRequest < ApplicationRecord
end
scope :by_target_branch, ->(branch_name) { where(target_branch: branch_name) }
scope :order_merged_at, ->(direction) do
- query = join_metrics.order(Gitlab::Database.nulls_last_order('merge_request_metrics.merged_at', direction))
-
- # Add `merge_request_metrics.merged_at` to the `SELECT` in order to make the keyset pagination work.
- query.select(*query.arel.projections, MergeRequest::Metrics.arel_table[:merged_at].as('"merge_request_metrics.merged_at"'))
+ reverse_direction = { 'ASC' => 'DESC', 'DESC' => 'ASC' }
+ reversed_direction = reverse_direction[direction] || raise("Unknown sort direction was given: #{direction}")
+
+ order = Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'merge_request_metrics_merged_at',
+ column_expression: MergeRequest::Metrics.arel_table[:merged_at],
+ order_expression: Gitlab::Database.nulls_last_order('merge_request_metrics.merged_at', direction),
+ reversed_order_expression: Gitlab::Database.nulls_first_order('merge_request_metrics.merged_at', reversed_direction),
+ order_direction: direction,
+ nullable: :nulls_last,
+ distinct: false,
+ add_to_projections: true
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'merge_request_metrics_id',
+ order_expression: MergeRequest::Metrics.arel_table[:id].desc,
+ add_to_projections: true
+ )
+ ])
+
+ order.apply_cursor_conditions(join_metrics).order(order)
end
scope :order_merged_at_asc, -> { order_merged_at('ASC') }
scope :order_merged_at_desc, -> { order_merged_at('DESC') }
@@ -411,8 +429,8 @@ class MergeRequest < ApplicationRecord
def self.sort_by_attribute(method, excluded_labels: [])
case method.to_s
- when 'merged_at', 'merged_at_asc' then order_merged_at_asc.with_order_id_desc
- when 'merged_at_desc' then order_merged_at_desc.with_order_id_desc
+ when 'merged_at', 'merged_at_asc' then order_merged_at_asc
+ when 'merged_at_desc' then order_merged_at_desc
else
super
end
diff --git a/app/models/project.rb b/app/models/project.rb
index d960732b16f..ef92dda443a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -493,10 +493,22 @@ class Project < ApplicationRecord
{ column: arel_table["description"], multiplier: 0.2 }
])
- query = reorder(order_expression.desc, arel_table['id'].desc)
+ order = Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'similarity',
+ column_expression: order_expression,
+ order_expression: order_expression.desc,
+ order_direction: :desc,
+ distinct: false,
+ add_to_projections: true
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id',
+ order_expression: Project.arel_table[:id].desc
+ )
+ ])
- query = query.select(*query.arel.projections, order_expression.as('similarity')) if include_in_select
- query
+ order.apply_cursor_conditions(reorder(order))
end
scope :with_packages, -> { joins(:packages) }
diff --git a/app/models/project_services/discord_service.rb b/app/models/project_services/discord_service.rb
index 941b7f64263..37bbb9b8752 100644
--- a/app/models/project_services/discord_service.rb
+++ b/app/models/project_services/discord_service.rb
@@ -59,6 +59,9 @@ class DiscordService < ChatNotificationService
embed.description = (message.pretext + "\n" + Array.wrap(message.attachments).join("\n")).gsub(ATTACHMENT_REGEX, " \\k<entry> - \\k<name>\n")
end
end
+ rescue RestClient::Exception => error
+ log_error(error.message)
+ false
end
def custom_data(data)
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 20e1636b2fa..f6ea1828ab6 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1106,8 +1106,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
+ :tags: []
- :name: pipeline_background:ci_build_trace_chunk_flush
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -1251,8 +1250,7 @@
:resource_boundary: :cpu
:weight: 5
:idempotent:
- :tags:
- - :requires_disk_io
+ :tags: []
- :name: pipeline_processing:build_queue
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -1484,8 +1482,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :tags:
- - :requires_disk_io
+ :tags: []
- :name: ci_delete_objects
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -1645,8 +1642,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :tags:
- - :requires_disk_io
+ :tags: []
- :name: export_csv
:feature_category: :issue_tracking
:has_external_dependencies:
diff --git a/app/workers/archive_trace_worker.rb b/app/workers/archive_trace_worker.rb
index b0c5bef336a..3ddb5686bf2 100644
--- a/app/workers/archive_trace_worker.rb
+++ b/app/workers/archive_trace_worker.rb
@@ -4,8 +4,6 @@ class ArchiveTraceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineBackgroundQueue
- tags :requires_disk_io
-
# rubocop: disable CodeReuse/ActiveRecord
def perform(job_id)
Ci::Build.without_archived_trace.find_by(id: job_id).try do |job|
diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb
index 1f4ebe58638..3f99b30fdf7 100644
--- a/app/workers/build_finished_worker.rb
+++ b/app/workers/build_finished_worker.rb
@@ -7,7 +7,6 @@ class BuildFinishedWorker # rubocop:disable Scalability/IdempotentWorker
queue_namespace :pipeline_processing
urgency :high
worker_resource_boundary :cpu
- tags :requires_disk_io
ARCHIVE_TRACES_IN = 2.minutes.freeze
diff --git a/app/workers/chat_notification_worker.rb b/app/workers/chat_notification_worker.rb
index 94a0197b862..5fab437f49f 100644
--- a/app/workers/chat_notification_worker.rb
+++ b/app/workers/chat_notification_worker.rb
@@ -7,7 +7,6 @@ class ChatNotificationWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: false
feature_category :chatops
- tags :requires_disk_io
urgency :low # Can't be high as it has external dependencies
weight 2
worker_has_external_dependencies!
diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb
index a5571473b43..e6cd60a3e47 100644
--- a/app/workers/expire_build_instance_artifacts_worker.rb
+++ b/app/workers/expire_build_instance_artifacts_worker.rb
@@ -4,7 +4,6 @@ class ExpireBuildInstanceArtifactsWorker # rubocop:disable Scalability/Idempoten
include ApplicationWorker
feature_category :continuous_integration
- tags :requires_disk_io
# rubocop: disable CodeReuse/ActiveRecord
def perform(build_id)