diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-28 15:08:39 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-28 15:08:39 +0300 |
commit | aaff41e10e8c03e545af9ba157e79f67686972a0 (patch) | |
tree | dbfc8ba40f533bd62bd1ffae500ebb43bceb5878 /app | |
parent | c00c766f13d6e0291831a25434eb54057708cc47 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
5 files changed, 18 insertions, 257 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js index a59f48fb8b2..1a469f9b7bb 100644 --- a/app/assets/javascripts/vue_merge_request_widget/constants.js +++ b/app/assets/javascripts/vue_merge_request_widget/constants.js @@ -13,12 +13,18 @@ export const WARNING = 'warning'; export const INFO = 'info'; export const MWPS_MERGE_STRATEGY = 'merge_when_pipeline_succeeds'; +export const MWCP_MERGE_STRATEGY = 'merge_when_checks_pass'; export const MTWPS_MERGE_STRATEGY = 'add_to_merge_train_when_pipeline_succeeds'; export const MT_MERGE_STRATEGY = 'merge_train'; export const PIPELINE_FAILED_STATE = 'failed'; -export const AUTO_MERGE_STRATEGIES = [MWPS_MERGE_STRATEGY, MTWPS_MERGE_STRATEGY, MT_MERGE_STRATEGY]; +export const AUTO_MERGE_STRATEGIES = [ + MWPS_MERGE_STRATEGY, + MTWPS_MERGE_STRATEGY, + MT_MERGE_STRATEGY, + MWCP_MERGE_STRATEGY, +]; // SP - "Suggest Pipelines" export const SP_TRACK_LABEL = 'no_pipeline_noticed'; 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 9ddf8241020..b1c069d9b1e 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 @@ -6,6 +6,7 @@ import { machine } from '~/lib/utils/finite_state_machine'; import { MTWPS_MERGE_STRATEGY, MT_MERGE_STRATEGY, + MWCP_MERGE_STRATEGY, MWPS_MERGE_STRATEGY, STATE_MACHINE, stateToTransitionMap, @@ -352,6 +353,8 @@ export default class MergeRequestStore { return MTWPS_MERGE_STRATEGY; } else if (availableAutoMergeStrategies.includes(MT_MERGE_STRATEGY)) { return MT_MERGE_STRATEGY; + } else if (availableAutoMergeStrategies.includes(MWCP_MERGE_STRATEGY)) { + return MWCP_MERGE_STRATEGY; } else if (availableAutoMergeStrategies.includes(MWPS_MERGE_STRATEGY)) { return MWPS_MERGE_STRATEGY; } @@ -375,6 +378,14 @@ export default class MergeRequestStore { return false; } + get isApprovalNeeded() { + return this.hasApprovalsAvailable ? !this.isApproved : false; + } + + get preventMerge() { + return this.isApprovalNeeded; + } + // Because the state machine doesn't yet handle every state and transition, // some use-cases will need to force a state that can't be reached by // a known transition. This is undesirable long-term (as it subverts diff --git a/app/services/metrics/dashboard/grafana_metric_embed_service.rb b/app/services/metrics/dashboard/grafana_metric_embed_service.rb deleted file mode 100644 index 26ccded45f8..00000000000 --- a/app/services/metrics/dashboard/grafana_metric_embed_service.rb +++ /dev/null @@ -1,179 +0,0 @@ -# frozen_string_literal: true - -# Responsible for returning a gitlab-compatible dashboard -# containing info based on a grafana dashboard and datasource. -# -# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards. -module Metrics - module Dashboard - class GrafanaMetricEmbedService < ::Metrics::Dashboard::BaseEmbedService - include ReactiveCaching - - SEQUENCE = [ - ::Gitlab::Metrics::Dashboard::Stages::GrafanaFormatter, - ::Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter - ].freeze - - self.reactive_cache_key = ->(service) { service.cache_key } - self.reactive_cache_lease_timeout = 30.seconds - self.reactive_cache_refresh_interval = 30.minutes - self.reactive_cache_lifetime = 30.minutes - self.reactive_cache_work_type = :external_dependency - self.reactive_cache_worker_finder = ->(_id, *args) { from_cache(*args) } - - class << self - # Determines whether the provided params are sufficient - # to uniquely identify a grafana dashboard. - def valid_params?(params) - [ - embedded?(params[:embedded]), - params[:grafana_url] - ].all? - end - - def from_cache(project_id, user_id, grafana_url) - project = Project.find(project_id) - user = User.find(user_id) if user_id.present? - - new(project, user, grafana_url: grafana_url) - end - end - - def get_dashboard - with_reactive_cache(*cache_key) { |result| result } - end - - # Inherits the primary logic from the parent class and - # maintains the service's API while including ReactiveCache - def calculate_reactive_cache(*) - # This is called with explicit parentheses to prevent - # the params passed to #calculate_reactive_cache from - # being passed to #get_dashboard (which accepts none) - ::Metrics::Dashboard::BaseService - .instance_method(:get_dashboard) - .bind_call(self) - end - - def cache_key(*args) - [project.id, current_user&.id, grafana_url] - end - - # Required for ReactiveCaching; Usage overridden by - # self.reactive_cache_worker_finder - def id - nil - end - - private - - def get_raw_dashboard - raise MissingIntegrationError unless client - - grafana_dashboard = fetch_dashboard - datasource = fetch_datasource(grafana_dashboard) - - params.merge!(grafana_dashboard: grafana_dashboard, datasource: datasource) - - {} - end - - def fetch_dashboard - uid = GrafanaUidParser.new(grafana_url, project).parse - raise DashboardProcessingError, _('Dashboard uid not found') unless uid - - response = client.get_dashboard(uid: uid) - - parse_json(response.body) - end - - def fetch_datasource(dashboard) - name = DatasourceNameParser.new(grafana_url, dashboard).parse - raise DashboardProcessingError, _('Datasource name not found') unless name - - response = client.get_datasource(name: name) - - parse_json(response.body) - end - - def grafana_url - params[:grafana_url] - end - - def client - project.grafana_integration&.client - end - - def allowed? - Ability.allowed?(current_user, :read_project, project) - end - - def sequence - SEQUENCE - end - - def parse_json(json) - Gitlab::Json.parse(json, symbolize_names: true) - rescue JSON::ParserError - raise DashboardProcessingError, _('Grafana response contains invalid json') - end - end - - # Identifies the uid of the dashboard based on url format - class GrafanaUidParser - def initialize(grafana_url, project) - @grafana_url = grafana_url - @project = project - end - - def parse - @grafana_url.match(uid_regex) { |m| m.named_captures['uid'] } - end - - private - - # URLs are expected to look like https://domain.com/d/:uid/other/stuff - def uid_regex - base_url = @project.grafana_integration.grafana_url.chomp('/') - - %r{^(#{Regexp.escape(base_url)}\/d\/(?<uid>.+)\/)}x - end - end - - # Identifies the name of the datasource for a dashboard - # based on the panelId query parameter found in the url. - # - # If no panel is specified, defaults to the first valid panel. - class DatasourceNameParser - def initialize(grafana_url, grafana_dashboard) - @grafana_url = grafana_url - @grafana_dashboard = grafana_dashboard - end - - def parse - @grafana_dashboard[:dashboard][:panels] - .find { |panel| panel_id ? matching_panel?(panel) : valid_panel?(panel) } - .try(:[], :datasource) - end - - private - - def panel_id - query_params[:panelId] - end - - def query_params - Gitlab::Metrics::Dashboard::Url.parse_query(@grafana_url) - end - - def matching_panel?(panel) - panel[:id].to_s == panel_id - end - - def valid_panel?(panel) - ::Grafana::Validator - .new(@grafana_dashboard, nil, panel, query_params) - .valid? - end - end - end -end diff --git a/app/services/metrics/dashboard/pod_dashboard_service.rb b/app/services/metrics/dashboard/pod_dashboard_service.rb deleted file mode 100644 index e2d7a081a3e..00000000000 --- a/app/services/metrics/dashboard/pod_dashboard_service.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -module Metrics - module Dashboard - class PodDashboardService < ::Metrics::Dashboard::PredefinedDashboardService - DASHBOARD_PATH = 'config/prometheus/pod_metrics.yml' - DASHBOARD_NAME = N_('K8s pod health') - - # SHA256 hash of dashboard content - DASHBOARD_VERSION = '3a91b32f91b2dd3d90275333c0ea3630b3f3f37c4296ede5b5eef59bf523d66b' - - SEQUENCE = [ - STAGES::VariableEndpointInserter, - STAGES::PanelIdsInserter - ].freeze - - class << self - def all_dashboard_paths(_project) - [{ - path: DASHBOARD_PATH, - display_name: _(DASHBOARD_NAME), - default: false, - system_dashboard: false, - out_of_the_box_dashboard: out_of_the_box_dashboard? - }] - end - end - - private - - def dashboard_version - DASHBOARD_VERSION - end - end - end -end diff --git a/app/services/metrics/dashboard/transient_embed_service.rb b/app/services/metrics/dashboard/transient_embed_service.rb deleted file mode 100644 index 8b0ba992342..00000000000 --- a/app/services/metrics/dashboard/transient_embed_service.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -# Acts as a pass-through to allow embeddable dashboards to be -# generated based on external data, but still processed with the -# required attributes that allow the FE to render them appropriately. -# -# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards. -module Metrics - module Dashboard - class TransientEmbedService < ::Metrics::Dashboard::BaseEmbedService - extend ::Gitlab::Utils::Override - - class << self - def valid_params?(params) - [ - embedded?(params[:embedded]), - params[:embed_json] - ].all? - end - end - - private - - override :get_raw_dashboard - def get_raw_dashboard - Gitlab::Json.parse(params[:embed_json]) - rescue JSON::ParserError => e - invalid_embed_json!(e.message) - end - - override :identifiers - def identifiers - Digest::SHA256.hexdigest(params[:embed_json]) - end - - def invalid_embed_json!(message) - raise DashboardProcessingError, _("Parsing error for param :embed_json. %{message}") % { message: message } - end - end - end -end |