Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1743439667
commit
a1ed241c82
|
@ -2647,113 +2647,6 @@ Style/FrozenStringLiteralComment:
|
|||
- 'app/views/projects/tags/index.atom.builder'
|
||||
- 'app/views/users/show.atom.builder'
|
||||
- 'bin/secpick'
|
||||
- 'config.ru'
|
||||
- 'config/boot.rb'
|
||||
- 'config/environment.rb'
|
||||
- 'config/environments/development.rb'
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/environments/test.rb'
|
||||
- 'config/initializers/01_secret_token.rb'
|
||||
- 'config/initializers/0_acts_as_taggable.rb'
|
||||
- 'config/initializers/0_inject_feature_flags.rb'
|
||||
- 'config/initializers/0_post_deployment_migrations.rb'
|
||||
- 'config/initializers/1_settings.rb'
|
||||
- 'config/initializers/2_gitlab.rb'
|
||||
- 'config/initializers/5_backend.rb'
|
||||
- 'config/initializers/6_validations.rb'
|
||||
- 'config/initializers/7_prometheus_metrics.rb'
|
||||
- 'config/initializers/7_redis.rb'
|
||||
- 'config/initializers/8_devise.rb'
|
||||
- 'config/initializers/8_gitaly.rb'
|
||||
- 'config/initializers/9_fast_gettext.rb'
|
||||
- 'config/initializers/action_dispatch_http_mime_negotiation.rb'
|
||||
- 'config/initializers/action_mailer_hooks.rb'
|
||||
- 'config/initializers/active_record_data_types.rb'
|
||||
- 'config/initializers/active_record_ping.rb'
|
||||
- 'config/initializers/active_record_preloader.rb'
|
||||
- 'config/initializers/active_record_schema_ignore_tables.rb'
|
||||
- 'config/initializers/active_record_table_definition.rb'
|
||||
- 'config/initializers/ar_speed_up_migration_checking.rb'
|
||||
- 'config/initializers/asset_proxy_settings.rb'
|
||||
- 'config/initializers/attr_encrypted_no_db_connection.rb'
|
||||
- 'config/initializers/backtrace_silencers.rb'
|
||||
- 'config/initializers/batch_loader.rb'
|
||||
- 'config/initializers/bootstrap_form.rb'
|
||||
- 'config/initializers/bullet.rb'
|
||||
- 'config/initializers/cluster_events_before_phased_restart.rb'
|
||||
- 'config/initializers/console_message.rb'
|
||||
- 'config/initializers/cookies_serializer.rb'
|
||||
- 'config/initializers/date_time_formats.rb'
|
||||
- 'config/initializers/default_url_options.rb'
|
||||
- 'config/initializers/deprecations.rb'
|
||||
- 'config/initializers/direct_upload_support.rb'
|
||||
- 'config/initializers/doorkeeper.rb'
|
||||
- 'config/initializers/doorkeeper_openid_connect.rb'
|
||||
- 'config/initializers/etag_caching.rb'
|
||||
- 'config/initializers/fill_shards.rb'
|
||||
- 'config/initializers/fix_local_cache_middleware.rb'
|
||||
- 'config/initializers/fog_google_https_private_urls.rb'
|
||||
- 'config/initializers/forbid_sidekiq_in_transactions.rb'
|
||||
- 'config/initializers/gettext_rails_i18n_patch.rb'
|
||||
- 'config/initializers/gitlab_kas_secret.rb'
|
||||
- 'config/initializers/gitlab_shell_secret_token.rb'
|
||||
- 'config/initializers/gitlab_workhorse_secret.rb'
|
||||
- 'config/initializers/go_get.rb'
|
||||
- 'config/initializers/grpc.rb'
|
||||
- 'config/initializers/hamlit.rb'
|
||||
- 'config/initializers/health_check.rb'
|
||||
- 'config/initializers/http_hostname_override.rb'
|
||||
- 'config/initializers/kaminari_active_record_relation_methods_with_limit.rb'
|
||||
- 'config/initializers/kaminari_config.rb'
|
||||
- 'config/initializers/lograge.rb'
|
||||
- 'config/initializers/mail_encoding_patch.rb'
|
||||
- 'config/initializers/mime_types.rb'
|
||||
- 'config/initializers/mini_magick.rb'
|
||||
- 'config/initializers/new_framework_defaults.rb'
|
||||
- 'config/initializers/octokit.rb'
|
||||
- 'config/initializers/omniauth.rb'
|
||||
- 'config/initializers/peek.rb'
|
||||
- 'config/initializers/postgresql_cte.rb'
|
||||
- 'config/initializers/premailer.rb'
|
||||
- 'config/initializers/query_limiting.rb'
|
||||
- 'config/initializers/rack_lineprof.rb'
|
||||
- 'config/initializers/relative_naming_ci_namespace.rb'
|
||||
- 'config/initializers/request_context.rb'
|
||||
- 'config/initializers/request_profiler.rb'
|
||||
- 'config/initializers/routing_draw.rb'
|
||||
- 'config/initializers/sentry.rb'
|
||||
- 'config/initializers/server_uptime.rb'
|
||||
- 'config/initializers/session_store.rb'
|
||||
- 'config/initializers/sherlock.rb'
|
||||
- 'config/initializers/sprockets.rb'
|
||||
- 'config/initializers/static_files.rb'
|
||||
- 'config/initializers/time_zone.rb'
|
||||
- 'config/initializers/trusted_proxies.rb'
|
||||
- 'config/initializers/warden.rb'
|
||||
- 'config/initializers/workhorse_multipart.rb'
|
||||
- 'config/initializers/wrap_parameters.rb'
|
||||
- 'config/initializers/zz_metrics.rb'
|
||||
- 'config/initializers_before_autoloader/000_inflections.rb'
|
||||
- 'config/object_store_settings.rb'
|
||||
- 'config/routes.rb'
|
||||
- 'config/routes/admin.rb'
|
||||
- 'config/routes/api.rb'
|
||||
- 'config/routes/dashboard.rb'
|
||||
- 'config/routes/development.rb'
|
||||
- 'config/routes/explore.rb'
|
||||
- 'config/routes/git_http.rb'
|
||||
- 'config/routes/google_api.rb'
|
||||
- 'config/routes/help.rb'
|
||||
- 'config/routes/import.rb'
|
||||
- 'config/routes/legacy_builds.rb'
|
||||
- 'config/routes/repository.rb'
|
||||
- 'config/routes/sherlock.rb'
|
||||
- 'config/routes/sidekiq.rb'
|
||||
- 'config/routes/snippets.rb'
|
||||
- 'config/routes/uploads.rb'
|
||||
- 'config/routes/wiki.rb'
|
||||
- 'config/smime_signature_settings.rb'
|
||||
- 'config/spring.rb'
|
||||
- 'danger/changes_size/Dangerfile'
|
||||
- 'danger/metadata/Dangerfile'
|
||||
- 'db/migrate/20190325080727_truncate_user_fullname.rb'
|
||||
|
|
|
@ -86,16 +86,16 @@ export default {
|
|||
return !this.disabled && this.listType !== ListType.closed;
|
||||
},
|
||||
showMilestoneListDetails() {
|
||||
return (
|
||||
this.listType === ListType.milestone &&
|
||||
this.list.milestone &&
|
||||
(!this.list.collapsed || !this.isSwimlanesHeader)
|
||||
);
|
||||
return this.listType === ListType.milestone && this.list.milestone && this.showListDetails;
|
||||
},
|
||||
showAssigneeListDetails() {
|
||||
return (
|
||||
this.listType === ListType.assignee && (!this.list.collapsed || !this.isSwimlanesHeader)
|
||||
);
|
||||
return this.listType === ListType.assignee && this.showListDetails;
|
||||
},
|
||||
showIterationListDetails() {
|
||||
return this.listType === ListType.iteration && this.showListDetails;
|
||||
},
|
||||
showListDetails() {
|
||||
return !this.list.collapsed || !this.isSwimlanesHeader;
|
||||
},
|
||||
issuesCount() {
|
||||
return this.list.issuesCount;
|
||||
|
@ -218,6 +218,17 @@ export default {
|
|||
<gl-icon name="timer" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="showIterationListDetails"
|
||||
aria-hidden="true"
|
||||
:class="{
|
||||
'gl-mt-3 gl-rotate-90': list.collapsed,
|
||||
'gl-mr-2': !list.collapsed,
|
||||
}"
|
||||
>
|
||||
<gl-icon name="iteration" />
|
||||
</span>
|
||||
|
||||
<a
|
||||
v-if="showAssigneeListDetails"
|
||||
:href="list.assignee.webUrl"
|
||||
|
|
|
@ -78,14 +78,16 @@ export default {
|
|||
return !this.disabled && this.listType !== ListType.closed;
|
||||
},
|
||||
showMilestoneListDetails() {
|
||||
return (
|
||||
this.list.type === 'milestone' &&
|
||||
this.list.milestone &&
|
||||
(this.list.isExpanded || !this.isSwimlanesHeader)
|
||||
);
|
||||
return this.list.type === 'milestone' && this.list.milestone && this.showListDetails;
|
||||
},
|
||||
showAssigneeListDetails() {
|
||||
return this.list.type === 'assignee' && (this.list.isExpanded || !this.isSwimlanesHeader);
|
||||
return this.list.type === 'assignee' && this.showListDetails;
|
||||
},
|
||||
showIterationListDetails() {
|
||||
return this.listType === ListType.iteration && this.showListDetails;
|
||||
},
|
||||
showListDetails() {
|
||||
return this.list.isExpanded || !this.isSwimlanesHeader;
|
||||
},
|
||||
issuesCount() {
|
||||
return this.list.issuesSize;
|
||||
|
@ -203,6 +205,17 @@ export default {
|
|||
<gl-icon name="timer" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="showIterationListDetails"
|
||||
aria-hidden="true"
|
||||
:class="{
|
||||
'gl-mt-3 gl-rotate-90': !list.isExpanded,
|
||||
'gl-mr-2': list.isExpanded,
|
||||
}"
|
||||
>
|
||||
<gl-icon name="iteration" />
|
||||
</span>
|
||||
|
||||
<a
|
||||
v-if="showAssigneeListDetails"
|
||||
:href="list.assignee.path"
|
||||
|
|
|
@ -5,17 +5,13 @@ import { __ } from '~/locale';
|
|||
import boardsStore from '~/boards/stores/boards_store';
|
||||
import eventHub from '~/sidebar/event_hub';
|
||||
import { isScopedLabel } from '~/lib/utils/common_utils';
|
||||
import { LIST } from '~/boards/constants';
|
||||
import { LIST, ListType, ListTypeTitles } from '~/boards/constants';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
|
||||
// NOTE: need to revisit how we handle headerHeight, because we have so many different header and footer options.
|
||||
export default {
|
||||
headerHeight: process.env.NODE_ENV === 'development' ? '75px' : '40px',
|
||||
listSettingsText: __('List settings'),
|
||||
assignee: 'assignee',
|
||||
milestone: 'milestone',
|
||||
label: 'label',
|
||||
labelListText: __('Label'),
|
||||
components: {
|
||||
GlButton,
|
||||
GlDrawer,
|
||||
|
@ -33,6 +29,11 @@ export default {
|
|||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ListType,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isSidebarOpen', 'shouldUseGraphQL']),
|
||||
...mapState(['activeId', 'sidebarType', 'boardLists']),
|
||||
|
@ -56,7 +57,7 @@ export default {
|
|||
return this.activeList.type || this.activeList.listType || null;
|
||||
},
|
||||
listTypeTitle() {
|
||||
return this.$options.labelListText;
|
||||
return ListTypeTitles[ListType.label];
|
||||
},
|
||||
showSidebar() {
|
||||
return this.sidebarType === LIST;
|
||||
|
@ -98,7 +99,7 @@ export default {
|
|||
>
|
||||
<template #header>{{ $options.listSettingsText }}</template>
|
||||
<template v-if="isSidebarOpen">
|
||||
<div v-if="boardListType === $options.label">
|
||||
<div v-if="boardListType === ListType.label">
|
||||
<label class="js-list-label gl-display-block">{{ listTypeTitle }}</label>
|
||||
<gl-label
|
||||
:title="activeListLabel.title"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { __ } from '~/locale';
|
||||
|
||||
export const BoardType = {
|
||||
project: 'project',
|
||||
group: 'group',
|
||||
|
@ -6,11 +8,19 @@ export const BoardType = {
|
|||
export const ListType = {
|
||||
assignee: 'assignee',
|
||||
milestone: 'milestone',
|
||||
iteration: 'iteration',
|
||||
backlog: 'backlog',
|
||||
closed: 'closed',
|
||||
label: 'label',
|
||||
};
|
||||
|
||||
export const ListTypeTitles = {
|
||||
assignee: __('Assignee'),
|
||||
milestone: __('Milestone'),
|
||||
iteration: __('Iteration'),
|
||||
label: __('Label'),
|
||||
};
|
||||
|
||||
export const inactiveId = 0;
|
||||
|
||||
export const ISSUABLE = 'issuable';
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
export default class ListIteration {
|
||||
constructor(obj) {
|
||||
this.id = obj.id;
|
||||
this.title = obj.title;
|
||||
this.state = obj.state;
|
||||
this.webUrl = obj.web_url || obj.webUrl;
|
||||
this.description = obj.description;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import boardsStore from '../stores/boards_store';
|
|||
import ListLabel from './label';
|
||||
import ListAssignee from './assignee';
|
||||
import ListMilestone from './milestone';
|
||||
import ListIteration from './iteration';
|
||||
import 'ee_else_ce/boards/models/issue';
|
||||
|
||||
const TYPES = {
|
||||
|
@ -57,6 +58,9 @@ class List {
|
|||
} else if (IS_EE && obj.milestone) {
|
||||
this.milestone = new ListMilestone(obj.milestone);
|
||||
this.title = this.milestone.title;
|
||||
} else if (IS_EE && obj.iteration) {
|
||||
this.iteration = new ListIteration(obj.iteration);
|
||||
this.title = this.iteration.title;
|
||||
}
|
||||
|
||||
// doNotFetchIssues is a temporary workaround until issues are fetched using GraphQL on issue boards
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
/* eslint-disable vue/no-v-html */
|
||||
import { GlLoadingIcon, GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { showLearnGitLabGroupItemPopover } from '~/onboarding_issues';
|
||||
import { visitUrl } from '../../lib/utils/url_utility';
|
||||
import identicon from '../../vue_shared/components/identicon.vue';
|
||||
import eventHub from '../event_hub';
|
||||
|
@ -77,11 +76,6 @@ export default {
|
|||
return this.group.microdata || {};
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.group.name === 'Learn GitLab') {
|
||||
showLearnGitLabGroupItemPopover(this.group.id);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClickRowGroup(e) {
|
||||
const NO_EXPAND_CLS = 'no-expand';
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
import $ from 'jquery';
|
||||
import { parseBoolean, getCookie, setCookie, removeCookie } from '~/lib/utils/common_utils';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
|
||||
const COOKIE_NAME = 'onboarding_issues_settings';
|
||||
|
||||
const POPOVER_LOCATIONS = {
|
||||
GROUPS_SHOW: 'groups#show',
|
||||
PROJECTS_SHOW: 'projects#show',
|
||||
ISSUES_INDEX: 'issues#index',
|
||||
};
|
||||
|
||||
const removeLearnGitLabCookie = () => {
|
||||
removeCookie(COOKIE_NAME);
|
||||
};
|
||||
|
||||
function disposePopover(event) {
|
||||
event.preventDefault();
|
||||
this.popover('dispose');
|
||||
removeLearnGitLabCookie();
|
||||
Tracking.event('Growth::Conversion::Experiment::OnboardingIssues', 'dismiss_popover');
|
||||
}
|
||||
|
||||
const showPopover = (el, path, footer, options) => {
|
||||
// Cookie value looks like `{ 'groups#show': true, 'projects#show': true, 'issues#index': true }`. When it doesn't exist, don't show the popover.
|
||||
const cookie = getCookie(COOKIE_NAME);
|
||||
if (!cookie) return;
|
||||
|
||||
// When the popover action has already been taken, don't show the popover.
|
||||
const settings = JSON.parse(cookie);
|
||||
if (!parseBoolean(settings[path])) return;
|
||||
|
||||
const defaultOptions = {
|
||||
boundary: 'window',
|
||||
html: true,
|
||||
placement: 'top',
|
||||
template: `<div class="gl-popover popover blue learn-gitlab d-none d-xl-block" role="tooltip">
|
||||
<div class="arrow"></div>
|
||||
<div class="js-close-learn-gitlab gl-font-weight-bold gl-line-height-normal float-right gl-cursor-pointer gl-font-base gl-text-white gl-opacity-10 gl-p-3">✕</div>
|
||||
<div class="popover-body gl-font-base"></div>
|
||||
<div class="gl-font-weight-bold gl-text-right gl-text-white gl-p-3 gl-pt-0">${footer}</div>
|
||||
</div>`,
|
||||
};
|
||||
|
||||
// When one of the popovers is dismissed, remove the cookie.
|
||||
const closeButton = () => document.querySelector('.js-close-learn-gitlab');
|
||||
|
||||
// We still have to use jQuery, since Bootstrap's Popover is based on jQuery.
|
||||
const jQueryEl = $(el);
|
||||
const clickCloseButton = disposePopover.bind(jQueryEl);
|
||||
|
||||
jQueryEl
|
||||
.popover({ ...defaultOptions, ...options })
|
||||
.on('inserted.bs.popover', () => closeButton().addEventListener('click', clickCloseButton))
|
||||
.on('hide.bs.dropdown', () => closeButton().removeEventListener('click', clickCloseButton))
|
||||
.popover('show');
|
||||
|
||||
// The previous popover actions have been taken, don't show those popovers anymore.
|
||||
Object.keys(settings).forEach((pathSetting) => {
|
||||
if (path !== pathSetting) {
|
||||
settings[pathSetting] = false;
|
||||
} else {
|
||||
setCookie(COOKIE_NAME, settings);
|
||||
}
|
||||
});
|
||||
|
||||
// The final popover action will be taken on click, we then no longer need the cookie.
|
||||
if (path === POPOVER_LOCATIONS.ISSUES_INDEX) {
|
||||
el.addEventListener('click', removeLearnGitLabCookie);
|
||||
}
|
||||
};
|
||||
|
||||
export const showLearnGitLabGroupItemPopover = (id) => {
|
||||
const el = document.querySelector(`#group-${id} .group-text a`);
|
||||
|
||||
if (!el) return;
|
||||
|
||||
const options = {
|
||||
content: __(
|
||||
'Here are all your projects in your group, including the one you just created. To start, let’s take a look at your personalized learning project which will help you learn about GitLab at your own pace.',
|
||||
),
|
||||
};
|
||||
|
||||
showPopover(el, POPOVER_LOCATIONS.GROUPS_SHOW, '1 / 2', options);
|
||||
};
|
||||
|
||||
export const showLearnGitLabProjectPopover = () => {
|
||||
// Do not show a popover if we are not viewing the 'Learn GitLab' project.
|
||||
if (!window.location.pathname.includes('learn-gitlab')) return;
|
||||
|
||||
const el = document.querySelector('a.shortcuts-issues');
|
||||
|
||||
if (!el) return;
|
||||
|
||||
const options = {
|
||||
content: sprintf(
|
||||
__(
|
||||
'Go to %{strongStart}Issues%{strongEnd} > %{strongStart}Boards%{strongEnd} to access your personalized learning issue board.',
|
||||
),
|
||||
{ strongStart: '<strong>', strongEnd: '</strong>' },
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
showPopover(el, POPOVER_LOCATIONS.PROJECTS_SHOW, '2 / 2', options);
|
||||
};
|
||||
|
||||
export const showLearnGitLabIssuesPopover = () => {
|
||||
// Do not show a popover if we are not viewing the 'Learn GitLab' project.
|
||||
if (!window.location.pathname.includes('learn-gitlab')) return;
|
||||
|
||||
const el = document.querySelector('a[data-qa-selector="issue_boards_link"]');
|
||||
|
||||
if (!el) return;
|
||||
|
||||
const options = {
|
||||
content: sprintf(
|
||||
__(
|
||||
'Go to %{strongStart}Issues%{strongEnd} > %{strongStart}Boards%{strongEnd} to access your personalized learning issue board.',
|
||||
),
|
||||
{ strongStart: '<strong>', strongEnd: '</strong>' },
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
showPopover(el, POPOVER_LOCATIONS.ISSUES_INDEX, '2 / 2', options);
|
||||
};
|
|
@ -9,7 +9,6 @@ import { FILTERED_SEARCH } from '~/pages/constants';
|
|||
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
|
||||
import initIssuablesList from '~/issues_list';
|
||||
import initManualOrdering from '~/manual_ordering';
|
||||
import { showLearnGitLabIssuesPopover } from '~/onboarding_issues';
|
||||
|
||||
IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
|
||||
|
||||
|
@ -25,4 +24,3 @@ new UsersSelect();
|
|||
|
||||
initManualOrdering();
|
||||
initIssuablesList();
|
||||
showLearnGitLabIssuesPopover();
|
||||
|
|
|
@ -7,7 +7,6 @@ import BlobViewer from '~/blob/viewer/index';
|
|||
import Activities from '~/activities';
|
||||
import initReadMore from '~/read_more';
|
||||
import leaveByUrl from '~/namespaces/leave_by_url';
|
||||
import { showLearnGitLabProjectPopover } from '~/onboarding_issues';
|
||||
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
|
||||
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
|
||||
import initVueNotificationsDropdown from '~/notifications';
|
||||
|
@ -41,8 +40,6 @@ if (document.querySelector('.project-show-activity')) {
|
|||
|
||||
leaveByUrl('project');
|
||||
|
||||
showLearnGitLabProjectPopover();
|
||||
|
||||
if (gon.features?.vueNotificationDropdown) {
|
||||
initVueNotificationsDropdown();
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<script>
|
||||
import CommitForm from './commit_form.vue';
|
||||
import commitCIFile from '../../graphql/mutations/commit_ci_file.mutation.graphql';
|
||||
import getCommitSha from '../../graphql/queries/client/commit_sha.graphql';
|
||||
|
||||
import { COMMIT_FAILURE, COMMIT_SUCCESS } from '../../constants';
|
||||
import { mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
|
||||
const MR_SOURCE_BRANCH = 'merge_request[source_branch]';
|
||||
const MR_TARGET_BRANCH = 'merge_request[target_branch]';
|
||||
|
||||
export default {
|
||||
alertTexts: {
|
||||
[COMMIT_FAILURE]: s__('Pipelines|The GitLab CI configuration could not be updated.'),
|
||||
[COMMIT_SUCCESS]: __('Your changes have been successfully committed.'),
|
||||
},
|
||||
i18n: {
|
||||
defaultCommitMessage: __('Update %{sourcePath} file'),
|
||||
},
|
||||
components: {
|
||||
CommitForm,
|
||||
},
|
||||
inject: ['projectFullPath', 'ciConfigPath', 'defaultBranch', 'newMergeRequestPath'],
|
||||
props: {
|
||||
ciFileContent: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
commit: {},
|
||||
isSaving: false,
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
commitSha: {
|
||||
query: getCommitSha,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
defaultCommitMessage() {
|
||||
return sprintf(this.$options.i18n.defaultCommitMessage, { sourcePath: this.ciConfigPath });
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
redirectToNewMergeRequest(sourceBranch) {
|
||||
const url = mergeUrlParams(
|
||||
{
|
||||
[MR_SOURCE_BRANCH]: sourceBranch,
|
||||
[MR_TARGET_BRANCH]: this.defaultBranch,
|
||||
},
|
||||
this.newMergeRequestPath,
|
||||
);
|
||||
redirectTo(url);
|
||||
},
|
||||
async onCommitSubmit({ message, branch, openMergeRequest }) {
|
||||
this.isSaving = true;
|
||||
|
||||
try {
|
||||
const {
|
||||
data: {
|
||||
commitCreate: { errors },
|
||||
},
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: commitCIFile,
|
||||
variables: {
|
||||
projectPath: this.projectFullPath,
|
||||
branch,
|
||||
startBranch: this.defaultBranch,
|
||||
message,
|
||||
filePath: this.ciConfigPath,
|
||||
content: this.ciFileContent,
|
||||
lastCommitId: this.commitSha,
|
||||
},
|
||||
update(store, { data }) {
|
||||
const commitSha = data?.commitCreate?.commit?.sha;
|
||||
|
||||
if (commitSha) {
|
||||
store.writeQuery({ query: getCommitSha, data: { commitSha } });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (errors?.length) {
|
||||
this.$emit('showError', { type: COMMIT_FAILURE, reasons: errors });
|
||||
} else if (openMergeRequest) {
|
||||
this.redirectToNewMergeRequest(branch);
|
||||
} else {
|
||||
this.$emit('commit', { type: COMMIT_SUCCESS });
|
||||
}
|
||||
} catch (error) {
|
||||
this.$emit('showError', { type: COMMIT_FAILURE, reasons: [error?.message] });
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
}
|
||||
},
|
||||
onCommitCancel() {
|
||||
this.$emit('resetContent');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<commit-form
|
||||
:default-branch="defaultBranch"
|
||||
:default-message="defaultCommitMessage"
|
||||
:is-saving="isSaving"
|
||||
@cancel="onCommitCancel"
|
||||
@submit="onCommitSubmit"
|
||||
/>
|
||||
</template>
|
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
import ValidationSegment from './validation_segment.vue';
|
||||
|
||||
export default {
|
||||
validationSegmentClasses:
|
||||
'gl-p-5 gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100 gl-rounded-base',
|
||||
components: {
|
||||
ValidationSegment,
|
||||
},
|
||||
props: {
|
||||
ciConfigData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
isCiConfigDataLoading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="gl-mb-5">
|
||||
<validation-segment
|
||||
:class="$options.validationSegmentClasses"
|
||||
:loading="isCiConfigDataLoading"
|
||||
:ci-config="ciConfigData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,62 @@
|
|||
<script>
|
||||
import { GlLoadingIcon, GlTabs, GlTab } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import CiLint from './lint/ci_lint.vue';
|
||||
import EditorTab from './ui/editor_tab.vue';
|
||||
import TextEditor from './text_editor.vue';
|
||||
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
tabEdit: s__('Pipelines|Write pipeline configuration'),
|
||||
tabGraph: s__('Pipelines|Visualize'),
|
||||
tabLint: s__('Pipelines|Lint'),
|
||||
},
|
||||
components: {
|
||||
CiLint,
|
||||
EditorTab,
|
||||
GlLoadingIcon,
|
||||
GlTab,
|
||||
GlTabs,
|
||||
PipelineGraph,
|
||||
TextEditor,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
props: {
|
||||
ciConfigData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
ciFileContent: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
isCiConfigDataLoading: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-tabs class="file-editor gl-mb-3">
|
||||
<editor-tab :title="$options.i18n.tabEdit" lazy data-testid="editor-tab">
|
||||
<text-editor :value="ciFileContent" v-on="$listeners" />
|
||||
</editor-tab>
|
||||
<gl-tab
|
||||
v-if="glFeatures.ciConfigVisualizationTab"
|
||||
:title="$options.i18n.tabGraph"
|
||||
lazy
|
||||
data-testid="visualization-tab"
|
||||
>
|
||||
<gl-loading-icon v-if="isCiConfigDataLoading" size="lg" class="gl-m-3" />
|
||||
<pipeline-graph v-else :pipeline-data="ciConfigData" />
|
||||
</gl-tab>
|
||||
<editor-tab :title="$options.i18n.tabLint" data-testid="lint-tab">
|
||||
<gl-loading-icon v-if="isCiConfigDataLoading" size="lg" class="gl-m-3" />
|
||||
<ci-lint v-else :ci-config="ciConfigData" />
|
||||
</editor-tab>
|
||||
</gl-tabs>
|
||||
</template>
|
|
@ -2,26 +2,29 @@
|
|||
import EditorLite from '~/vue_shared/components/editor_lite.vue';
|
||||
import { CiSchemaExtension } from '~/editor/extensions/editor_ci_schema_ext';
|
||||
import { EDITOR_READY_EVENT } from '~/editor/constants';
|
||||
import getCommitSha from '../graphql/queries/client/commit_sha.graphql';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorLite,
|
||||
},
|
||||
inject: ['projectPath', 'projectNamespace'],
|
||||
inject: ['ciConfigPath', 'projectPath', 'projectNamespace'],
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
ciConfigPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
commitSha: '',
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
commitSha: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
query: getCommitSha,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onEditorReady() {
|
||||
onCiConfigUpdate(content) {
|
||||
this.$emit('updateCiConfig', content);
|
||||
},
|
||||
registerCiSchema() {
|
||||
const editorInstance = this.$refs.editor.getEditor();
|
||||
|
||||
editorInstance.use(new CiSchemaExtension());
|
||||
|
@ -41,7 +44,8 @@ export default {
|
|||
ref="editor"
|
||||
:file-name="ciConfigPath"
|
||||
v-bind="$attrs"
|
||||
@[$options.readyEvent]="onEditorReady"
|
||||
@[$options.readyEvent]="registerCiSchema"
|
||||
@input="onCiConfigUpdate"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,2 +1,9 @@
|
|||
export const CI_CONFIG_STATUS_VALID = 'VALID';
|
||||
export const CI_CONFIG_STATUS_INVALID = 'INVALID';
|
||||
|
||||
export const COMMIT_FAILURE = 'COMMIT_FAILURE';
|
||||
export const COMMIT_SUCCESS = 'COMMIT_SUCCESS';
|
||||
|
||||
export const DEFAULT_FAILURE = 'DEFAULT_FAILURE';
|
||||
export const LOAD_FAILURE_NO_FILE = 'LOAD_FAILURE_NO_FILE';
|
||||
export const LOAD_FAILURE_UNKNOWN = 'LOAD_FAILURE_UNKNOWN';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
mutation commitCIFileMutation(
|
||||
mutation commitCIFile(
|
||||
$projectPath: ID!
|
||||
$branch: String!
|
||||
$startBranch: String
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
query getCommitSha {
|
||||
commitSha @client
|
||||
}
|
|
@ -15,14 +15,13 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
|
|||
}
|
||||
|
||||
const {
|
||||
// props
|
||||
ciConfigPath,
|
||||
// Add to apollo cache as it can be updated by future queries
|
||||
commitSha,
|
||||
// Add to provide/inject API for static values
|
||||
ciConfigPath,
|
||||
defaultBranch,
|
||||
newMergeRequestPath,
|
||||
|
||||
// `provide/inject` data
|
||||
lintHelpPagePath,
|
||||
newMergeRequestPath,
|
||||
projectFullPath,
|
||||
projectPath,
|
||||
projectNamespace,
|
||||
|
@ -35,25 +34,27 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
|
|||
defaultClient: createDefaultClient(resolvers, { typeDefs }),
|
||||
});
|
||||
|
||||
apolloProvider.clients.defaultClient.cache.writeData({
|
||||
data: {
|
||||
commitSha,
|
||||
},
|
||||
});
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
apolloProvider,
|
||||
provide: {
|
||||
ciConfigPath,
|
||||
defaultBranch,
|
||||
lintHelpPagePath,
|
||||
newMergeRequestPath,
|
||||
projectFullPath,
|
||||
projectPath,
|
||||
projectNamespace,
|
||||
ymlHelpPagePath,
|
||||
},
|
||||
render(h) {
|
||||
return h(PipelineEditorApp, {
|
||||
props: {
|
||||
ciConfigPath,
|
||||
commitSha,
|
||||
defaultBranch,
|
||||
newMergeRequestPath,
|
||||
},
|
||||
});
|
||||
return h(PipelineEditorApp);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,87 +1,55 @@
|
|||
<script>
|
||||
import { GlAlert, GlLoadingIcon, GlTabs, GlTab } from '@gitlab/ui';
|
||||
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import { mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import httpStatusCodes from '~/lib/utils/http_status';
|
||||
|
||||
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
|
||||
import { unwrapStagesWithNeeds } from '~/pipelines/components/unwrapping_utils';
|
||||
import CiLint from './components/lint/ci_lint.vue';
|
||||
import CommitForm from './components/commit/commit_form.vue';
|
||||
import ConfirmUnsavedChangesDialog from './components/ui/confirm_unsaved_changes_dialog.vue';
|
||||
import EditorTab from './components/ui/editor_tab.vue';
|
||||
import TextEditor from './components/text_editor.vue';
|
||||
import ValidationSegment from './components/info/validation_segment.vue';
|
||||
|
||||
import commitCiFileMutation from './graphql/mutations/commit_ci_file.mutation.graphql';
|
||||
import {
|
||||
COMMIT_FAILURE,
|
||||
COMMIT_SUCCESS,
|
||||
DEFAULT_FAILURE,
|
||||
LOAD_FAILURE_NO_FILE,
|
||||
LOAD_FAILURE_UNKNOWN,
|
||||
} from './constants';
|
||||
import getBlobContent from './graphql/queries/blob_content.graphql';
|
||||
import getCiConfigData from './graphql/queries/ci_config.graphql';
|
||||
|
||||
const MR_SOURCE_BRANCH = 'merge_request[source_branch]';
|
||||
const MR_TARGET_BRANCH = 'merge_request[target_branch]';
|
||||
|
||||
const COMMIT_FAILURE = 'COMMIT_FAILURE';
|
||||
const COMMIT_SUCCESS = 'COMMIT_SUCCESS';
|
||||
const DEFAULT_FAILURE = 'DEFAULT_FAILURE';
|
||||
const LOAD_FAILURE_NO_FILE = 'LOAD_FAILURE_NO_FILE';
|
||||
const LOAD_FAILURE_UNKNOWN = 'LOAD_FAILURE_UNKNOWN';
|
||||
import PipelineEditorHome from './pipeline_editor_home.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CiLint,
|
||||
CommitForm,
|
||||
ConfirmUnsavedChangesDialog,
|
||||
EditorTab,
|
||||
GlAlert,
|
||||
GlLoadingIcon,
|
||||
GlTabs,
|
||||
GlTab,
|
||||
PipelineGraph,
|
||||
TextEditor,
|
||||
ValidationSegment,
|
||||
PipelineEditorHome,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
inject: ['projectFullPath'],
|
||||
props: {
|
||||
defaultBranch: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
commitSha: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
inject: {
|
||||
ciConfigPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: '',
|
||||
},
|
||||
newMergeRequestPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
defaultBranch: {
|
||||
default: null,
|
||||
},
|
||||
projectFullPath: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ciConfigData: {},
|
||||
content: '',
|
||||
contentModel: '',
|
||||
lastCommittedContent: '',
|
||||
lastCommitSha: this.commitSha,
|
||||
isSaving: false,
|
||||
|
||||
// Success and failure state
|
||||
failureType: null,
|
||||
showFailureAlert: false,
|
||||
failureReasons: [],
|
||||
successType: null,
|
||||
initialCiFileContent: '',
|
||||
lastCommittedContent: '',
|
||||
currentCiFileContent: '',
|
||||
showFailureAlert: false,
|
||||
showSuccessAlert: false,
|
||||
successType: null,
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
content: {
|
||||
initialCiFileContent: {
|
||||
query: getBlobContent,
|
||||
variables() {
|
||||
return {
|
||||
|
@ -91,12 +59,13 @@ export default {
|
|||
};
|
||||
},
|
||||
update(data) {
|
||||
const content = data?.blobContent?.rawData;
|
||||
this.lastCommittedContent = content;
|
||||
return content;
|
||||
return data?.blobContent?.rawData;
|
||||
},
|
||||
result({ data }) {
|
||||
this.contentModel = data?.blobContent?.rawData ?? '';
|
||||
const fileContent = data?.blobContent?.rawData ?? '';
|
||||
|
||||
this.lastCommittedContent = fileContent;
|
||||
this.currentCiFileContent = fileContent;
|
||||
},
|
||||
error(error) {
|
||||
this.handleBlobContentError(error);
|
||||
|
@ -105,13 +74,13 @@ export default {
|
|||
ciConfigData: {
|
||||
query: getCiConfigData,
|
||||
// If content is not loaded, we can't lint the data
|
||||
skip: ({ contentModel }) => {
|
||||
return !contentModel;
|
||||
skip: ({ currentCiFileContent }) => {
|
||||
return !currentCiFileContent;
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
projectPath: this.projectFullPath,
|
||||
content: this.contentModel,
|
||||
content: this.currentCiFileContent,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
|
@ -128,10 +97,10 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
hasUnsavedChanges() {
|
||||
return this.lastCommittedContent !== this.contentModel;
|
||||
return this.lastCommittedContent !== this.currentCiFileContent;
|
||||
},
|
||||
isBlobContentLoading() {
|
||||
return this.$apollo.queries.content.loading;
|
||||
return this.$apollo.queries.initialCiFileContent.loading;
|
||||
},
|
||||
isBlobContentError() {
|
||||
return this.failureType === LOAD_FAILURE_NO_FILE;
|
||||
|
@ -139,62 +108,60 @@ export default {
|
|||
isCiConfigDataLoading() {
|
||||
return this.$apollo.queries.ciConfigData.loading;
|
||||
},
|
||||
defaultCommitMessage() {
|
||||
return sprintf(this.$options.i18n.defaultCommitMessage, { sourcePath: this.ciConfigPath });
|
||||
},
|
||||
success() {
|
||||
switch (this.successType) {
|
||||
case COMMIT_SUCCESS:
|
||||
return {
|
||||
text: this.$options.alertTexts[COMMIT_SUCCESS],
|
||||
variant: 'info',
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
failure() {
|
||||
switch (this.failureType) {
|
||||
case LOAD_FAILURE_NO_FILE:
|
||||
return {
|
||||
text: sprintf(this.$options.alertTexts[LOAD_FAILURE_NO_FILE], {
|
||||
text: sprintf(this.$options.errorTexts[LOAD_FAILURE_NO_FILE], {
|
||||
filePath: this.ciConfigPath,
|
||||
}),
|
||||
variant: 'danger',
|
||||
};
|
||||
case LOAD_FAILURE_UNKNOWN:
|
||||
return {
|
||||
text: this.$options.alertTexts[LOAD_FAILURE_UNKNOWN],
|
||||
text: this.$options.errorTexts[LOAD_FAILURE_UNKNOWN],
|
||||
variant: 'danger',
|
||||
};
|
||||
case COMMIT_FAILURE:
|
||||
return {
|
||||
text: this.$options.alertTexts[COMMIT_FAILURE],
|
||||
text: this.$options.errorTexts[COMMIT_FAILURE],
|
||||
variant: 'danger',
|
||||
};
|
||||
default:
|
||||
return {
|
||||
text: this.$options.alertTexts[DEFAULT_FAILURE],
|
||||
text: this.$options.errorTexts[DEFAULT_FAILURE],
|
||||
variant: 'danger',
|
||||
};
|
||||
}
|
||||
},
|
||||
success() {
|
||||
switch (this.successType) {
|
||||
case COMMIT_SUCCESS:
|
||||
return {
|
||||
text: this.$options.successTexts[COMMIT_SUCCESS],
|
||||
variant: 'info',
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
defaultCommitMessage: __('Update %{sourcePath} file'),
|
||||
tabEdit: s__('Pipelines|Write pipeline configuration'),
|
||||
tabGraph: s__('Pipelines|Visualize'),
|
||||
tabLint: s__('Pipelines|Lint'),
|
||||
},
|
||||
alertTexts: {
|
||||
errorTexts: {
|
||||
[COMMIT_FAILURE]: s__('Pipelines|The GitLab CI configuration could not be updated.'),
|
||||
[COMMIT_SUCCESS]: __('Your changes have been successfully committed.'),
|
||||
[DEFAULT_FAILURE]: __('Something went wrong on our end.'),
|
||||
[LOAD_FAILURE_NO_FILE]: s__(
|
||||
'Pipelines|There is no %{filePath} file in this repository, please add one and visit the Pipeline Editor again.',
|
||||
),
|
||||
[LOAD_FAILURE_UNKNOWN]: s__('Pipelines|The CI configuration was not loaded, please try again.'),
|
||||
},
|
||||
successTexts: {
|
||||
[COMMIT_SUCCESS]: __('Your changes have been successfully committed.'),
|
||||
},
|
||||
methods: {
|
||||
handleBlobContentError(error = {}) {
|
||||
const { networkError } = error;
|
||||
|
@ -215,73 +182,32 @@ export default {
|
|||
dismissFailure() {
|
||||
this.showFailureAlert = false;
|
||||
},
|
||||
dismissSuccess() {
|
||||
this.showSuccessAlert = false;
|
||||
},
|
||||
reportFailure(type, reasons = []) {
|
||||
this.showFailureAlert = true;
|
||||
this.failureType = type;
|
||||
this.failureReasons = reasons;
|
||||
},
|
||||
dismissSuccess() {
|
||||
this.showSuccessAlert = false;
|
||||
},
|
||||
reportSuccess(type) {
|
||||
this.showSuccessAlert = true;
|
||||
this.successType = type;
|
||||
},
|
||||
|
||||
redirectToNewMergeRequest(sourceBranch) {
|
||||
const url = mergeUrlParams(
|
||||
{
|
||||
[MR_SOURCE_BRANCH]: sourceBranch,
|
||||
[MR_TARGET_BRANCH]: this.defaultBranch,
|
||||
},
|
||||
this.newMergeRequestPath,
|
||||
);
|
||||
redirectTo(url);
|
||||
resetContent() {
|
||||
this.currentCiFileContent = this.lastCommittedContent;
|
||||
},
|
||||
async onCommitSubmit(event) {
|
||||
this.isSaving = true;
|
||||
const { message, branch, openMergeRequest } = event;
|
||||
|
||||
try {
|
||||
const {
|
||||
data: {
|
||||
commitCreate: { errors, commit },
|
||||
},
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: commitCiFileMutation,
|
||||
variables: {
|
||||
projectPath: this.projectFullPath,
|
||||
branch,
|
||||
startBranch: this.defaultBranch,
|
||||
message,
|
||||
filePath: this.ciConfigPath,
|
||||
content: this.contentModel,
|
||||
lastCommitId: this.lastCommitSha,
|
||||
},
|
||||
});
|
||||
|
||||
if (errors?.length) {
|
||||
this.reportFailure(COMMIT_FAILURE, errors);
|
||||
return;
|
||||
}
|
||||
|
||||
if (openMergeRequest) {
|
||||
this.redirectToNewMergeRequest(branch);
|
||||
} else {
|
||||
this.reportSuccess(COMMIT_SUCCESS);
|
||||
|
||||
// Update latest commit
|
||||
this.lastCommitSha = commit.sha;
|
||||
this.lastCommittedContent = this.contentModel;
|
||||
}
|
||||
} catch (error) {
|
||||
this.reportFailure(COMMIT_FAILURE, [error?.message]);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
}
|
||||
showErrorAlert({ type, reasons = [] }) {
|
||||
this.reportFailure(type, reasons);
|
||||
},
|
||||
onCommitCancel() {
|
||||
this.contentModel = this.content;
|
||||
updateCiConfig(ciFileContent) {
|
||||
this.currentCiFileContent = ciFileContent;
|
||||
},
|
||||
updateOnCommit({ type }) {
|
||||
this.reportSuccess(type);
|
||||
// Keep track of the latest commited content to know
|
||||
// if the user has made changes to the file that are unsaved.
|
||||
this.lastCommittedContent = this.currentCiFileContent;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -289,20 +215,10 @@ export default {
|
|||
|
||||
<template>
|
||||
<div class="gl-mt-4">
|
||||
<gl-alert
|
||||
v-if="showSuccessAlert"
|
||||
:variant="success.variant"
|
||||
:dismissible="true"
|
||||
@dismiss="dismissSuccess"
|
||||
>
|
||||
<gl-alert v-if="showSuccessAlert" :variant="success.variant" @dismiss="dismissSuccess">
|
||||
{{ success.text }}
|
||||
</gl-alert>
|
||||
<gl-alert
|
||||
v-if="showFailureAlert"
|
||||
:variant="failure.variant"
|
||||
:dismissible="true"
|
||||
@dismiss="dismissFailure"
|
||||
>
|
||||
<gl-alert v-if="showFailureAlert" :variant="failure.variant" @dismiss="dismissFailure">
|
||||
{{ failure.text }}
|
||||
<ul v-if="failureReasons.length" class="gl-mb-0">
|
||||
<li v-for="reason in failureReasons" :key="reason">{{ reason }}</li>
|
||||
|
@ -310,45 +226,14 @@ export default {
|
|||
</gl-alert>
|
||||
<gl-loading-icon v-if="isBlobContentLoading" size="lg" class="gl-m-3" />
|
||||
<div v-else-if="!isBlobContentError" class="gl-mt-4">
|
||||
<div class="file-editor gl-mb-3">
|
||||
<div class="info-well gl-display-none gl-sm-display-block">
|
||||
<validation-segment
|
||||
class="well-segment"
|
||||
:loading="isCiConfigDataLoading"
|
||||
:ci-config="ciConfigData"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<gl-tabs>
|
||||
<editor-tab :lazy="true" :title="$options.i18n.tabEdit">
|
||||
<text-editor
|
||||
v-model="contentModel"
|
||||
:ci-config-path="ciConfigPath"
|
||||
:commit-sha="lastCommitSha"
|
||||
/>
|
||||
</editor-tab>
|
||||
<gl-tab
|
||||
v-if="glFeatures.ciConfigVisualizationTab"
|
||||
:lazy="true"
|
||||
:title="$options.i18n.tabGraph"
|
||||
data-testid="visualization-tab"
|
||||
>
|
||||
<gl-loading-icon v-if="isCiConfigDataLoading" size="lg" class="gl-m-3" />
|
||||
<pipeline-graph v-else :pipeline-data="ciConfigData" />
|
||||
</gl-tab>
|
||||
|
||||
<editor-tab :title="$options.i18n.tabLint">
|
||||
<gl-loading-icon v-if="isCiConfigDataLoading" size="lg" class="gl-m-3" />
|
||||
<ci-lint v-else :ci-config="ciConfigData" />
|
||||
</editor-tab>
|
||||
</gl-tabs>
|
||||
</div>
|
||||
<commit-form
|
||||
:default-branch="defaultBranch"
|
||||
:default-message="defaultCommitMessage"
|
||||
:is-saving="isSaving"
|
||||
@cancel="onCommitCancel"
|
||||
@submit="onCommitSubmit"
|
||||
<pipeline-editor-home
|
||||
:is-ci-config-data-loading="isCiConfigDataLoading"
|
||||
:ci-config-data="ciConfigData"
|
||||
:ci-file-content="currentCiFileContent"
|
||||
@commit="updateOnCommit"
|
||||
@resetContent="resetContent"
|
||||
@showError="showErrorAlert"
|
||||
@updateCiConfig="updateCiConfig"
|
||||
/>
|
||||
</div>
|
||||
<confirm-unsaved-changes-dialog :has-unsaved-changes="hasUnsavedChanges" />
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<script>
|
||||
import CommitSection from './components/commit/commit_section.vue';
|
||||
import PipelineEditorTabs from './components/pipeline_editor_tabs.vue';
|
||||
import PipelineEditorHeader from './components/header/pipeline_editor_header.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CommitSection,
|
||||
PipelineEditorHeader,
|
||||
PipelineEditorTabs,
|
||||
},
|
||||
props: {
|
||||
ciConfigData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
ciFileContent: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
isCiConfigDataLoading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<pipeline-editor-header
|
||||
:ci-config-data="ciConfigData"
|
||||
:is-ci-config-data-loading="isCiConfigDataLoading"
|
||||
/>
|
||||
<pipeline-editor-tabs
|
||||
:ci-config-data="ciConfigData"
|
||||
:ci-file-content="ciFileContent"
|
||||
:is-ci-config-data-loading="isCiConfigDataLoading"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
<commit-section :ci-file-content="ciFileContent" v-on="$listeners" />
|
||||
</div>
|
||||
</template>
|
|
@ -28,7 +28,6 @@ export default {
|
|||
return {
|
||||
currentPipeline: null,
|
||||
loadingPipelineId: null,
|
||||
minWidth: 0,
|
||||
pipelineExpanded: false,
|
||||
};
|
||||
},
|
||||
|
@ -40,6 +39,7 @@ export default {
|
|||
'gl-pl-3',
|
||||
'gl-mb-5',
|
||||
],
|
||||
minWidth: `${ONE_COL_WIDTH}px`,
|
||||
computed: {
|
||||
columnClass() {
|
||||
const positionValues = {
|
||||
|
@ -48,12 +48,6 @@ export default {
|
|||
};
|
||||
return `graph-position-${this.graphPosition} ${positionValues[this.graphPosition]}`;
|
||||
},
|
||||
graphPosition() {
|
||||
return this.isUpstream ? 'left' : 'right';
|
||||
},
|
||||
isUpstream() {
|
||||
return this.type === UPSTREAM;
|
||||
},
|
||||
computedTitleClasses() {
|
||||
const positionalClasses = this.isUpstream
|
||||
? ['gl-w-full', 'gl-text-right', 'gl-linked-pipeline-padding']
|
||||
|
@ -61,6 +55,12 @@ export default {
|
|||
|
||||
return [...this.$options.titleClasses, ...positionalClasses];
|
||||
},
|
||||
graphPosition() {
|
||||
return this.isUpstream ? 'left' : 'right';
|
||||
},
|
||||
isUpstream() {
|
||||
return this.type === UPSTREAM;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getPipelineData(pipeline) {
|
||||
|
@ -105,7 +105,6 @@ export default {
|
|||
if (this.currentPipeline?.id === pipeline.id) {
|
||||
this.pipelineExpanded = false;
|
||||
this.currentPipeline = null;
|
||||
this.minWidth = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -120,11 +119,6 @@ export default {
|
|||
*/
|
||||
this.pipelineExpanded = true;
|
||||
|
||||
/*
|
||||
Min-width is set manually for timing reasons.
|
||||
*/
|
||||
this.minWidth = `${ONE_COL_WIDTH}px`;
|
||||
|
||||
this.getPipelineData(pipeline);
|
||||
},
|
||||
onDownstreamHovered(jobName) {
|
||||
|
@ -138,6 +132,9 @@ export default {
|
|||
|
||||
this.$emit('pipelineExpandToggle', jobName, expanded);
|
||||
},
|
||||
showDownstreamContainer(id) {
|
||||
return !this.isUpstream && (this.isExpanded(id) || this.isLoadingPipeline(id));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -167,12 +164,12 @@ export default {
|
|||
@pipelineExpandToggle="onPipelineExpandToggle"
|
||||
/>
|
||||
<div
|
||||
v-if="isExpanded(pipeline.id) && !isUpstream"
|
||||
:style="{ minWidth }"
|
||||
v-if="showDownstreamContainer(pipeline.id)"
|
||||
:style="{ minWidth: $options.minWidth }"
|
||||
class="gl-display-inline-block"
|
||||
>
|
||||
<pipeline-graph
|
||||
v-if="currentPipeline"
|
||||
v-if="isExpanded(pipeline.id)"
|
||||
:type="type"
|
||||
class="d-inline-block gl-mt-n2"
|
||||
:pipeline="currentPipeline"
|
||||
|
|
|
@ -74,13 +74,15 @@ export default {
|
|||
<div v-else>
|
||||
<gl-alert
|
||||
v-if="showAlert"
|
||||
class="gl-w-max-content gl-ml-4"
|
||||
class="gl-ml-4 gl-mb-4"
|
||||
:primary-button-text="$options.i18n.showLinksAnyways"
|
||||
@primaryAction="overrideShowLinks"
|
||||
@dismiss="dismissAlert"
|
||||
>
|
||||
{{ $options.i18n.tooManyJobs }}
|
||||
</gl-alert>
|
||||
<slot></slot>
|
||||
<div class="gl-display-flex gl-relative">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -203,6 +203,17 @@ module DiffHelper
|
|||
set_secure_cookie(:diff_view, params.delete(:view), type: CookiesHelper::COOKIE_TYPE_PERMANENT) if params[:view].present?
|
||||
end
|
||||
|
||||
def collapsed_diff_url(diff_file)
|
||||
url_for(
|
||||
safe_params.merge(
|
||||
action: :diff_for_path,
|
||||
old_path: diff_file.old_path,
|
||||
new_path: diff_file.new_path,
|
||||
file_identifier: diff_file.file_identifier
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def diff_btn(title, name, selected)
|
||||
|
|
|
@ -76,6 +76,22 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Sometime we need to ensure that the first read goes to a primary
|
||||
# database, what is especially important in EE. This method does not
|
||||
# change the behavior in CE.
|
||||
#
|
||||
def with_read_consistency(build, &block)
|
||||
return yield unless consistent_reads_enabled?(build)
|
||||
|
||||
::Gitlab::Database::Consistency
|
||||
.with_read_consistency(&block)
|
||||
end
|
||||
|
||||
def consistent_reads_enabled?(build)
|
||||
Feature.enabled?(:gitlab_ci_trace_read_consistency, build.project, type: :development, default_enabled: false)
|
||||
end
|
||||
|
||||
##
|
||||
# Sometimes we do not want to read raw data. This method makes it easier
|
||||
# to find attributes that are just metadata excluding raw data.
|
||||
|
@ -154,8 +170,8 @@ module Ci
|
|||
in_lock(lock_key, **lock_params) do # exclusive Redis lock is acquired first
|
||||
raise FailedToPersistDataError, 'Modifed build trace chunk detected' if has_changes_to_save?
|
||||
|
||||
self.reset.then do |chunk| # we ensure having latest lock_version
|
||||
chunk.unsafe_persist_data! # we migrate the data and update data store
|
||||
self.class.with_read_consistency(build) do
|
||||
self.reset.then { |chunk| chunk.unsafe_persist_data! }
|
||||
end
|
||||
end
|
||||
rescue FailedToObtainLockError
|
||||
|
|
|
@ -24,9 +24,7 @@ module Pages
|
|||
@queue.close
|
||||
|
||||
@logger.info("Waiting for threads to finish...")
|
||||
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
||||
threads.each(&:join)
|
||||
end
|
||||
threads.each(&:join)
|
||||
|
||||
{ migrated: @migrated, errored: @errored }
|
||||
end
|
||||
|
@ -34,8 +32,8 @@ module Pages
|
|||
def start_migration_threads
|
||||
Array.new(@migration_threads) do
|
||||
Thread.new do
|
||||
Rails.application.executor.wrap do
|
||||
while batch = @queue.pop
|
||||
while batch = @queue.pop
|
||||
Rails.application.executor.wrap do
|
||||
process_batch(batch)
|
||||
end
|
||||
end
|
||||
|
@ -51,6 +49,11 @@ module Pages
|
|||
end
|
||||
|
||||
@logger.info("#{@migrated} projects are migrated successfully, #{@errored} projects failed to be migrated")
|
||||
rescue => e
|
||||
# This method should never raise exception otherwise all threads might be killed
|
||||
# and this will result in queue starving (and deadlock)
|
||||
Gitlab::ErrorTracking.track_exception(e)
|
||||
@logger.error("failed processing a batch: #{e.message}")
|
||||
end
|
||||
|
||||
def migrate_project(project)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
- diff_file = viewer.diff_file
|
||||
- url = url_for(safe_params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier))
|
||||
.nothing-here-block.diff-collapsed{ data: { diff_for_path: url } }
|
||||
.nothing-here-block.diff-collapsed{ data: { diff_for_path: collapsed_diff_url(viewer.diff_file) } }
|
||||
= _("This diff is collapsed.")
|
||||
%button.click-to-expand.btn.btn-link= _("Click to expand it.")
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
= render 'shared/notes/hints'
|
||||
.error-alert
|
||||
.gl-mt-3
|
||||
= f.submit 'Save changes', class: 'btn btn-success'
|
||||
= link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn btn-default btn-cancel"
|
||||
= f.submit 'Save changes', class: 'btn gl-button btn-success'
|
||||
= link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel"
|
||||
|
|
|
@ -42,13 +42,13 @@
|
|||
- if @tag.has_signature?
|
||||
= render partial: 'projects/commit/signature', object: @tag.signature
|
||||
- if can?(current_user, :admin_tag, @project)
|
||||
= link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn btn-icon btn-edit gl-button controls-item has-tooltip', title: s_('TagsPage|Edit release notes') do
|
||||
= link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn btn-icon btn-edit gl-button btn-default controls-item has-tooltip', title: s_('TagsPage|Edit release notes') do
|
||||
= sprite_icon("pencil", css_class: 'gl-icon')
|
||||
= link_to project_tree_path(@project, @tag.name), class: 'btn btn-icon gl-button controls-item has-tooltip', title: s_('TagsPage|Browse files') do
|
||||
= link_to project_tree_path(@project, @tag.name), class: 'btn btn-icon gl-button btn-default controls-item has-tooltip', title: s_('TagsPage|Browse files') do
|
||||
= sprite_icon('folder-open', css_class: 'gl-icon')
|
||||
= link_to project_commits_path(@project, @tag.name), class: 'btn btn-icon gl-button controls-item has-tooltip', title: s_('TagsPage|Browse commits') do
|
||||
= link_to project_commits_path(@project, @tag.name), class: 'btn btn-icon gl-button btn-default controls-item has-tooltip', title: s_('TagsPage|Browse commits') do
|
||||
= sprite_icon('history', css_class: 'gl-icon')
|
||||
.btn-container.controls-item
|
||||
.controls-item
|
||||
= render 'projects/buttons/download', project: @project, ref: @tag.name
|
||||
- if can?(current_user, :admin_tag, @project)
|
||||
.btn-container.controls-item-full
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Lower allocations in _collapsed partial
|
||||
merge_request: 53233
|
||||
author:
|
||||
type: performance
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add btn-default to buttons in tag action on the single tag page
|
||||
merge_request: 52866
|
||||
author: Yogi (@yo)
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Apply new GitLab UI for buttons in the tag edit page
|
||||
merge_request: 52863
|
||||
author: Yogi (@yo)
|
||||
type: other
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This file is used by Rack-based servers to start the application.
|
||||
|
||||
if defined?(Unicorn)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
|
||||
# Set up gems listed in the Gemfile.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Load the Rails application.
|
||||
require_relative 'application'
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'gitlab/testing/request_blocker_middleware'
|
||||
require 'gitlab/testing/robots_blocker_middleware'
|
||||
require 'gitlab/testing/request_inspector_middleware'
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: gitlab_ci_trace_read_consistency
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46976
|
||||
rollout_issue_url:
|
||||
milestone: '13.9'
|
||||
type: development
|
||||
group: group::continuous integration
|
||||
default_enabled: false
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: usage_data_i_testing_load_performance_widget_total
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52688
|
||||
rollout_issue_url:
|
||||
milestone: '13.9'
|
||||
type: development
|
||||
group: group::testing
|
||||
default_enabled: true
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# WARNING: Before you make a change to secrets.yml, read the development guide for GitLab secrets
|
||||
# doc/development/application_secrets.md.
|
||||
#
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ActsAsTaggableOn.strict_case_match = true
|
||||
|
||||
# tags_counter enables caching count of tags which results in an update whenever a tag is added or removed
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This needs to be loaded after
|
||||
# config/initializers/0_inject_enterprise_edition_module.rb
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Post deployment migrations are included by default. This file must be loaded
|
||||
# before other initializers as Rails may otherwise memoize a list of migrations
|
||||
# excluding the post deployment migrations.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../settings'
|
||||
require_relative '../object_store_settings'
|
||||
require_relative '../smime_signature_settings'
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_dependency 'gitlab'
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
unless Rails.env.test?
|
||||
required_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version_required)
|
||||
current_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
def storage_validation_error(message)
|
||||
raise "#{message}. Please fix this in your gitlab.yml before starting GitLab."
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'prometheus/client'
|
||||
|
||||
# Keep separate directories for separate processes
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Make sure we initialize a Redis connection pool before multi-threaded
|
||||
# execution starts by
|
||||
# 1. Sidekiq
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Use this hook to configure devise mailer, warden hooks and so forth. The first
|
||||
# four configuration values can also be set straight in your models.
|
||||
Devise.setup do |config|
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'uri'
|
||||
|
||||
Gitlab.config.repositories.storages.keys.each do |storage|
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FastGettext.default_available_locales = Gitlab::I18n.available_locales
|
||||
I18n.available_locales = Gitlab::I18n.available_locales
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Starting with Rails 5, Rails tries to determine the request format based on
|
||||
# the extension of the full URL path if no explicit `format` param or `Accept`
|
||||
# header is provided, like when simply browsing to a page in your browser.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
unless Gitlab.config.gitlab.email_enabled
|
||||
ActionMailer::Base.register_interceptor(::Gitlab::Email::Hook::DisableEmailInterceptor)
|
||||
ActionMailer::Base.logger = nil
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# ActiveRecord custom data type for storing datetimes with timezone information.
|
||||
# See https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/11229
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# # frozen_string_literal: true
|
||||
|
||||
if Gitlab::Utils.to_boolean(ENV['ENABLE_ACTIVERECORD_EMPTY_PING'], default: false)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
module Associations
|
||||
class Preloader
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Ignore dynamically managed partitions in static application schema
|
||||
ActiveRecord::SchemaDumper.ignore_tables += ["#{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.*"]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# ActiveRecord custom method definitions with timezone information.
|
||||
# See https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/11229
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if Rails.env.test?
|
||||
require 'active_record/migration'
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# Asset proxy settings
|
||||
#
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module AttrEncrypted
|
||||
module Adapters
|
||||
module ActiveRecord
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.backtrace_cleaner.remove_silencers!
|
||||
|
||||
# This allows us to see the proper caller of SQL calls in {development,test}.log
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.config.middleware.use(BatchLoader::Middleware)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BootstrapFormBuilderCustomization
|
||||
def label_class
|
||||
"label-bold"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
def bullet_enabled?
|
||||
Gitlab::Utils.to_boolean(ENV['ENABLE_BULLET'].to_s)
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Technical debt, this should be ideally upstreamed.
|
||||
#
|
||||
# However, there's currently no way to hook before doing
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop:disable Rails/Output
|
||||
if Gitlab::Runtime.console?
|
||||
# note that this will not print out when using `spring`
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Rails.application.config.action_dispatch.use_cookies_with_metadata = true
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# :short - 10 Nov
|
||||
# :medium - Nov 10, 2007
|
||||
# :long - November 10, 2007
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
default_url_options = {
|
||||
host: Gitlab.config.gitlab.host,
|
||||
protocol: Gitlab.config.gitlab.protocol,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if Rails.env.development? || ENV['GITLAB_LEGACY_PATH_LOG_MESSAGE']
|
||||
deprecator = ActiveSupport::Deprecation.new('11.0', 'GitLab')
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DirectUploadsValidator
|
||||
SUPPORTED_DIRECT_UPLOAD_PROVIDERS = [ObjectStorage::Config::GOOGLE_PROVIDER,
|
||||
ObjectStorage::Config::AWS_PROVIDER,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Doorkeeper.configure do
|
||||
# Change the ORM that doorkeeper will use.
|
||||
# Currently supported options are :active_record, :mongoid2, :mongoid3, :mongo_mapper
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Doorkeeper::OpenidConnect.configure do
|
||||
issuer Gitlab.config.gitlab.url
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This middleware has to come after Gitlab::Metrics::RackMiddleware
|
||||
# in the middleware stack, because it tracks events with
|
||||
# GitLab Performance Monitoring
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# The explicit schema version check is needed because during our migration rollback testing,
|
||||
# `Shard.connected?` could be cached and return true even though the table doesn't exist
|
||||
return unless Shard.connected?
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module LocalCacheRegistryCleanupWithEnsure
|
||||
LocalCacheRegistry =
|
||||
ActiveSupport::Cache::Strategy::LocalCache::LocalCacheRegistry
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# Monkey patching the https support for private urls
|
||||
# See https://gitlab.com/gitlab-org/gitlab/issues/4879
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Sidekiq
|
||||
module Worker
|
||||
EnqueueFromTransactionError = Class.new(StandardError)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'gettext_i18n_rails/haml_parser'
|
||||
require 'gettext_i18n_rails_js/parser/javascript'
|
||||
require 'json'
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Gitlab::Kas.ensure_secret!
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Gitlab::Shell.ensure_secret_token!
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
begin
|
||||
Gitlab::Workhorse.secret
|
||||
rescue
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.config.middleware.use(Gitlab::Middleware::Go)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'logger'
|
||||
|
||||
GRPC_LOGGER = Logger.new(Rails.root.join('log/grpc.log'))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Hamlit::RailsTemplate.set_options(attr_quote: '"')
|
||||
|
||||
Hamlit::Filters.remove_filter('coffee')
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
HealthCheck.setup do |config|
|
||||
config.standard_checks = %w(database migrations cache)
|
||||
config.full_checks = %w(database migrations cache)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This override allows passing `@hostname_override` to the SNI protocol,
|
||||
# which is used to lookup the correct SSL certificate in the
|
||||
# request handshake process.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Kaminari
|
||||
# Active Record specific page scope methods implementations
|
||||
module ActiveRecordRelationMethodsWithLimit
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Kaminari.configure do |config|
|
||||
config.default_per_page = 20
|
||||
config.max_per_page = 100
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Only use Lograge for Rails
|
||||
unless Gitlab::Runtime.sidekiq?
|
||||
Rails.application.reloader.to_prepare do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Monkey patch mail 2.7.1 to fix quoted-printable issues with newlines
|
||||
# The issues upstream invalidate SMIME signatures under some conditions
|
||||
# This was working properly in 2.6.6
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new mime types for use in respond_to blocks:
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
MiniMagick.configure do |config|
|
||||
config.cli = :graphicsmagick
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Remove this `if` condition when upgraded to rails 5.0.
|
||||
# The body must be kept.
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Octokit.middleware.insert_after Octokit::Middleware::FollowRedirects, Gitlab::Octokit::Middleware
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if Gitlab::Auth::Ldap::Config.enabled?
|
||||
module OmniAuth::Strategies
|
||||
Gitlab::Auth::Ldap::Config.available_servers.each do |server|
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue