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>2022-03-17 18:07:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-17 18:07:44 +0300
commit6c41e447edac3453ae0df99fb9232ec71b679b75 (patch)
tree125416ba49222f7c0deb44950e451e39d45c433b /app
parent77ee26b43bda4b092f356d5185f424bad232af36 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/reports/codequality_report/constants.js14
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue11
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js123
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue13
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js6
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb27
-rw-r--r--app/controllers/jira_connect/events_controller.rb30
-rw-r--r--app/models/project.rb13
-rw-r--r--app/models/user.rb16
-rw-r--r--app/views/admin/groups/_form.html.haml9
-rw-r--r--app/views/dashboard/todos/index.html.haml1
-rw-r--r--app/views/layouts/_page.html.haml1
-rw-r--r--app/views/projects/_deletion_failed.html.haml11
-rw-r--r--app/views/projects/_new_project_fields.html.haml3
-rw-r--r--app/views/shared/_two_factor_auth_recovery_settings_check.html.haml2
15 files changed, 222 insertions, 58 deletions
diff --git a/app/assets/javascripts/reports/codequality_report/constants.js b/app/assets/javascripts/reports/codequality_report/constants.js
index 502977e714c..0c472b24471 100644
--- a/app/assets/javascripts/reports/codequality_report/constants.js
+++ b/app/assets/javascripts/reports/codequality_report/constants.js
@@ -15,3 +15,17 @@ export const SEVERITY_ICONS = {
blocker: 'severity-critical',
unknown: 'severity-unknown',
};
+
+// This is the icons mapping for the code Quality Merge-Request Widget Extension
+// once the refactor_mr_widgets_extensions flag is activated the above SEVERITY_ICONS
+// need be removed and this variable needs to be rename to SEVERITY_ICONS
+// Rollout Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/341759
+
+export const SEVERITY_ICONS_EXTENSION = {
+ info: 'severityInfo',
+ minor: 'severityLow',
+ major: 'severityMedium',
+ critical: 'severityHigh',
+ blocker: 'severityCritical',
+ unknown: 'severityUnknown',
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
index 1621b6831a2..7435f578852 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
@@ -82,17 +82,8 @@ export default {
return this.mr.shouldBeRebased;
},
- sourceBranchProtected() {
- if (this.glFeatures.mergeRequestWidgetGraphql) {
- return this.stateData.sourceBranchProtected;
- }
-
- return this.mr.sourceBranchProtected;
- },
showResolveButton() {
- return (
- this.mr.conflictResolutionPath && this.canPushToSourceBranch && !this.sourceBranchProtected
- );
+ return this.mr.conflictResolutionPath && this.canPushToSourceBranch;
},
},
};
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
new file mode 100644
index 00000000000..d32db50874c
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
@@ -0,0 +1,123 @@
+import { n__, s__, sprintf } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants';
+import { SEVERITY_ICONS_EXTENSION } from '~/reports/codequality_report/constants';
+import { parseCodeclimateMetrics } from '~/reports/codequality_report/store/utils/codequality_parser';
+import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
+
+export default {
+ name: 'WidgetCodeQuality',
+ props: ['codeQuality', 'blobPath'],
+ i18n: {
+ label: s__('ciReport|Code Quality'),
+ loading: s__('ciReport|Code Quality test metrics results are being parsed'),
+ error: s__('ciReport|Code Quality failed loading results'),
+ },
+ expandEvent: 'i_testing_code_quality_widget_total',
+ computed: {
+ summary() {
+ const { newErrors, resolvedErrors, errorSummary } = this.collapsedData;
+ if (errorSummary.errored >= 1 && errorSummary.resolved >= 1) {
+ const improvements = sprintf(
+ n__(
+ '%{strongOpen}%{errors}%{strongClose} point',
+ '%{strongOpen}%{errors}%{strongClose} points',
+ resolvedErrors.length,
+ ),
+ {
+ errors: resolvedErrors.length,
+ strongOpen: '<strong>',
+ strongClose: '</strong>',
+ },
+ false,
+ );
+
+ const degradations = sprintf(
+ n__(
+ '%{strongOpen}%{errors}%{strongClose} point',
+ '%{strongOpen}%{errors}%{strongClose} points',
+ newErrors.length,
+ ),
+ { errors: newErrors.length, strongOpen: '<strong>', strongClose: '</strong>' },
+ false,
+ );
+ return sprintf(
+ s__(`ciReport|Code Quality improved on ${improvements} and degraded on ${degradations}.`),
+ );
+ } else if (errorSummary.resolved >= 1) {
+ const improvements = n__('%d point', '%d points', resolvedErrors.length);
+ return sprintf(s__(`ciReport|Code Quality improved on ${improvements}.`));
+ } else if (errorSummary.errored >= 1) {
+ const degradations = n__('%d point', '%d points', newErrors.length);
+ return sprintf(s__(`ciReport|Code Quality degraded on ${degradations}.`));
+ }
+ return s__(`ciReport|No changes to Code Quality.`);
+ },
+ statusIcon() {
+ if (this.collapsedData.errorSummary?.errored >= 1) {
+ return EXTENSION_ICONS.warning;
+ }
+ return EXTENSION_ICONS.success;
+ },
+ },
+ methods: {
+ fetchCollapsedData() {
+ return Promise.all([this.fetchReport(this.codeQuality)]).then((values) => {
+ return {
+ resolvedErrors: parseCodeclimateMetrics(
+ values[0].resolved_errors,
+ this.blobPath.head_path,
+ ),
+ newErrors: parseCodeclimateMetrics(values[0].new_errors, this.blobPath.head_path),
+ existingErrors: parseCodeclimateMetrics(
+ values[0].existing_errors,
+ this.blobPath.head_path,
+ ),
+ errorSummary: values[0].summary,
+ };
+ });
+ },
+ fetchFullData() {
+ const fullData = [];
+
+ this.collapsedData.newErrors.map((e) => {
+ return fullData.push({
+ text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`,
+ subtext: sprintf(
+ s__(`ciReport|in %{open_link}${e.file_path}:${e.line}%{close_link}`),
+ {
+ open_link: `<a class="gl-text-decoration-underline" href="${e.urlPath}">`,
+ close_link: '</a>',
+ },
+ false,
+ ),
+ icon: {
+ name: SEVERITY_ICONS_EXTENSION[e.severity],
+ },
+ });
+ });
+
+ this.collapsedData.resolvedErrors.map((e) => {
+ return fullData.push({
+ text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`,
+ subtext: sprintf(
+ s__(`ciReport|in %{open_link}${e.file_path}:${e.line}%{close_link}`),
+ {
+ open_link: `<a class="gl-text-decoration-underline" href="${e.urlPath}">`,
+ close_link: '</a>',
+ },
+ false,
+ ),
+ icon: {
+ name: SEVERITY_ICONS_EXTENSION[e.severity],
+ },
+ });
+ });
+
+ return Promise.resolve(fullData);
+ },
+ fetchReport(endpoint) {
+ return axios.get(endpoint).then((res) => res.data);
+ },
+ },
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index cd4d9398899..965746e79fb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -46,6 +46,7 @@ import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variab
import getStateQuery from './queries/get_state.query.graphql';
import terraformExtension from './extensions/terraform';
import accessibilityExtension from './extensions/accessibility';
+import codeQualityExtension from './extensions/code_quality';
export default {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
@@ -241,6 +242,11 @@ export default {
this.registerTerraformPlans();
}
},
+ shouldRenderCodeQuality(newVal) {
+ if (newVal) {
+ this.registerCodeQualityExtension();
+ }
+ },
shouldShowAccessibilityReport(newVal) {
if (newVal) {
this.registerAccessibilityExtension();
@@ -491,6 +497,11 @@ export default {
registerExtension(accessibilityExtension);
}
},
+ registerCodeQualityExtension() {
+ if (this.shouldRenderCodeQuality && this.shouldShowExtension) {
+ registerExtension(codeQualityExtension);
+ }
+ },
},
};
</script>
@@ -546,7 +557,7 @@ export default {
</div>
<extensions-container :mr="mr" />
<grouped-codequality-reports-app
- v-if="shouldRenderCodeQuality"
+ v-if="shouldRenderCodeQuality && !shouldShowExtension"
:head-blob-path="mr.headBlobPath"
:base-blob-path="mr.baseBlobPath"
:codequality-reports-path="mr.codequalityReportsPath"
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 994e0c23b44..eb07609d5d6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -32,9 +32,15 @@ export default class MergeRequestStore {
this.setPaths(data);
this.setData(data);
+ this.initCodeQualityReport(data);
this.setGitpodData(data);
}
+ initCodeQualityReport(data) {
+ this.blobPath = data.blob_path;
+ this.codeQuality = data.codequality_reports_path;
+ }
+
setData(data, isRebased) {
this.initApprovals();
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
new file mode 100644
index 00000000000..03296d6b233
--- /dev/null
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module ProductAnalyticsTracking
+ include Gitlab::Tracking::Helpers
+ include RedisTracking
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def track_event(*controller_actions, name:, conditions: nil, destinations: [:redis_hll], &block)
+ custom_conditions = [:trackable_html_request?, *conditions]
+
+ after_action only: controller_actions, if: custom_conditions do
+ route_events_to(destinations, name, &block)
+ end
+ end
+ end
+
+ private
+
+ def route_events_to(destinations, name, &block)
+ track_unique_redis_hll_event(name, &block) if destinations.include?(:redis_hll)
+
+ if destinations.include?(:snowplow) && Feature.enabled?(:route_hll_to_snowplow, tracking_namespace_source, default_enabled: :yaml)
+ Gitlab::Tracking.event(self.class.to_s, name, namespace: tracking_namespace_source, user: current_user)
+ end
+ end
+end
diff --git a/app/controllers/jira_connect/events_controller.rb b/app/controllers/jira_connect/events_controller.rb
index 1ea0a92662b..327192857f6 100644
--- a/app/controllers/jira_connect/events_controller.rb
+++ b/app/controllers/jira_connect/events_controller.rb
@@ -7,11 +7,13 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
before_action :verify_asymmetric_atlassian_jwt!
def installed
- return head :ok if current_jira_installation
+ unless Feature.enabled?(:jira_connect_installation_update, default_enabled: :yaml)
+ return head :ok if current_jira_installation
+ end
- installation = JiraConnectInstallation.new(event_params)
+ success = current_jira_installation ? update_installation : create_installation
- if installation.save
+ if success
head :ok
else
head :unprocessable_entity
@@ -28,8 +30,24 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
private
- def event_params
- params.permit(:clientKey, :sharedSecret, :baseUrl).transform_keys(&:underscore)
+ def create_installation
+ JiraConnectInstallation.new(create_params).save
+ end
+
+ def update_installation
+ current_jira_installation.update(update_params)
+ end
+
+ def create_params
+ transformed_params.permit(:client_key, :shared_secret, :base_url)
+ end
+
+ def update_params
+ transformed_params.permit(:shared_secret, :base_url)
+ end
+
+ def transformed_params
+ @transformed_params ||= params.transform_keys(&:underscore)
end
def verify_asymmetric_atlassian_jwt!
@@ -43,7 +61,7 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
def jwt_verification_claims
{
aud: jira_connect_base_url(protocol: 'https'),
- iss: event_params[:client_key],
+ iss: transformed_params[:client_key],
qsh: Atlassian::Jwt.create_query_string_hash(request.url, request.method, jira_connect_base_url)
}
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 3ca719101d2..155ebe88d33 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -498,7 +498,10 @@ class Project < ApplicationRecord
presence: true,
project_path: true,
length: { maximum: 255 }
- validate :container_registry_project_path_validation
+ validates :path,
+ format: { with: Gitlab::Regex.oci_repository_path_regex,
+ message: Gitlab::Regex.oci_repository_path_regex_message },
+ if: :path_changed?
validates :project_feature, presence: true
@@ -889,14 +892,6 @@ class Project < ApplicationRecord
super
end
- def container_registry_project_path_validation
- if Feature.enabled?(:restrict_special_characters_in_project_path, self, default_enabled: :yaml) &&
- path_changed? &&
- !path.match?(Gitlab::Regex.oci_repository_path_regex)
- errors.add(:path, Gitlab::Regex.oci_repository_path_regex_message)
- end
- end
-
def parent_loaded?
association(:namespace).loaded?
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 2905db7ce6c..b3bdc2c1c42 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -291,21 +291,7 @@ class User < ApplicationRecord
end
end
after_commit(on: :update) do
- if previous_changes.key?('email')
- # Add the old primary email to Emails if not added already - this should be removed
- # after the background migration for MR https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70872/ has completed,
- # as the primary email is now added to Emails upon confirmation
- # Issue to remove that: https://gitlab.com/gitlab-org/gitlab/-/issues/344134
- previous_confirmed_at = previous_changes.key?('confirmed_at') ? previous_changes['confirmed_at'][0] : confirmed_at
- previous_email = previous_changes[:email][0]
- if previous_confirmed_at && !emails.exists?(email: previous_email)
- # rubocop: disable CodeReuse/ServiceClass
- Emails::CreateService.new(self, user: self, email: previous_email).execute(confirmed_at: previous_confirmed_at)
- # rubocop: enable CodeReuse/ServiceClass
- end
-
- update_invalid_gpg_signatures
- end
+ update_invalid_gpg_signatures if previous_changes.key?('email')
end
after_initialize :set_projects_limit
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index 91a018121c0..0c3ce1f3fa4 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -27,12 +27,9 @@
- if @group.new_record?
.form-group.row
.offset-sm-2.col-sm-10
- .gl-alert.gl-alert-
- .gl-alert-container
- = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- = render 'shared/group_tips'
+ = render 'shared/global_alert', dismissible: false do
+ .gl-alert-body
+ = render 'shared/group_tips'
.form-actions
= f.submit _('Create group'), class: "gl-button btn btn-confirm"
= link_to _('Cancel'), admin_groups_path, class: "gl-button btn btn-default btn-cancel"
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index cd177db3ed0..1d711f366c4 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -2,6 +2,7 @@
- page_title _("To-Do List")
- header_title _("To-Do List"), dashboard_todos_path
+= render_two_factor_auth_recovery_settings_check
= render_dashboard_ultimate_trial(current_user)
- add_page_specific_style 'page_bundles/todos'
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 133083f1103..a656b61dc8f 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -14,7 +14,6 @@
= dispensable_render "layouts/nav/classification_level_banner"
= yield :flash_message
= dispensable_render "shared/service_ping_consent"
- = render_two_factor_auth_recovery_settings_check
= dispensable_render_if_exists "layouts/header/ee_subscribable_banner"
= dispensable_render_if_exists "layouts/header/seats_count_alert"
= dispensable_render_if_exists "shared/namespace_storage_limit_alert"
diff --git a/app/views/projects/_deletion_failed.html.haml b/app/views/projects/_deletion_failed.html.haml
index 21c799f5bb6..b713b805009 100644
--- a/app/views/projects/_deletion_failed.html.haml
+++ b/app/views/projects/_deletion_failed.html.haml
@@ -1,10 +1,7 @@
- project = local_assigns.fetch(:project)
- return unless project.delete_error.present?
-.project-deletion-failed-message.gl-alert.gl-alert-warning
- .gl-alert-container
- = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- This project was scheduled for deletion, but failed with the following message:
- = project.delete_error
+= render 'shared/global_alert', variant: :warning, dismissible: false, alert_class: 'project-deletion-failed-message' do
+ .gl-alert-body
+ This project was scheduled for deletion, but failed with the following message:
+ = project.delete_error
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 2d0a4ae8605..1fb045544aa 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -35,8 +35,7 @@
- link_start_group_path = '<a href="%{path}">' % { path: new_group_path }
- project_tip = s_('ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}') % { link_start: link_start_group_path, link_end: '</a>' }
= project_tip.html_safe
-.gl-alert.gl-alert-success.gl-mb-4.gl-display-none.js-user-readme-repo
- = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+= render 'shared/global_alert', alert_class: "gl-mb-4 gl-display-none js-user-readme-repo", dismissible: false, variant: :success do
.gl-alert-body
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/profile/index', anchor: 'add-details-to-your-profile-with-a-readme') }
= html_escape(_('%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}')) % { project_path: "<strong>#{current_user.username} / #{current_user.username}</strong>".html_safe, help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
diff --git a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
index e7239661313..f21acd26ada 100644
--- a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
+++ b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
@@ -1,6 +1,6 @@
= render 'shared/global_alert',
variant: :warning,
- alert_class: 'js-recovery-settings-callout',
+ alert_class: 'js-recovery-settings-callout gl-mt-5',
alert_data: { feature_id: Users::CalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK, dismiss_endpoint: callouts_path, defer_links: 'true' },
close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do
.gl-alert-body