Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
90a3c1a32f
commit
3e5162fc5b
|
|
@ -2,7 +2,6 @@
|
|||
# Cop supports --autocorrect.
|
||||
Lint/SymbolConversion:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/application_settings_controller.rb'
|
||||
- 'app/controllers/groups_controller.rb'
|
||||
- 'app/controllers/projects/issues_controller.rb'
|
||||
- 'app/controllers/projects_controller.rb'
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ Style/ClassAndModuleChildren:
|
|||
- 'app/controllers/admin/abuse_reports_controller.rb'
|
||||
- 'app/controllers/admin/application_controller.rb'
|
||||
- 'app/controllers/admin/application_settings/appearances_controller.rb'
|
||||
- 'app/controllers/admin/application_settings_controller.rb'
|
||||
- 'app/controllers/admin/applications_controller.rb'
|
||||
- 'app/controllers/admin/clusters_controller.rb'
|
||||
- 'app/controllers/admin/cohorts_controller.rb'
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
0be460967aff73c3ce3262e840bee3dc6ed289f5
|
||||
6dc57705f4d70c87ea803faa572e5bb844cbc569
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ export default {
|
|||
default: '',
|
||||
required: false,
|
||||
},
|
||||
canUpdateAllJobs: {
|
||||
default: false,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
jobs: {
|
||||
|
|
@ -240,7 +244,7 @@ export default {
|
|||
<jobs-table-tabs
|
||||
:all-jobs-count="count"
|
||||
:loading="loading"
|
||||
:show-cancel-all-jobs-button="isCancelable"
|
||||
:show-cancel-all-jobs-button="canUpdateAllJobs && isCancelable"
|
||||
@fetchJobsByStatus="fetchJobsByStatus"
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { GlIcon, GlAvatarsInline, GlAvatarLink, GlAvatar, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { __, n__, sprintf } from '~/locale';
|
||||
import { n__ } from '~/locale';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { swapArrayItems } from '~/lib/utils/array_utility';
|
||||
import { isCurrentUser } from '~/lib/utils/common_utils';
|
||||
|
|
@ -28,15 +28,6 @@ const REVIEW_STATE_ICONS = {
|
|||
foregroundClass: 'gl-fill-status-neutral',
|
||||
},
|
||||
};
|
||||
const USER_TOOLTIP_TITLES = {
|
||||
ASSIGNEES: __('%{strongStart}%{you}%{strongEnd}%{break}Assigned to %{name}'),
|
||||
REQUESTED_CHANGES: __('%{strongStart}%{you}%{strongEnd}%{break}%{name} requested changes'),
|
||||
REVIEWED: __('%{strongStart}%{you}%{strongEnd}%{break}%{name} left feedback'),
|
||||
APPROVED: __('%{strongStart}%{you}%{strongEnd}%{break}Approved by %{name}'),
|
||||
UNREVIEWED: __('%{strongStart}%{you}%{strongEnd}%{break}Review requested from %{name}'),
|
||||
REVIEW_STARTED: __('%{strongStart}%{you}%{strongEnd}%{break}%{name} started a review'),
|
||||
default: __('%{strongStart}%{you}%{strongEnd}%{break}Review requested from %{name}'),
|
||||
};
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -86,36 +77,15 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
userId(user) {
|
||||
return getIdFromGraphQLId(user.id);
|
||||
},
|
||||
isCurrentUser(user) {
|
||||
return !this.newListsEnabled && isCurrentUser(getIdFromGraphQLId(user.id));
|
||||
return isCurrentUser(getIdFromGraphQLId(user.id));
|
||||
},
|
||||
reviewStateIcon(user) {
|
||||
return REVIEW_STATE_ICONS[user.mergeRequestInteraction?.reviewState];
|
||||
},
|
||||
tooltipTitle(user) {
|
||||
const currentUser = this.isCurrentUser(user);
|
||||
const thisIsYouText = currentUser ? __('This is you.') : '';
|
||||
|
||||
let titleType;
|
||||
|
||||
if (this.type === 'ASSIGNEES') {
|
||||
titleType = this.type;
|
||||
} else if (user.mergeRequestInteraction?.reviewState) {
|
||||
titleType = user.mergeRequestInteraction.reviewState;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
USER_TOOLTIP_TITLES[titleType] || USER_TOOLTIP_TITLES.default,
|
||||
{
|
||||
name: user.name,
|
||||
you: thisIsYouText,
|
||||
break: currentUser ? '<br />' : '',
|
||||
strongStart: currentUser ? '<strong>' : '',
|
||||
strongEnd: currentUser ? '</strong>' : '',
|
||||
},
|
||||
false,
|
||||
);
|
||||
},
|
||||
},
|
||||
MAX_VISIBLE_USERS,
|
||||
REVIEW_STATE_ICONS,
|
||||
|
|
@ -135,15 +105,17 @@ export default {
|
|||
>
|
||||
<template #avatar="{ avatar: user }">
|
||||
<gl-avatar-link
|
||||
v-gl-tooltip.viewport.top.html="tooltipTitle(user)"
|
||||
:data-name="user.name"
|
||||
:data-user-id="userId(user)"
|
||||
:data-username="user.username"
|
||||
target="blank"
|
||||
:href="user.webUrl"
|
||||
class="gl-relative"
|
||||
class="js-user-link gl-relative"
|
||||
data-testid="assigned-user"
|
||||
>
|
||||
<gl-avatar :src="user.avatarUrl" :size="32" class="!gl-bg-white" />
|
||||
<span
|
||||
v-if="isCurrentUser(user)"
|
||||
v-if="!newListsEnabled && isCurrentUser(user)"
|
||||
class="gl-absolute -gl-left-2 -gl-top-2 gl-flex gl-h-5 gl-w-5 gl-items-center gl-justify-center gl-rounded-full gl-bg-blue-500 gl-p-1 gl-text-white"
|
||||
data-testid="current-user"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import Vue from 'vue';
|
|||
import VueApollo from 'vue-apollo';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import AdminJobsTableApp from '~/ci/admin/jobs_table/admin_jobs_table_app.vue';
|
||||
import cacheConfig from '~/ci/admin/jobs_table/graphql/cache_config';
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ const initAdminJobsApp = () => {
|
|||
|
||||
if (!containerEl) return false;
|
||||
|
||||
const { jobStatuses, emptyStateSvgPath, url } = containerEl.dataset;
|
||||
const { jobStatuses, emptyStateSvgPath, url, canUpdateAllJobs } = containerEl.dataset;
|
||||
|
||||
return new Vue({
|
||||
el: containerEl,
|
||||
|
|
@ -28,6 +29,7 @@ const initAdminJobsApp = () => {
|
|||
url,
|
||||
emptyStateSvgPath,
|
||||
jobStatuses: JSON.parse(jobStatuses),
|
||||
canUpdateAllJobs: parseBoolean(canUpdateAllJobs),
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(AdminJobsTableApp);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ export default {
|
|||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
buttonText: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -47,5 +51,6 @@ export default {
|
|||
:merge-requests-count="mergeRequestsCount"
|
||||
:forks-count="forksCount"
|
||||
:stars-count="starsCount"
|
||||
:button-text="buttonText"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@ export default {
|
|||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
buttonText: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: __('Delete project'),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -58,9 +63,6 @@ export default {
|
|||
this.isModalVisible = true;
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
deleteProject: __('Delete project'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -89,7 +91,7 @@ export default {
|
|||
variant="danger"
|
||||
data-testid="delete-button"
|
||||
@click="onButtonClick"
|
||||
>{{ $options.i18n.deleteProject }}</gl-button
|
||||
>{{ buttonText }}</gl-button
|
||||
>
|
||||
</gl-form>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export default (selector = '#js-project-delete-button') => {
|
|||
mergeRequestsCount,
|
||||
forksCount,
|
||||
starsCount,
|
||||
buttonText,
|
||||
} = el.dataset;
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
|
|
@ -30,6 +31,7 @@ export default (selector = '#js-project-delete-button') => {
|
|||
mergeRequestsCount: parseInt(mergeRequestsCount, 10),
|
||||
forksCount: parseInt(forksCount, 10),
|
||||
starsCount: parseInt(starsCount, 10),
|
||||
buttonText,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
import {
|
||||
GlAlert,
|
||||
GlButton,
|
||||
GlLink,
|
||||
GlCollapsibleListbox,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlLoadingIcon,
|
||||
GlSprintf,
|
||||
GlTooltipDirective,
|
||||
|
|
@ -22,6 +23,10 @@ import inboundUpdateCIJobTokenScopeMutation from '../graphql/mutations/inbound_u
|
|||
import inboundGetCIJobTokenScopeQuery from '../graphql/queries/inbound_get_ci_job_token_scope.query.graphql';
|
||||
import inboundGetGroupsAndProjectsWithCIJobTokenScopeQuery from '../graphql/queries/inbound_get_groups_and_projects_with_ci_job_token_scope.query.graphql';
|
||||
import getCiJobTokenScopeAllowlistQuery from '../graphql/queries/get_ci_job_token_scope_allowlist.query.graphql';
|
||||
import {
|
||||
JOB_TOKEN_FORM_ADD_GROUP_OR_PROJECT,
|
||||
JOB_TOKEN_FORM_AUTOPOPULATE_AUTH_LOG,
|
||||
} from '../constants';
|
||||
import TokenAccessTable from './token_access_table.vue';
|
||||
import NamespaceForm from './namespace_form.vue';
|
||||
|
||||
|
|
@ -38,6 +43,7 @@ export default {
|
|||
settingDisabledMessage: s__(
|
||||
'CICD|Access unrestricted, so users with sufficient permissions in this project can authenticate with a job token generated in any other project.',
|
||||
),
|
||||
add: __('Add'),
|
||||
addGroupOrProject: __('Add group or project'),
|
||||
projectsFetchError: __('There was a problem fetching the projects'),
|
||||
scopeFetchError: __('There was a problem fetching the job token scope value'),
|
||||
|
|
@ -58,11 +64,22 @@ export default {
|
|||
text: s__('CICD|Only this project and any groups and projects in the allowlist'),
|
||||
},
|
||||
],
|
||||
crudFormActions: [
|
||||
{
|
||||
text: __('Group or project'),
|
||||
value: JOB_TOKEN_FORM_ADD_GROUP_OR_PROJECT,
|
||||
},
|
||||
{
|
||||
text: __('All projects in authentication log'),
|
||||
value: JOB_TOKEN_FORM_AUTOPOPULATE_AUTH_LOG,
|
||||
},
|
||||
],
|
||||
components: {
|
||||
GlAlert,
|
||||
GlButton,
|
||||
GlLink,
|
||||
GlCollapsibleListbox,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlLoadingIcon,
|
||||
GlSprintf,
|
||||
CrudComponent,
|
||||
|
|
@ -132,6 +149,7 @@ export default {
|
|||
projectName: '',
|
||||
namespaceToEdit: null,
|
||||
namespaceToRemove: null,
|
||||
selectedAction: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -147,6 +165,9 @@ export default {
|
|||
const { groups, projects } = this.groupsAndProjectsWithAccess;
|
||||
return [...groups, ...projects];
|
||||
},
|
||||
canAutopopulateAuthLog() {
|
||||
return this.glFeatures.authenticationLogsMigrationForAllowlist;
|
||||
},
|
||||
groupCount() {
|
||||
return this.groupsAndProjectsWithAccess.groups.length;
|
||||
},
|
||||
|
|
@ -169,6 +190,10 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
hideSelectedAction() {
|
||||
this.namespaceToEdit = null;
|
||||
this.selectedAction = null;
|
||||
},
|
||||
mapAllowlistNodes(list) {
|
||||
// The defaultPermissions and jobTokenPolicies are separate fields from the target (the group or project in the
|
||||
// allowlist). Combine them into a single object.
|
||||
|
|
@ -235,6 +260,11 @@ export default {
|
|||
refetchGroupsAndProjects() {
|
||||
this.$apollo.queries.groupsAndProjectsWithAccess.refetch();
|
||||
},
|
||||
selectAction(action, showFormFn) {
|
||||
// TODO: render autopopulate modal when selected
|
||||
this.selectedAction = action;
|
||||
showFormFn();
|
||||
},
|
||||
showNamespaceForm(namespace, showFormFn) {
|
||||
this.namespaceToEdit = namespace;
|
||||
showFormFn();
|
||||
|
|
@ -289,10 +319,20 @@ export default {
|
|||
<crud-component
|
||||
:title="$options.i18n.cardHeaderTitle"
|
||||
:description="$options.i18n.cardHeaderDescription"
|
||||
:toggle-text="$options.i18n.addGroupOrProject"
|
||||
:toggle-text="!canAutopopulateAuthLog ? $options.i18n.addGroupOrProject : undefined"
|
||||
class="gl-mt-5"
|
||||
@hideForm="namespaceToEdit = null"
|
||||
@hideForm="hideSelectedAction"
|
||||
>
|
||||
<template v-if="canAutopopulateAuthLog" #actions="{ showForm }">
|
||||
<gl-collapsible-listbox
|
||||
v-model="selectedAction"
|
||||
:items="$options.crudFormActions"
|
||||
:toggle-text="$options.i18n.add"
|
||||
data-testid="form-selector"
|
||||
size="small"
|
||||
@select="selectAction($event, showForm)"
|
||||
/>
|
||||
</template>
|
||||
<template #count>
|
||||
<gl-loading-icon v-if="isAllowlistLoading" data-testid="count-loading-icon" />
|
||||
<template v-else>
|
||||
|
|
|
|||
|
|
@ -145,3 +145,6 @@ export const JOB_TOKEN_POLICIES = keyBy(
|
|||
POLICIES_BY_RESOURCE.flatMap(({ policies }) => policies),
|
||||
({ value }) => value,
|
||||
);
|
||||
|
||||
export const JOB_TOKEN_FORM_ADD_GROUP_OR_PROJECT = 'JOB_TOKEN_FORM_ADD_GROUP_OR_PROJECT';
|
||||
export const JOB_TOKEN_FORM_AUTOPOPULATE_AUTH_LOG = 'JOB_TOKEN_FORM_AUTOPOPULATE_AUTH_LOG';
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ export default {
|
|||
</p>
|
||||
</div>
|
||||
<div class="gl-flex gl-items-center gl-gap-3" data-testid="crud-actions">
|
||||
<slot name="actions"></slot>
|
||||
<slot name="actions" :show-form="showForm"></slot>
|
||||
<gl-button
|
||||
v-if="toggleText && !isFormUsedAndVisible"
|
||||
size="small"
|
||||
|
|
|
|||
|
|
@ -1,258 +1,261 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||
include InternalRedirect
|
||||
include IntegrationsHelper
|
||||
include DefaultBranchProtection
|
||||
module Admin
|
||||
class ApplicationSettingsController < Admin::ApplicationController
|
||||
include InternalRedirect
|
||||
include IntegrationsHelper
|
||||
include DefaultBranchProtection
|
||||
|
||||
# NOTE: Use @application_setting in this controller when you need to access
|
||||
# application_settings after it has been modified. This is because the
|
||||
# ApplicationSetting model uses Gitlab::ProcessMemoryCache for caching and the
|
||||
# cache might be stale immediately after an update.
|
||||
# https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233
|
||||
before_action :set_application_setting, except: :integrations
|
||||
# NOTE: Use @application_setting in this controller when you need to access
|
||||
# application_settings after it has been modified. This is because the
|
||||
# ApplicationSetting model uses Gitlab::ProcessMemoryCache for caching and the
|
||||
# cache might be stale immediately after an update.
|
||||
# https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233
|
||||
before_action :set_application_setting, except: :integrations
|
||||
|
||||
before_action :disable_query_limiting, only: [:usage_data]
|
||||
before_action :prerecorded_service_ping_data, only: [:metrics_and_profiling] # rubocop:disable Rails/LexicallyScopedActionFilter
|
||||
before_action :disable_query_limiting, only: [:usage_data]
|
||||
before_action :prerecorded_service_ping_data, only: [:metrics_and_profiling] # rubocop:disable Rails/LexicallyScopedActionFilter
|
||||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:ci_variables_pages, current_user)
|
||||
end
|
||||
|
||||
feature_category :not_owned, [ # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
|
||||
:general, :reporting, :metrics_and_profiling, :network,
|
||||
:preferences, :update, :reset_health_check_token
|
||||
]
|
||||
|
||||
urgency :low, [
|
||||
:reset_error_tracking_access_token
|
||||
]
|
||||
|
||||
feature_category :source_code_management, [:repository, :clear_repository_check_states]
|
||||
feature_category :continuous_integration, [:ci_cd, :reset_registration_token]
|
||||
urgency :low, [:ci_cd, :reset_registration_token]
|
||||
feature_category :service_ping, [:usage_data]
|
||||
feature_category :integrations, [:integrations, :slack_app_manifest_share, :slack_app_manifest_download]
|
||||
feature_category :pages, [:lets_encrypt_terms_of_service]
|
||||
feature_category :observability, [:reset_error_tracking_access_token]
|
||||
|
||||
VALID_SETTING_PANELS = %w[general repository
|
||||
ci_cd reporting metrics_and_profiling
|
||||
network preferences].freeze
|
||||
|
||||
# The current size of a sidekiq job's jid is 24 characters. The size of the
|
||||
# jid is an internal detail of Sidekiq, and they do not guarantee that it'll
|
||||
# stay the same. We chose 50 to give us room in case the size of the jid
|
||||
# increases. The jid is alphanumeric, so 50 is very generous. There is a spec
|
||||
# that ensures that the constant value is more than the size of an actual jid.
|
||||
PARAM_JOB_ID_MAX_SIZE = 50
|
||||
|
||||
VALID_SETTING_PANELS.each do |action|
|
||||
define_method(action) { perform_update if submitted? }
|
||||
end
|
||||
|
||||
def integrations
|
||||
return not_found unless instance_level_integrations?
|
||||
|
||||
@integrations = Integration.find_or_initialize_all_non_project_specific(
|
||||
Integration.for_instance, include_instance_specific: true
|
||||
).sort_by { |int| int.title.downcase }
|
||||
end
|
||||
|
||||
def update
|
||||
perform_update
|
||||
end
|
||||
|
||||
def usage_data
|
||||
return not_found unless prerecorded_service_ping_data.present?
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
usage_data_json = Gitlab::Json.pretty_generate(prerecorded_service_ping_data)
|
||||
|
||||
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json, language: 'json')
|
||||
end
|
||||
|
||||
format.json do
|
||||
Gitlab::InternalEvents.track_event('usage_data_download_payload_clicked', user: current_user)
|
||||
|
||||
render json: Gitlab::Json.dump(prerecorded_service_ping_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def reset_registration_token
|
||||
::Ci::Runners::ResetRegistrationTokenService.new(@application_setting, current_user).execute
|
||||
|
||||
flash[:notice] = _('New runners registration token has been generated!')
|
||||
redirect_to admin_runners_path
|
||||
end
|
||||
|
||||
def reset_health_check_token
|
||||
@application_setting.reset_health_check_access_token!
|
||||
flash[:notice] = _('New health check access token has been generated!')
|
||||
redirect_back_or_default
|
||||
end
|
||||
|
||||
def reset_error_tracking_access_token
|
||||
@application_setting.reset_error_tracking_access_token!
|
||||
|
||||
redirect_to general_admin_application_settings_path,
|
||||
notice: _('New error tracking access token has been generated!')
|
||||
end
|
||||
|
||||
def clear_repository_check_states
|
||||
RepositoryCheck::ClearWorker.perform_async # rubocop:disable CodeReuse/Worker
|
||||
|
||||
redirect_to(
|
||||
general_admin_application_settings_path,
|
||||
notice: _('Started asynchronous removal of all repository check states.')
|
||||
)
|
||||
end
|
||||
|
||||
# Getting ToS url requires `directory` api call to Let's Encrypt
|
||||
# which could result in 500 error/slow rendering on settings page
|
||||
# Because of that we use separate controller action
|
||||
def lets_encrypt_terms_of_service
|
||||
redirect_to ::Gitlab::LetsEncrypt.terms_of_service_url
|
||||
end
|
||||
|
||||
def slack_app_manifest_share
|
||||
redirect_to Slack::Manifest.share_url
|
||||
end
|
||||
|
||||
def slack_app_manifest_download
|
||||
send_data Slack::Manifest.to_json, type: :json, disposition: 'attachment', filename: 'slack_manifest.json'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_application_setting
|
||||
@application_setting = ApplicationSetting.current_without_cache
|
||||
@plans = Plan.all
|
||||
end
|
||||
|
||||
def disable_query_limiting
|
||||
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/29418')
|
||||
end
|
||||
|
||||
def application_setting_params # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
||||
params[:application_setting] ||= {}
|
||||
|
||||
if params[:application_setting].key?(:enabled_oauth_sign_in_sources)
|
||||
enabled_oauth_sign_in_sources = params[:application_setting].delete(:enabled_oauth_sign_in_sources)
|
||||
enabled_oauth_sign_in_sources&.delete("")
|
||||
|
||||
params[:application_setting][:disabled_oauth_sign_in_sources] =
|
||||
AuthHelper.button_based_providers.map(&:to_s) -
|
||||
Array(enabled_oauth_sign_in_sources)
|
||||
before_action do
|
||||
push_frontend_feature_flag(:ci_variables_pages, current_user)
|
||||
end
|
||||
|
||||
params[:application_setting][:import_sources]&.delete("")
|
||||
params[:application_setting][:valid_runner_registrars]&.delete("")
|
||||
params[:application_setting][:restricted_visibility_levels]&.delete("")
|
||||
|
||||
params[:application_setting][:package_metadata_purl_types]&.delete("")
|
||||
params[:application_setting][:package_metadata_purl_types]&.map!(&:to_i)
|
||||
|
||||
normalize_default_branch_params!(:application_setting)
|
||||
|
||||
if params[:application_setting][:required_instance_ci_template].blank?
|
||||
params[:application_setting][:required_instance_ci_template] = nil
|
||||
end
|
||||
|
||||
remove_blank_params_for!(:elasticsearch_aws_secret_access_key, :eks_secret_access_key)
|
||||
|
||||
# TODO Remove domain_denylist_raw in APIv5 (See https://gitlab.com/gitlab-org/gitlab-foss/issues/67204)
|
||||
params.delete(:domain_denylist_raw) if params[:domain_denylist_file]
|
||||
params.delete(:domain_denylist_raw) if params[:domain_denylist]
|
||||
params.delete(:domain_allowlist_raw) if params[:domain_allowlist]
|
||||
|
||||
params[:application_setting].permit(visible_application_setting_attributes)
|
||||
end
|
||||
|
||||
def recheck_user_consent?
|
||||
return false unless session[:ask_for_usage_stats_consent]
|
||||
return false unless params[:application_setting]
|
||||
|
||||
params[:application_setting].key?(:usage_ping_enabled) || params[:application_setting].key?(:version_check_enabled)
|
||||
end
|
||||
|
||||
def visible_application_setting_attributes
|
||||
[
|
||||
*::ApplicationSettingsHelper.visible_attributes,
|
||||
*::ApplicationSettingsHelper.external_authorization_service_attributes,
|
||||
*ApplicationSetting.kroki_formats_attributes.keys.map { |key| "kroki_formats_#{key}".to_sym },
|
||||
{ default_branch_protection_defaults: [
|
||||
:allow_force_push,
|
||||
:developer_can_initial_push,
|
||||
{
|
||||
allowed_to_merge: [:access_level],
|
||||
allowed_to_push: [:access_level]
|
||||
}
|
||||
] },
|
||||
:lets_encrypt_notification_email,
|
||||
:lets_encrypt_terms_of_service_accepted,
|
||||
:domain_denylist_file,
|
||||
:raw_blob_request_limit,
|
||||
:issues_create_limit,
|
||||
:notes_create_limit,
|
||||
:pipeline_limit_per_project_user_sha,
|
||||
:default_branch_name,
|
||||
:auto_approve_pending_users,
|
||||
{ disabled_oauth_sign_in_sources: [],
|
||||
import_sources: [],
|
||||
package_metadata_purl_types: [],
|
||||
restricted_visibility_levels: [],
|
||||
repository_storages_weighted: {},
|
||||
valid_runner_registrars: [] }
|
||||
feature_category :not_owned, [ # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
|
||||
:general, :reporting, :metrics_and_profiling, :network,
|
||||
:preferences, :update, :reset_health_check_token
|
||||
]
|
||||
end
|
||||
|
||||
def submitted?
|
||||
request.patch?
|
||||
end
|
||||
urgency :low, [
|
||||
:reset_error_tracking_access_token
|
||||
]
|
||||
|
||||
def perform_update
|
||||
successful = ::ApplicationSettings::UpdateService
|
||||
.new(@application_setting, current_user, application_setting_params)
|
||||
.execute
|
||||
feature_category :source_code_management, [:repository, :clear_repository_check_states]
|
||||
feature_category :continuous_integration, [:ci_cd, :reset_registration_token]
|
||||
urgency :low, [:ci_cd, :reset_registration_token]
|
||||
feature_category :service_ping, [:usage_data]
|
||||
feature_category :integrations, [:integrations, :slack_app_manifest_share, :slack_app_manifest_download]
|
||||
feature_category :pages, [:lets_encrypt_terms_of_service]
|
||||
feature_category :observability, [:reset_error_tracking_access_token]
|
||||
|
||||
session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent? if recheck_user_consent?
|
||||
VALID_SETTING_PANELS = %w[general repository
|
||||
ci_cd reporting metrics_and_profiling
|
||||
network preferences].freeze
|
||||
|
||||
redirect_path = referer_path(request) || general_admin_application_settings_path
|
||||
# The current size of a sidekiq job's jid is 24 characters. The size of the
|
||||
# jid is an internal detail of Sidekiq, and they do not guarantee that it'll
|
||||
# stay the same. We chose 50 to give us room in case the size of the jid
|
||||
# increases. The jid is alphanumeric, so 50 is very generous. There is a spec
|
||||
# that ensures that the constant value is more than the size of an actual jid.
|
||||
PARAM_JOB_ID_MAX_SIZE = 50
|
||||
|
||||
respond_to do |format|
|
||||
if successful
|
||||
format.json { head :ok }
|
||||
format.html { redirect_to redirect_path, notice: _('Application settings saved successfully') }
|
||||
else
|
||||
format.json { head :bad_request }
|
||||
format.html { render_update_error }
|
||||
VALID_SETTING_PANELS.each do |action|
|
||||
define_method(action) { perform_update if submitted? }
|
||||
end
|
||||
|
||||
def integrations
|
||||
return not_found unless instance_level_integrations?
|
||||
|
||||
@integrations = Integration.find_or_initialize_all_non_project_specific(
|
||||
Integration.for_instance, include_instance_specific: true
|
||||
).sort_by { |int| int.title.downcase }
|
||||
end
|
||||
|
||||
def update
|
||||
perform_update
|
||||
end
|
||||
|
||||
def usage_data
|
||||
return not_found unless prerecorded_service_ping_data.present?
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
usage_data_json = Gitlab::Json.pretty_generate(prerecorded_service_ping_data)
|
||||
|
||||
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json, language: 'json')
|
||||
end
|
||||
|
||||
format.json do
|
||||
Gitlab::InternalEvents.track_event('usage_data_download_payload_clicked', user: current_user)
|
||||
|
||||
render json: Gitlab::Json.dump(prerecorded_service_ping_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_update_error
|
||||
action = valid_setting_panels.include?(action_name) ? action_name : :general
|
||||
def reset_registration_token
|
||||
::Ci::Runners::ResetRegistrationTokenService.new(@application_setting, current_user).execute
|
||||
|
||||
flash[:alert] = _('Application settings update failed')
|
||||
flash[:notice] = _('New runners registration token has been generated!')
|
||||
redirect_to admin_runners_path
|
||||
end
|
||||
|
||||
render action
|
||||
end
|
||||
def reset_health_check_token
|
||||
@application_setting.reset_health_check_access_token!
|
||||
flash[:notice] = _('New health check access token has been generated!')
|
||||
redirect_back_or_default
|
||||
end
|
||||
|
||||
def remove_blank_params_for!(*keys)
|
||||
params[:application_setting].delete_if { |setting, value| setting.to_sym.in?(keys) && value.blank? }
|
||||
end
|
||||
def reset_error_tracking_access_token
|
||||
@application_setting.reset_error_tracking_access_token!
|
||||
|
||||
# overridden in EE
|
||||
def valid_setting_panels
|
||||
VALID_SETTING_PANELS
|
||||
end
|
||||
redirect_to general_admin_application_settings_path,
|
||||
notice: _('New error tracking access token has been generated!')
|
||||
end
|
||||
|
||||
def prerecorded_service_ping_data
|
||||
@service_ping_data ||= Rails.cache.fetch(Gitlab::Usage::ServicePingReport::CACHE_KEY) ||
|
||||
::RawUsageData.for_current_reporting_cycle.first&.payload
|
||||
def clear_repository_check_states
|
||||
RepositoryCheck::ClearWorker.perform_async # rubocop:disable CodeReuse/Worker
|
||||
|
||||
redirect_to(
|
||||
general_admin_application_settings_path,
|
||||
notice: _('Started asynchronous removal of all repository check states.')
|
||||
)
|
||||
end
|
||||
|
||||
# Getting ToS url requires `directory` api call to Let's Encrypt
|
||||
# which could result in 500 error/slow rendering on settings page
|
||||
# Because of that we use separate controller action
|
||||
def lets_encrypt_terms_of_service
|
||||
redirect_to ::Gitlab::LetsEncrypt.terms_of_service_url
|
||||
end
|
||||
|
||||
def slack_app_manifest_share
|
||||
redirect_to Slack::Manifest.share_url
|
||||
end
|
||||
|
||||
def slack_app_manifest_download
|
||||
send_data Slack::Manifest.to_json, type: :json, disposition: 'attachment', filename: 'slack_manifest.json'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_application_setting
|
||||
@application_setting = ApplicationSetting.current_without_cache
|
||||
@plans = Plan.all
|
||||
end
|
||||
|
||||
def disable_query_limiting
|
||||
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/29418')
|
||||
end
|
||||
|
||||
def application_setting_params # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
||||
params[:application_setting] ||= {}
|
||||
|
||||
if params[:application_setting].key?(:enabled_oauth_sign_in_sources)
|
||||
enabled_oauth_sign_in_sources = params[:application_setting].delete(:enabled_oauth_sign_in_sources)
|
||||
enabled_oauth_sign_in_sources&.delete("")
|
||||
|
||||
params[:application_setting][:disabled_oauth_sign_in_sources] =
|
||||
AuthHelper.button_based_providers.map(&:to_s) -
|
||||
Array(enabled_oauth_sign_in_sources)
|
||||
end
|
||||
|
||||
params[:application_setting][:import_sources]&.delete("")
|
||||
params[:application_setting][:valid_runner_registrars]&.delete("")
|
||||
params[:application_setting][:restricted_visibility_levels]&.delete("")
|
||||
|
||||
params[:application_setting][:package_metadata_purl_types]&.delete("")
|
||||
params[:application_setting][:package_metadata_purl_types]&.map!(&:to_i)
|
||||
|
||||
normalize_default_branch_params!(:application_setting)
|
||||
|
||||
if params[:application_setting][:required_instance_ci_template].blank?
|
||||
params[:application_setting][:required_instance_ci_template] = nil
|
||||
end
|
||||
|
||||
remove_blank_params_for!(:elasticsearch_aws_secret_access_key, :eks_secret_access_key)
|
||||
|
||||
# TODO Remove domain_denylist_raw in APIv5 (See https://gitlab.com/gitlab-org/gitlab-foss/issues/67204)
|
||||
params.delete(:domain_denylist_raw) if params[:domain_denylist_file]
|
||||
params.delete(:domain_denylist_raw) if params[:domain_denylist]
|
||||
params.delete(:domain_allowlist_raw) if params[:domain_allowlist]
|
||||
|
||||
params[:application_setting].permit(visible_application_setting_attributes)
|
||||
end
|
||||
|
||||
def recheck_user_consent?
|
||||
return false unless session[:ask_for_usage_stats_consent]
|
||||
return false unless params[:application_setting]
|
||||
|
||||
params[:application_setting].key?(:usage_ping_enabled) ||
|
||||
params[:application_setting].key?(:version_check_enabled)
|
||||
end
|
||||
|
||||
def visible_application_setting_attributes
|
||||
[
|
||||
*::ApplicationSettingsHelper.visible_attributes,
|
||||
*::ApplicationSettingsHelper.external_authorization_service_attributes,
|
||||
*ApplicationSetting.kroki_formats_attributes.keys.map { |key| :"kroki_formats_#{key}" },
|
||||
{ default_branch_protection_defaults: [
|
||||
:allow_force_push,
|
||||
:developer_can_initial_push,
|
||||
{
|
||||
allowed_to_merge: [:access_level],
|
||||
allowed_to_push: [:access_level]
|
||||
}
|
||||
] },
|
||||
:lets_encrypt_notification_email,
|
||||
:lets_encrypt_terms_of_service_accepted,
|
||||
:domain_denylist_file,
|
||||
:raw_blob_request_limit,
|
||||
:issues_create_limit,
|
||||
:notes_create_limit,
|
||||
:pipeline_limit_per_project_user_sha,
|
||||
:default_branch_name,
|
||||
:auto_approve_pending_users,
|
||||
{ disabled_oauth_sign_in_sources: [],
|
||||
import_sources: [],
|
||||
package_metadata_purl_types: [],
|
||||
restricted_visibility_levels: [],
|
||||
repository_storages_weighted: {},
|
||||
valid_runner_registrars: [] }
|
||||
]
|
||||
end
|
||||
|
||||
def submitted?
|
||||
request.patch?
|
||||
end
|
||||
|
||||
def perform_update
|
||||
successful = ::ApplicationSettings::UpdateService
|
||||
.new(@application_setting, current_user, application_setting_params)
|
||||
.execute
|
||||
|
||||
session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent? if recheck_user_consent?
|
||||
|
||||
redirect_path = referer_path(request) || general_admin_application_settings_path
|
||||
|
||||
respond_to do |format|
|
||||
if successful
|
||||
format.json { head :ok }
|
||||
format.html { redirect_to redirect_path, notice: _('Application settings saved successfully') }
|
||||
else
|
||||
format.json { head :bad_request }
|
||||
format.html { render_update_error }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_update_error
|
||||
action = valid_setting_panels.include?(action_name) ? action_name : :general
|
||||
|
||||
flash[:alert] = _('Application settings update failed')
|
||||
|
||||
render action
|
||||
end
|
||||
|
||||
def remove_blank_params_for!(*keys)
|
||||
params[:application_setting].delete_if { |setting, value| setting.to_sym.in?(keys) && value.blank? }
|
||||
end
|
||||
|
||||
# overridden in EE
|
||||
def valid_setting_panels
|
||||
VALID_SETTING_PANELS
|
||||
end
|
||||
|
||||
def prerecorded_service_ping_data
|
||||
@service_ping_data ||= Rails.cache.fetch(Gitlab::Usage::ServicePingReport::CACHE_KEY) ||
|
||||
::RawUsageData.for_current_reporting_cycle.first&.payload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,3 +18,5 @@ class Admin::JobsController < Admin::ApplicationController
|
|||
redirect_to admin_jobs_path, status: :see_other
|
||||
end
|
||||
end
|
||||
|
||||
Admin::JobsController.prepend_mod
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
|||
include Gitlab::GonHelper
|
||||
include InitializesCurrentUserMode
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
include RequestPayloadLogger
|
||||
|
||||
alias_method :auth_user, :current_user
|
||||
|
||||
prepend_before_action :set_current_organization
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ module Projects
|
|||
push_frontend_feature_flag(:ci_variables_pages, current_user)
|
||||
push_frontend_feature_flag(:allow_push_repository_for_job_token, @project)
|
||||
push_frontend_feature_flag(:add_policies_to_ci_job_token, @project)
|
||||
push_frontend_feature_flag(:authentication_logs_migration_for_allowlist, @project)
|
||||
|
||||
push_frontend_ability(ability: :admin_project, resource: @project, user: current_user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ module MergeRequests
|
|||
],
|
||||
'properties' => {
|
||||
'current_user_id' => { 'type' => 'integer' },
|
||||
'merge_request_id' => { 'type' => 'integer' }
|
||||
'merge_request_id' => { 'type' => 'integer' },
|
||||
'approved_at' => { 'type' => 'string', 'format' => 'date-time' }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ module Ci
|
|||
end
|
||||
|
||||
def all_jobs
|
||||
raise Gitlab::Access::AccessDeniedError unless current_user&.can_admin_all_resources?
|
||||
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_admin_cicd)
|
||||
|
||||
type.all
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
module JobsHelper
|
||||
def admin_jobs_app_data
|
||||
{
|
||||
job_statuses: job_statuses.to_json,
|
||||
empty_state_svg_path: image_path('illustrations/empty-state/empty-pipeline-md.svg'),
|
||||
url: cancel_all_admin_jobs_path,
|
||||
can_update_all_jobs: current_user.can_admin_all_resources?.to_s
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -730,14 +730,11 @@ module ProjectsHelper
|
|||
end
|
||||
|
||||
def delete_immediately_message(project)
|
||||
message = _('This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this ' \
|
||||
'project contains. %{strongOpen}There is no going back.%{strongClose}')
|
||||
|
||||
ERB::Util.html_escape(message) % delete_message_data(project)
|
||||
_('This action will permanently delete this project, including all its resources.')
|
||||
end
|
||||
|
||||
def project_delete_immediately_button_data(project)
|
||||
project_delete_button_shared_data(project).merge({
|
||||
def project_delete_immediately_button_data(project, button_text = nil)
|
||||
project_delete_button_shared_data(project, button_text).merge({
|
||||
form_path: project_path(project, permanently_delete: true)
|
||||
})
|
||||
end
|
||||
|
|
@ -767,7 +764,7 @@ module ProjectsHelper
|
|||
}
|
||||
end
|
||||
|
||||
def project_delete_button_shared_data(project)
|
||||
def project_delete_button_shared_data(project, button_text = nil)
|
||||
merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count
|
||||
issues_count = Projects::AllIssuesCountService.new(project).count
|
||||
forks_count = Projects::ForksCountService.new(project).count
|
||||
|
|
@ -778,7 +775,8 @@ module ProjectsHelper
|
|||
issues_count: number_with_delimiter(issues_count),
|
||||
merge_requests_count: number_with_delimiter(merge_requests_count),
|
||||
forks_count: number_with_delimiter(forks_count),
|
||||
stars_count: number_with_delimiter(project.star_count)
|
||||
stars_count: number_with_delimiter(project.star_count),
|
||||
button_text: button_text.presence || _('Delete project')
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MergeRequest::ApprovalMetrics < ApplicationRecord # rubocop:disable Style/ClassAndModuleChildren, Gitlab/BoundedContexts -- Same as the rest of the models
|
||||
belongs_to :merge_request, optional: false
|
||||
belongs_to :target_project, class_name: 'Project', inverse_of: :merge_requests, optional: false
|
||||
|
||||
validates :last_approved_at, presence: true
|
||||
|
||||
def self.refresh_last_approved_at(merge_request:, last_approved_at:)
|
||||
attributes = {
|
||||
merge_request_id: merge_request.id,
|
||||
target_project_id: merge_request.target_project_id,
|
||||
last_approved_at: last_approved_at
|
||||
}
|
||||
|
||||
upsert(
|
||||
attributes,
|
||||
unique_by: :merge_request_id,
|
||||
on_duplicate: Arel.sql(<<~SQL.squish)
|
||||
last_approved_at = GREATEST(excluded.last_approved_at, merge_request_approval_metrics.last_approved_at)
|
||||
SQL
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -149,6 +149,9 @@ class GlobalPolicy < BasePolicy
|
|||
enable :create_instance_runner
|
||||
enable :read_web_hook
|
||||
enable :admin_web_hook
|
||||
|
||||
# Admin pages
|
||||
enable :read_admin_cicd
|
||||
end
|
||||
|
||||
# We can't use `read_statistics` because the user may have different permissions for different projects
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ module Ci
|
|||
duration_query = query.select(*allowed_duration_percentiles.map { |p| query.duration_quantile_function(p) })
|
||||
duration_result = ::ClickHouse::Client.select(duration_query.to_sql, :main)
|
||||
result[:duration_statistics] = duration_result.first.symbolize_keys.transform_values do |interval|
|
||||
interval ? interval.to_f.round(3).seconds : nil
|
||||
interval ? interval.to_f.round(3).seconds : 0.0
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -176,11 +176,9 @@ module Ci
|
|||
return
|
||||
end
|
||||
|
||||
@logger.instrument(:process_build_link_identity) do
|
||||
# Make sure that composite identity is propagated to `PipelineProcessWorker`
|
||||
# when the build's status change.
|
||||
::Gitlab::Auth::Identity.link_from_job(build)
|
||||
end
|
||||
# Make sure that composite identity is propagated to `PipelineProcessWorker`
|
||||
# when the build's status change.
|
||||
::Gitlab::Auth::Identity.link_from_job(build)
|
||||
|
||||
# In case when 2 runners try to assign the same build, second runner will be declined
|
||||
# with StateMachines::InvalidTransition or StaleObjectError when doing run! or save method.
|
||||
|
|
@ -223,16 +221,12 @@ module Ci
|
|||
def remove_from_queue!(build)
|
||||
@metrics.increment_queue_operation(:build_not_pending)
|
||||
|
||||
@logger.instrument(:process_build_not_pending) do
|
||||
##
|
||||
# If this build can not be picked because we had stale data in
|
||||
# `ci_pending_builds` table, we need to respond with 409 to retry
|
||||
# this operation.
|
||||
#
|
||||
if ::Ci::UpdateBuildQueueService.new.remove!(build)
|
||||
Result.new(nil, nil, nil, false)
|
||||
end
|
||||
end
|
||||
##
|
||||
# If this build can not be picked because we had stale data in
|
||||
# `ci_pending_builds` table, we need to respond with 409 to retry
|
||||
# this operation.
|
||||
#
|
||||
Result.new(nil, nil, nil, false) if ::Ci::UpdateBuildQueueService.new.remove!(build)
|
||||
end
|
||||
|
||||
def runner_matched?(build)
|
||||
|
|
@ -251,12 +245,18 @@ module Ci
|
|||
def present_build!(build)
|
||||
# We need to use the presenter here because Gitaly calls in the presenter
|
||||
# may fail, and we need to ensure the response has been generated.
|
||||
presented_build = ::Ci::BuildRunnerPresenter.new(build) # rubocop:disable CodeReuse/Presenter
|
||||
presented_build = @logger.instrument(:present_build_presenter) do
|
||||
::Ci::BuildRunnerPresenter.new(build) # rubocop:disable CodeReuse/Presenter -- old code
|
||||
end
|
||||
|
||||
log_artifacts_context(build)
|
||||
log_build_dependencies_size(presented_build)
|
||||
@logger.instrument(:present_build_logs) do
|
||||
log_artifacts_context(build)
|
||||
log_build_dependencies_size(presented_build)
|
||||
end
|
||||
|
||||
build_json = Gitlab::Json.dump(::API::Entities::Ci::JobRequest::Response.new(presented_build))
|
||||
build_json = @logger.instrument(:present_build_response_json) do
|
||||
Gitlab::Json.dump(::API::Entities::Ci::JobRequest::Response.new(presented_build))
|
||||
end
|
||||
Result.new(build, build_json, presented_build, true)
|
||||
end
|
||||
|
||||
|
|
@ -282,16 +282,22 @@ module Ci
|
|||
build.runner_id = runner.id
|
||||
build.runner_session_attributes = params[:session] if params[:session].present?
|
||||
|
||||
failure_reason, _ = pre_assign_runner_checks.find { |_, check| check.call(build, params) }
|
||||
failure_reason, _ = @logger.instrument(:assign_runner_failure_reason) do
|
||||
pre_assign_runner_checks.find { |_, check| check.call(build, params) }
|
||||
end
|
||||
|
||||
if failure_reason
|
||||
@metrics.increment_queue_operation(:runner_pre_assign_checks_failed)
|
||||
|
||||
build.drop!(failure_reason)
|
||||
@logger.instrument(:assign_runner_drop) do
|
||||
build.drop!(failure_reason)
|
||||
end
|
||||
else
|
||||
@metrics.increment_queue_operation(:runner_pre_assign_checks_success)
|
||||
|
||||
build.run!
|
||||
@logger.instrument(:assign_runner_run) do
|
||||
build.run!
|
||||
end
|
||||
persist_runtime_features(build, params)
|
||||
|
||||
build.runner_manager = runner_manager if runner_manager
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ module MergeRequests
|
|||
# Workers can subscribe to the `MergeRequests::ApprovedEvent`.
|
||||
Gitlab::EventStore.publish(
|
||||
MergeRequests::ApprovedEvent.new(
|
||||
data: { current_user_id: current_user.id, merge_request_id: merge_request.id }
|
||||
data: { current_user_id: current_user.id, merge_request_id: merge_request.id,
|
||||
approved_at: approval.created_at.iso8601 }
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
- page_title _("Jobs")
|
||||
|
||||
|
||||
#admin-jobs-app{ data: { job_statuses: job_statuses.to_json, empty_state_svg_path: image_path('illustrations/empty-state/empty-pipeline-md.svg'), url: cancel_all_admin_jobs_path } }
|
||||
#admin-jobs-app{ data: admin_jobs_app_data }
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
- c.with_body do
|
||||
= form_tag(group, method: :delete, id: remove_form_id) do
|
||||
%p
|
||||
= _('Deleting this group also deletes all child projects, including archived projects, and their resources.')
|
||||
%br
|
||||
%strong= _('Deleted group can not be restored!')
|
||||
= _('This action will permanently delete this group, including its subgroups and projects.')
|
||||
|
||||
= render 'groups/settings/remove_button', group: group, remove_form_id: remove_form_id
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
- remove_form_id = local_assigns.fetch(:remove_form_id, nil)
|
||||
- button_text = local_assigns.fetch(:button_text, nil)
|
||||
|
||||
- if group.linked_to_subscription?
|
||||
= render Pajamas::AlertComponent.new(variant: :tip, dismissible: false, alert_options: { class: 'gl-mb-5', data: { testid: 'group-has-linked-subscription-alert' }}) do |c|
|
||||
- c.with_body do
|
||||
= html_escape(_("This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/gitlab_com/index.md', anchor: 'link-subscription-to-a-group')}\">".html_safe, linkEnd: '</a>'.html_safe }
|
||||
|
||||
.js-confirm-danger{ data: group_confirm_modal_data(group: group, remove_form_id: remove_form_id) }
|
||||
.js-confirm-danger{ data: group_confirm_modal_data(group: group, remove_form_id: remove_form_id, button_text: button_text) }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
- return unless can?(current_user, :remove_project, @project)
|
||||
- title = @project.marked_for_deletion_at.present? ? _('Delete project immediately') : _('Delete project')
|
||||
|
||||
= render Pajamas::CardComponent.new(header_options: { class: 'gl-px-5 gl-py-4 gl-border-b-1 gl-border-b-solid gl-border-default' }, body_options: { class: 'gl-bg-red-50 gl-px-5 gl-py-4' }) do |c|
|
||||
= render Pajamas::CardComponent.new(body_options: { class: 'gl-bg-red-50' }) do |c|
|
||||
- c.with_header do
|
||||
.gl-flex.gl-grow
|
||||
%h4.gl-text-base.gl-leading-24.gl-m-0.danger-title= _('Delete this project')
|
||||
%h4.gl-text-base.gl-leading-24.gl-m-0.gl-text-red-500= title
|
||||
|
||||
- c.with_body do
|
||||
= render 'projects/delete_card_body'
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
- button_text = local_assigns.fetch(:button_text, nil)
|
||||
|
||||
%p
|
||||
= delete_immediately_message(@project)
|
||||
#js-project-delete-button{ data: project_delete_immediately_button_data(@project) }
|
||||
#js-project-delete-button{ data: project_delete_immediately_button_data(@project, button_text) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: authentication_logs_migration_for_allowlist
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/498125
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178429
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/514159
|
||||
milestone: '17.9'
|
||||
group: group::pipeline security
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/132517
|
|||
rollout_issue_url:
|
||||
milestone: '16.5'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/99287
|
|||
rollout_issue_url:
|
||||
milestone: '15.7'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ name: detect_cross_database_modification
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73316
|
||||
milestone: '14.5'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: false
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129748
|
|||
rollout_issue_url:
|
||||
milestone: '16.4'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128538
|
|||
rollout_issue_url:
|
||||
milestone: '16.4'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: false
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128538
|
|||
rollout_issue_url:
|
||||
milestone: '16.4'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: false
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120926
|
|||
rollout_issue_url:
|
||||
milestone: '16.1'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ name: query_analyzer_gitlab_schema_metrics
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73839
|
||||
milestone: '14.5'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: false
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121957
|
|||
rollout_issue_url:
|
||||
milestone: '16.1'
|
||||
type: ops
|
||||
group: group::tenant scale
|
||||
group: group::cells infrastructure
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ data_category: operational
|
|||
instrumentation_class: CountCiInternalPipelinesMetric
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
status: 2
|
||||
has_failures: true
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
status: 2
|
||||
has_failures: false
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
status: 2
|
||||
has_failures: true
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
status: 2
|
||||
has_failures: false
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@ options:
|
|||
events:
|
||||
- github_import_project_cancelled
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@ options:
|
|||
events:
|
||||
- github_import_project_partially_completed
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -23,9 +23,6 @@ events:
|
|||
unique: user.id
|
||||
performance_indicator_type:
|
||||
- gmau
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_quickactions_type
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ data_source: redis_hll
|
|||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@ data_category: operational
|
|||
instrumentation_class: CountAllCiBuildsMetric
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_editor_extensions_user_jetbrains_bundled_api_request
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ instrumentation_class: RedisHLLMetric
|
|||
options:
|
||||
events:
|
||||
- i_quickactions_unlink
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
- k8s_api_proxy_requests_unique_agents_via_ci_access
|
||||
performance_indicator_type:
|
||||
- smau
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- k8s_api_proxy_requests_unique_agents_via_user_access
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ events:
|
|||
- name: k8s_api_proxy_requests_unique_users_via_ci_access
|
||||
unique: user.id
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ events:
|
|||
- name: k8s_api_proxy_requests_unique_users_via_user_access
|
||||
unique: user.id
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- flux_git_push_notified_unique_projects
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: internal_events
|
||||
data_category: optional
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: internal_events
|
||||
data_category: optional
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: internal_events
|
||||
data_category: optional
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ data_source: redis_hll
|
|||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
tiers:
|
||||
- premium
|
||||
- ultimate
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: internal_events
|
||||
data_category: optional
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- k8s_api_proxy_requests_unique_agents_via_pat_access
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ events:
|
|||
- name: k8s_api_proxy_requests_unique_users_via_pat_access
|
||||
unique: user.id
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ data_source: redis_hll
|
|||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
events:
|
||||
- i_quickactions_set_parent
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
events:
|
||||
- i_quickactions_add_child
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ instrumentation_class: RedisHLLMetric
|
|||
options:
|
||||
events:
|
||||
- users_updating_work_item_todo
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_container_registry_push_tag_deploy_token
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_container_registry_delete_tag_deploy_token
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_container_registry_push_repository_deploy_token
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_container_registry_delete_repository_deploy_token
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ options:
|
|||
events:
|
||||
- i_container_registry_create_repository_deploy_token
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
events:
|
||||
- i_quickactions_remove_parent
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ options:
|
|||
events:
|
||||
- i_quickactions_remove_child
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ performance_indicator_type: []
|
|||
options:
|
||||
events:
|
||||
- i_quickactions_remind_me
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ time_frame: 28d
|
|||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/167165
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173261
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173261
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146834
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/132819
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/160635
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163352
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163352
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158070
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159484
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158070
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159484
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/171945
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/171945
|
|||
time_frame: 28d
|
||||
data_source: internal_events
|
||||
data_category: optional
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tiers:
|
||||
- free
|
||||
- premium
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue