Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
698fe342b9
commit
5c2d8a7cbe
|
@ -1,54 +0,0 @@
|
||||||
import $ from 'jquery';
|
|
||||||
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
|
||||||
|
|
||||||
export default class TargetBranchDropdown {
|
|
||||||
constructor() {
|
|
||||||
this.$dropdown = $('.js-target-branch-dropdown');
|
|
||||||
this.$dropdownToggle = this.$dropdown.find('.dropdown-toggle-text');
|
|
||||||
this.$input = $('#schedule_ref');
|
|
||||||
this.initDefaultBranch();
|
|
||||||
this.initDropdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
initDropdown() {
|
|
||||||
initDeprecatedJQueryDropdown(this.$dropdown, {
|
|
||||||
data: this.formatBranchesList(),
|
|
||||||
filterable: true,
|
|
||||||
selectable: true,
|
|
||||||
toggleLabel: (item) => item.name,
|
|
||||||
search: {
|
|
||||||
fields: ['name'],
|
|
||||||
},
|
|
||||||
clicked: (cfg) => this.updateInputValue(cfg),
|
|
||||||
text: (item) => item.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setDropdownToggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
formatBranchesList() {
|
|
||||||
return this.$dropdown.data('data').map((val) => ({ name: val }));
|
|
||||||
}
|
|
||||||
|
|
||||||
setDropdownToggle() {
|
|
||||||
const initialValue = this.$input.val();
|
|
||||||
|
|
||||||
this.$dropdownToggle.text(initialValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
initDefaultBranch() {
|
|
||||||
const initialValue = this.$input.val();
|
|
||||||
const defaultBranch = this.$dropdown.data('defaultBranch');
|
|
||||||
|
|
||||||
if (!initialValue) {
|
|
||||||
this.$input.val(defaultBranch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateInputValue({ selectedObj, e }) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
this.$input.val(selectedObj.name);
|
|
||||||
gl.pipelineScheduleFieldErrors.updateFormValidityState();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,12 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { __ } from '~/locale';
|
||||||
|
import RefSelector from '~/ref/components/ref_selector.vue';
|
||||||
|
import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
|
||||||
import setupNativeFormVariableList from '../../../../ci_variable_list/native_form_variable_list';
|
import setupNativeFormVariableList from '../../../../ci_variable_list/native_form_variable_list';
|
||||||
import GlFieldErrors from '../../../../gl_field_errors';
|
import GlFieldErrors from '../../../../gl_field_errors';
|
||||||
import Translate from '../../../../vue_shared/translate';
|
import Translate from '../../../../vue_shared/translate';
|
||||||
import intervalPatternInput from './components/interval_pattern_input.vue';
|
import intervalPatternInput from './components/interval_pattern_input.vue';
|
||||||
import TargetBranchDropdown from './components/target_branch_dropdown';
|
|
||||||
import TimezoneDropdown from './components/timezone_dropdown';
|
import TimezoneDropdown from './components/timezone_dropdown';
|
||||||
|
|
||||||
Vue.use(Translate);
|
Vue.use(Translate);
|
||||||
|
@ -30,6 +32,52 @@ function initIntervalPatternInput() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEnabledRefTypes() {
|
||||||
|
const refTypes = [REF_TYPE_BRANCHES];
|
||||||
|
|
||||||
|
if (gon.features.pipelineSchedulesWithTags) {
|
||||||
|
refTypes.push(REF_TYPE_TAGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return refTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initTargetRefDropdown() {
|
||||||
|
const $refField = document.getElementById('schedule_ref');
|
||||||
|
const el = document.querySelector('.js-target-ref-dropdown');
|
||||||
|
const { projectId, defaultBranch } = el.dataset;
|
||||||
|
|
||||||
|
if (!$refField.value) {
|
||||||
|
$refField.value = defaultBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const refDropdown = new Vue({
|
||||||
|
el,
|
||||||
|
render(h) {
|
||||||
|
return h(RefSelector, {
|
||||||
|
props: {
|
||||||
|
enabledRefTypes: getEnabledRefTypes(),
|
||||||
|
projectId,
|
||||||
|
value: $refField.value,
|
||||||
|
useSymbolicRefNames: true,
|
||||||
|
translations: {
|
||||||
|
dropdownHeader: gon.features.pipelineSchedulesWithTags
|
||||||
|
? __('Select target branch or tag')
|
||||||
|
: __('Select target branch'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
class: 'gl-w-full',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
refDropdown.$children[0].$on('input', (newRef) => {
|
||||||
|
$refField.value = newRef;
|
||||||
|
});
|
||||||
|
|
||||||
|
return refDropdown;
|
||||||
|
}
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
/* Most of the form is written in haml, but for fields with more complex behaviors,
|
/* Most of the form is written in haml, but for fields with more complex behaviors,
|
||||||
* you should mount individual Vue components here. If at some point components need
|
* you should mount individual Vue components here. If at some point components need
|
||||||
|
@ -48,9 +96,10 @@ export default () => {
|
||||||
gl.pipelineScheduleFieldErrors.updateFormValidityState();
|
gl.pipelineScheduleFieldErrors.updateFormValidityState();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
gl.targetBranchDropdown = new TargetBranchDropdown();
|
|
||||||
gl.pipelineScheduleFieldErrors = new GlFieldErrors(formElement);
|
gl.pipelineScheduleFieldErrors = new GlFieldErrors(formElement);
|
||||||
|
|
||||||
|
initTargetRefDropdown();
|
||||||
|
|
||||||
setupNativeFormVariableList({
|
setupNativeFormVariableList({
|
||||||
container: $('.js-ci-variable-list-section'),
|
container: $('.js-ci-variable-list-section'),
|
||||||
formField: 'schedule',
|
formField: 'schedule',
|
||||||
|
|
|
@ -58,6 +58,11 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
|
useSymbolicRefNames: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
/** The validation state of this component. */
|
/** The validation state of this component. */
|
||||||
state: {
|
state: {
|
||||||
|
@ -121,8 +126,15 @@ export default {
|
||||||
query: this.lastQuery,
|
query: this.lastQuery,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
selectedRefForDisplay() {
|
||||||
|
if (this.useSymbolicRefNames && this.selectedRef) {
|
||||||
|
return this.selectedRef.replace(/^refs\/(tags|heads)\//, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.selectedRef;
|
||||||
|
},
|
||||||
buttonText() {
|
buttonText() {
|
||||||
return this.selectedRef || this.i18n.noRefSelected;
|
return this.selectedRefForDisplay || this.i18n.noRefSelected;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -164,9 +176,20 @@ export default {
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.$watch(
|
||||||
|
'useSymbolicRefNames',
|
||||||
|
() => this.setUseSymbolicRefNames(this.useSymbolicRefNames),
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['setEnabledRefTypes', 'setProjectId', 'setSelectedRef']),
|
...mapActions([
|
||||||
|
'setEnabledRefTypes',
|
||||||
|
'setUseSymbolicRefNames',
|
||||||
|
'setProjectId',
|
||||||
|
'setSelectedRef',
|
||||||
|
]),
|
||||||
...mapActions({ storeSearch: 'search' }),
|
...mapActions({ storeSearch: 'search' }),
|
||||||
focusSearchBox() {
|
focusSearchBox() {
|
||||||
this.$refs.searchBox.$el.querySelector('input').focus();
|
this.$refs.searchBox.$el.querySelector('input').focus();
|
||||||
|
|
|
@ -5,6 +5,9 @@ import * as types from './mutation_types';
|
||||||
export const setEnabledRefTypes = ({ commit }, refTypes) =>
|
export const setEnabledRefTypes = ({ commit }, refTypes) =>
|
||||||
commit(types.SET_ENABLED_REF_TYPES, refTypes);
|
commit(types.SET_ENABLED_REF_TYPES, refTypes);
|
||||||
|
|
||||||
|
export const setUseSymbolicRefNames = ({ commit }, useSymbolicRefNames) =>
|
||||||
|
commit(types.SET_USE_SYMBOLIC_REF_NAMES, useSymbolicRefNames);
|
||||||
|
|
||||||
export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId);
|
export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId);
|
||||||
|
|
||||||
export const setSelectedRef = ({ commit }, selectedRef) =>
|
export const setSelectedRef = ({ commit }, selectedRef) =>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export const SET_ENABLED_REF_TYPES = 'SET_ENABLED_REF_TYPES';
|
export const SET_ENABLED_REF_TYPES = 'SET_ENABLED_REF_TYPES';
|
||||||
|
export const SET_USE_SYMBOLIC_REF_NAMES = 'SET_USE_SYMBOLIC_REF_NAMES';
|
||||||
|
|
||||||
export const SET_PROJECT_ID = 'SET_PROJECT_ID';
|
export const SET_PROJECT_ID = 'SET_PROJECT_ID';
|
||||||
export const SET_SELECTED_REF = 'SET_SELECTED_REF';
|
export const SET_SELECTED_REF = 'SET_SELECTED_REF';
|
||||||
|
|
|
@ -7,6 +7,9 @@ export default {
|
||||||
[types.SET_ENABLED_REF_TYPES](state, refTypes) {
|
[types.SET_ENABLED_REF_TYPES](state, refTypes) {
|
||||||
state.enabledRefTypes = refTypes;
|
state.enabledRefTypes = refTypes;
|
||||||
},
|
},
|
||||||
|
[types.SET_USE_SYMBOLIC_REF_NAMES](state, useSymbolicRefNames) {
|
||||||
|
state.useSymbolicRefNames = useSymbolicRefNames;
|
||||||
|
},
|
||||||
[types.SET_PROJECT_ID](state, projectId) {
|
[types.SET_PROJECT_ID](state, projectId) {
|
||||||
state.projectId = projectId;
|
state.projectId = projectId;
|
||||||
},
|
},
|
||||||
|
@ -28,6 +31,7 @@ export default {
|
||||||
state.matches.branches = {
|
state.matches.branches = {
|
||||||
list: convertObjectPropsToCamelCase(response.data).map((b) => ({
|
list: convertObjectPropsToCamelCase(response.data).map((b) => ({
|
||||||
name: b.name,
|
name: b.name,
|
||||||
|
value: state.useSymbolicRefNames ? `refs/heads/${b.name}` : undefined,
|
||||||
default: b.default,
|
default: b.default,
|
||||||
})),
|
})),
|
||||||
totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10),
|
totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10),
|
||||||
|
@ -46,6 +50,7 @@ export default {
|
||||||
state.matches.tags = {
|
state.matches.tags = {
|
||||||
list: convertObjectPropsToCamelCase(response.data).map((b) => ({
|
list: convertObjectPropsToCamelCase(response.data).map((b) => ({
|
||||||
name: b.name,
|
name: b.name,
|
||||||
|
value: state.useSymbolicRefNames ? `refs/tags/${b.name}` : undefined,
|
||||||
})),
|
})),
|
||||||
totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10),
|
totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10),
|
||||||
error: null,
|
error: null,
|
||||||
|
|
|
@ -10,6 +10,10 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
|
||||||
before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play]
|
before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play]
|
||||||
before_action :authorize_admin_pipeline_schedule!, only: [:destroy]
|
before_action :authorize_admin_pipeline_schedule!, only: [:destroy]
|
||||||
|
|
||||||
|
before_action do
|
||||||
|
push_frontend_feature_flag(:pipeline_schedules_with_tags, @project, default_enabled: :yaml)
|
||||||
|
end
|
||||||
|
|
||||||
feature_category :continuous_integration
|
feature_category :continuous_integration
|
||||||
|
|
||||||
# rubocop: disable CodeReuse/ActiveRecord
|
# rubocop: disable CodeReuse/ActiveRecord
|
||||||
|
|
|
@ -66,6 +66,18 @@ module Ci
|
||||||
project.actual_limits.limit_for(:ci_daily_pipeline_schedule_triggers)
|
project.actual_limits.limit_for(:ci_daily_pipeline_schedule_triggers)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ref_for_display
|
||||||
|
return unless ref.present?
|
||||||
|
|
||||||
|
ref.gsub(%r{^refs/(heads|tags)/}, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def for_tag?
|
||||||
|
return false unless ref.present?
|
||||||
|
|
||||||
|
ref.start_with? 'refs/tags/'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def worker_cron_expression
|
def worker_cron_expression
|
||||||
|
|
|
@ -15,8 +15,9 @@
|
||||||
= f.text_field :cron_timezone, value: @schedule.cron_timezone, id: 'schedule_cron_timezone', class: 'hidden', name: 'schedule[cron_timezone]', required: true
|
= f.text_field :cron_timezone, value: @schedule.cron_timezone, id: 'schedule_cron_timezone', class: 'hidden', name: 'schedule[cron_timezone]', required: true
|
||||||
.form-group.row
|
.form-group.row
|
||||||
.col-md-9
|
.col-md-9
|
||||||
= f.label :ref, _('Target Branch'), class: 'label-bold'
|
= f.label :ref, Feature.enabled?(:pipeline_schedules_with_tags) ? _('Target branch or tag') : _('Target branch'), class: 'label-bold'
|
||||||
= dropdown_tag(_("Select target branch"), options: { toggle_class: 'gl-button btn btn-default js-target-branch-dropdown w-100', dropdown_class: 'git-revision-dropdown w-100', title: _("Select target branch"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
|
%div{ data: { testid: 'schedule-target-ref' } }
|
||||||
|
.js-target-ref-dropdown{ data: { project_id: @project.id, default_branch: @project.default_branch } }
|
||||||
= f.text_field :ref, value: @schedule.ref, id: 'schedule_ref', class: 'hidden', name: 'schedule[ref]', required: true
|
= f.text_field :ref, value: @schedule.ref, id: 'schedule_ref', class: 'hidden', name: 'schedule[ref]', required: true
|
||||||
.form-group.row.js-ci-variable-list-section
|
.form-group.row.js-ci-variable-list-section
|
||||||
.col-md-9
|
.col-md-9
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
%td
|
%td
|
||||||
= pipeline_schedule.description
|
= pipeline_schedule.description
|
||||||
%td.branch-name-cell
|
%td.branch-name-cell
|
||||||
|
- if pipeline_schedule.for_tag?
|
||||||
|
= sprite_icon('tag', size: 12)
|
||||||
|
- else
|
||||||
= sprite_icon('fork', size: 12)
|
= sprite_icon('fork', size: 12)
|
||||||
- if pipeline_schedule.ref.present?
|
- if pipeline_schedule.ref.present?
|
||||||
= link_to pipeline_schedule.ref, project_ref_path(@project, pipeline_schedule.ref), class: "ref-name"
|
= link_to pipeline_schedule.ref_for_display, project_ref_path(@project, pipeline_schedule.ref_for_display), class: "ref-name"
|
||||||
%td
|
%td
|
||||||
- if pipeline_schedule.last_pipeline
|
- if pipeline_schedule.last_pipeline
|
||||||
.status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" }
|
.status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" }
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
milestone_issue_count: @milestone.issues.count,
|
milestone_issue_count: @milestone.issues.count,
|
||||||
milestone_merge_request_count: @milestone.merge_requests.count },
|
milestone_merge_request_count: @milestone.merge_requests.count },
|
||||||
disabled: true }
|
disabled: true }
|
||||||
|
= gl_loading_icon(inline: true, css_class: "gl-mr-2 js-loading-icon hidden")
|
||||||
= _('Delete')
|
= _('Delete')
|
||||||
.gl-spinner.js-loading-icon.hidden
|
|
||||||
|
|
||||||
#js-delete-milestone-modal
|
#js-delete-milestone-modal
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: pipeline_schedules_with_tags
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81476
|
||||||
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354421
|
||||||
|
milestone: '14.9'
|
||||||
|
type: development
|
||||||
|
group: group::pipeline execution
|
||||||
|
default_enabled: false
|
|
@ -0,0 +1,14 @@
|
||||||
|
- name: "GitLab self-monitoring" # The name of the feature to be deprecated
|
||||||
|
announcement_milestone: "14.9" # The milestone when this feature was first announced as deprecated.
|
||||||
|
announcement_date: "2022-03-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
|
||||||
|
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
|
||||||
|
removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
|
||||||
|
breaking_change: true # If this deprecation is a breaking change, set this value to true
|
||||||
|
reporter: abellucci # GitLab username of the person reporting the deprecation
|
||||||
|
body: | # Do not modify this line, instead modify the lines below.
|
||||||
|
GitLab self-monitoring gives administrators of self-hosted GitLab instances the tools to monitor the health of their instances. This feature is deprecated in GitLab 14.9, and is scheduled for removal in 15.0.
|
||||||
|
# The following items are not published on the docs page, but may be used in the future.
|
||||||
|
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
|
||||||
|
tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
|
||||||
|
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348909 # (optional) This is a link to the deprecation issue in GitLab
|
||||||
|
documentation_url: https://docs.gitlab.com/ee/administration/monitoring/gitlab_self_monitoring_project/ # (optional) This is a link to the current documentation page
|
|
@ -4,10 +4,15 @@ group: Respond
|
||||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||||
---
|
---
|
||||||
|
|
||||||
# Self-monitoring project **(FREE SELF)**
|
# Self-monitoring project (DEPRECATED) **(FREE SELF)**
|
||||||
|
|
||||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32351) in GitLab 12.7 [with a flag](../../feature_flags.md) named `self_monitoring_project`. Disabled by default.
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32351) in GitLab 12.7 [with a flag](../../feature_flags.md) named `self_monitoring_project`. Disabled by default.
|
||||||
> - Generally available in GitLab 12.8. [Feature flag `self_monitoring_project`](https://gitlab.com/gitlab-org/gitlab/-/issues/198511) removed.
|
> - Generally available in GitLab 12.8. [Feature flag `self_monitoring_project`](https://gitlab.com/gitlab-org/gitlab/-/issues/198511) removed.
|
||||||
|
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/348909) in GitLab 14.9. Planned for removal in GitLab 15.0.
|
||||||
|
|
||||||
|
WARNING:
|
||||||
|
This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/348909)
|
||||||
|
for use in GitLab 14.9, and is planned for removal in GitLab 15.0.
|
||||||
|
|
||||||
GitLab provides administrators insights into the health of their GitLab instance.
|
GitLab provides administrators insights into the health of their GitLab instance.
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ are very appreciative of the work done by translators and proofreaders!
|
||||||
- Paulo George Gomes Bezerra - [GitLab](https://gitlab.com/paulobezerra), [Crowdin](https://crowdin.com/profile/paulogomes.rep)
|
- Paulo George Gomes Bezerra - [GitLab](https://gitlab.com/paulobezerra), [Crowdin](https://crowdin.com/profile/paulogomes.rep)
|
||||||
- André Gama - [GitLab](https://gitlab.com/andregamma), [Crowdin](https://crowdin.com/profile/ToeOficial)
|
- André Gama - [GitLab](https://gitlab.com/andregamma), [Crowdin](https://crowdin.com/profile/ToeOficial)
|
||||||
- Eduardo Addad de Oliveira - [GitLab](https://gitlab.com/eduardoaddad), [Crowdin](https://crowdin.com/profile/eduardoaddad)
|
- Eduardo Addad de Oliveira - [GitLab](https://gitlab.com/eduardoaddad), [Crowdin](https://crowdin.com/profile/eduardoaddad)
|
||||||
|
- Horberlan Brito - [GitLab](https://gitlab.com/horberlan), [Crowdin](https://crowdin.com/profile/horberlan)
|
||||||
- Romanian
|
- Romanian
|
||||||
- Mircea Pop - [GitLab](https://gitlab.com/eeex), [Crowdin](https://crowdin.com/profile/eex)
|
- Mircea Pop - [GitLab](https://gitlab.com/eeex), [Crowdin](https://crowdin.com/profile/eex)
|
||||||
- Rareș Pița - [GitLab](https://gitlab.com/dlphin), [Crowdin](https://crowdin.com/profile/dlphin)
|
- Rareș Pița - [GitLab](https://gitlab.com/dlphin), [Crowdin](https://crowdin.com/profile/dlphin)
|
||||||
|
@ -110,6 +111,8 @@ are very appreciative of the work done by translators and proofreaders!
|
||||||
- Iaroslav Postovalov - [GitLab](https://gitlab.com/CMDR_Tvis), [Crowdin](https://crowdin.com/profile/CMDR_Tvis)
|
- Iaroslav Postovalov - [GitLab](https://gitlab.com/CMDR_Tvis), [Crowdin](https://crowdin.com/profile/CMDR_Tvis)
|
||||||
- Serbian (Latin and Cyrillic)
|
- Serbian (Latin and Cyrillic)
|
||||||
- Proofreaders needed.
|
- Proofreaders needed.
|
||||||
|
- Sinhalese/Sinhala සිංහල
|
||||||
|
- හෙළබස (HelaBasa) - [GitLab](https://gitlab.com/helabasa), [Crowdin](https://crowdin.com/profile/helabasa)
|
||||||
- Slovak
|
- Slovak
|
||||||
- Proofreaders needed.
|
- Proofreaders needed.
|
||||||
- Spanish
|
- Spanish
|
||||||
|
|
|
@ -36,6 +36,20 @@ For deprecation reviewers (Technical Writers only):
|
||||||
https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-deprecations-doc
|
https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-deprecations-doc
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## 14.9
|
||||||
|
|
||||||
|
### GitLab self-monitoring
|
||||||
|
|
||||||
|
WARNING:
|
||||||
|
This feature will be changed or removed in 15.0
|
||||||
|
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
|
||||||
|
Before updating GitLab, review the details carefully to determine if you need to make any
|
||||||
|
changes to your code, settings, or workflow.
|
||||||
|
|
||||||
|
GitLab self-monitoring gives administrators of self-hosted GitLab instances the tools to monitor the health of their instances. This feature is deprecated in GitLab 14.9, and is scheduled for removal in 15.0.
|
||||||
|
|
||||||
|
**Planned removal milestone: 15.0 (2022-05-22)**
|
||||||
|
|
||||||
## 14.8
|
## 14.8
|
||||||
|
|
||||||
### Changes to the `CI_JOB_JWT`
|
### Changes to the `CI_JOB_JWT`
|
||||||
|
|
|
@ -132,3 +132,25 @@ migrated:
|
||||||
- image URL
|
- image URL
|
||||||
- Boards
|
- Boards
|
||||||
- Board Lists
|
- Board Lists
|
||||||
|
|
||||||
|
## Troubleshooting Group Migration
|
||||||
|
|
||||||
|
In a [rails console session](../../../administration/operations/rails_console.md#starting-a-rails-console-session),
|
||||||
|
you can find the failure or error messages for the group import attempt using:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Get relevant import records
|
||||||
|
import = BulkImports::Entity.where(namespace_id: Group.id).bulk_import
|
||||||
|
|
||||||
|
# Alternative lookup by user
|
||||||
|
import = BulkImport.where(user_id: User.find(...)).last
|
||||||
|
|
||||||
|
# Get list of import entities. Each entity represents either a group or a project
|
||||||
|
entities = import.entities
|
||||||
|
|
||||||
|
# Get a list of entity failures
|
||||||
|
entities.map(&:failures).flatten
|
||||||
|
|
||||||
|
# Alternative failure lookup by status
|
||||||
|
entities.where(status: [-1]).pluck(:destination_name, :destination_namespace, :status)
|
||||||
|
```
|
||||||
|
|
|
@ -163,6 +163,11 @@ namespace :gitlab do
|
||||||
end
|
end
|
||||||
|
|
||||||
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
||||||
|
# We'll temporarily skip this enhancement for geo, since in some situations we
|
||||||
|
# wish to setup the geo database before the other databases have been setup,
|
||||||
|
# and partition management attempts to connect to the main database.
|
||||||
|
next if name == 'geo'
|
||||||
|
|
||||||
Rake::Task["db:migrate:#{name}"].enhance do
|
Rake::Task["db:migrate:#{name}"].enhance do
|
||||||
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
|
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
|
||||||
end
|
end
|
||||||
|
@ -181,6 +186,11 @@ namespace :gitlab do
|
||||||
end
|
end
|
||||||
|
|
||||||
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
||||||
|
# We'll temporarily skip this enhancement for geo, since in some situations we
|
||||||
|
# wish to setup the geo database before the other databases have been setup,
|
||||||
|
# and partition management attempts to connect to the main database.
|
||||||
|
next if name == 'geo'
|
||||||
|
|
||||||
Rake::Task["db:schema:load:#{name}"].enhance do
|
Rake::Task["db:schema:load:#{name}"].enhance do
|
||||||
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
|
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
|
||||||
end
|
end
|
||||||
|
|
|
@ -6840,6 +6840,9 @@ msgstr ""
|
||||||
msgid "ChangeTypeAction|Your changes will be committed to %{branchName} because a merge request is open."
|
msgid "ChangeTypeAction|Your changes will be committed to %{branchName} because a merge request is open."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Changed assignee(s)."
|
msgid "Changed assignee(s)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -30901,6 +30904,9 @@ msgstr ""
|
||||||
msgid "Reports|Identifier"
|
msgid "Reports|Identifier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reports|Metrics report scanning detected no new changes"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Reports|Metrics reports are loading"
|
msgid "Reports|Metrics reports are loading"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -30913,6 +30919,12 @@ msgstr ""
|
||||||
msgid "Reports|Metrics reports failed loading results"
|
msgid "Reports|Metrics reports failed loading results"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reports|Metrics reports failed to load results"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reports|Metrics reports: %{strong_start}%{numberOfChanges}%{strong_end} %{changes}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Reports|Scanner"
|
msgid "Reports|Scanner"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -33289,6 +33301,9 @@ msgstr ""
|
||||||
msgid "Select target branch"
|
msgid "Select target branch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select target branch or tag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Select timezone"
|
msgid "Select timezone"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -36041,6 +36056,9 @@ msgstr ""
|
||||||
msgid "Target branch"
|
msgid "Target branch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Target branch or tag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Target-Branch"
|
msgid "Target-Branch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -43009,6 +43027,11 @@ msgstr ""
|
||||||
msgid "cannot merge"
|
msgid "cannot merge"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "change"
|
||||||
|
msgid_plural "changes"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
|
msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -135,8 +135,8 @@ RSpec.describe 'Pipeline Schedules', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows the pipeline schedule with default ref' do
|
it 'shows the pipeline schedule with default ref' do
|
||||||
page.within('.js-target-branch-dropdown') do
|
page.within('[data-testid="schedule-target-ref"]') do
|
||||||
expect(first('.dropdown-toggle-text').text).to eq('master')
|
expect(first('.gl-new-dropdown-button-text').text).to eq('master')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -148,8 +148,8 @@ RSpec.describe 'Pipeline Schedules', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows the pipeline schedule with default ref' do
|
it 'shows the pipeline schedule with default ref' do
|
||||||
page.within('.js-target-branch-dropdown') do
|
page.within('[data-testid="schedule-target-ref"]') do
|
||||||
expect(first('.dropdown-toggle-text').text).to eq('master')
|
expect(first('.gl-new-dropdown-button-text').text).to eq('master')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -293,8 +293,8 @@ RSpec.describe 'Pipeline Schedules', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
def select_target_branch
|
def select_target_branch
|
||||||
find('.js-target-branch-dropdown').click
|
find('[data-testid="schedule-target-ref"] .dropdown-toggle').click
|
||||||
click_link 'master'
|
click_button 'master'
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_pipeline_schedule
|
def save_pipeline_schedule
|
||||||
|
|
|
@ -10,30 +10,37 @@ Object {
|
||||||
Object {
|
Object {
|
||||||
"default": false,
|
"default": false,
|
||||||
"name": "add_images_and_changes",
|
"name": "add_images_and_changes",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"default": false,
|
"default": false,
|
||||||
"name": "conflict-contains-conflict-markers",
|
"name": "conflict-contains-conflict-markers",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"default": false,
|
"default": false,
|
||||||
"name": "deleted-image-test",
|
"name": "deleted-image-test",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"default": false,
|
"default": false,
|
||||||
"name": "diff-files-image-to-symlink",
|
"name": "diff-files-image-to-symlink",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"default": false,
|
"default": false,
|
||||||
"name": "diff-files-symlink-to-image",
|
"name": "diff-files-symlink-to-image",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"default": false,
|
"default": false,
|
||||||
"name": "markdown",
|
"name": "markdown",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"default": true,
|
"default": true,
|
||||||
"name": "master",
|
"name": "master",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"totalCount": 123,
|
"totalCount": 123,
|
||||||
|
@ -54,12 +61,15 @@ Object {
|
||||||
"list": Array [
|
"list": Array [
|
||||||
Object {
|
Object {
|
||||||
"name": "v1.1.1",
|
"name": "v1.1.1",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"name": "v1.1.0",
|
"name": "v1.1.0",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"name": "v1.0.0",
|
"name": "v1.0.0",
|
||||||
|
"value": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"totalCount": 456,
|
"totalCount": 456,
|
||||||
|
|
|
@ -48,6 +48,14 @@ describe('Ref selector Vuex store mutations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe(`${types.SET_USE_SYMBOLIC_REF_NAMES}`, () => {
|
||||||
|
it('sets useSymbolicRefNames on the state', () => {
|
||||||
|
mutations[types.SET_USE_SYMBOLIC_REF_NAMES](state, true);
|
||||||
|
|
||||||
|
expect(state.useSymbolicRefNames).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe(`${types.SET_PROJECT_ID}`, () => {
|
describe(`${types.SET_PROJECT_ID}`, () => {
|
||||||
it('updates the project ID', () => {
|
it('updates the project ID', () => {
|
||||||
const newProjectId = '4';
|
const newProjectId = '4';
|
||||||
|
|
|
@ -228,6 +228,66 @@ RSpec.describe Ci::PipelineSchedule do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#for_tag?' do
|
||||||
|
context 'when the target is a tag' do
|
||||||
|
before do
|
||||||
|
subject.ref = 'refs/tags/v1.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.for_tag?).to eq(true) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the target is a branch' do
|
||||||
|
before do
|
||||||
|
subject.ref = 'refs/heads/main'
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.for_tag?).to eq(false) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is no ref' do
|
||||||
|
before do
|
||||||
|
subject.ref = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.for_tag?).to eq(false) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#ref_for_display' do
|
||||||
|
context 'when the target is a tag' do
|
||||||
|
before do
|
||||||
|
subject.ref = 'refs/tags/v1.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.ref_for_display).to eq('v1.0') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the target is a branch' do
|
||||||
|
before do
|
||||||
|
subject.ref = 'refs/heads/main'
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.ref_for_display).to eq('main') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the ref is ambiguous' do
|
||||||
|
before do
|
||||||
|
subject.ref = 'release-2.8'
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.ref_for_display).to eq('release-2.8') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is no ref' do
|
||||||
|
before do
|
||||||
|
subject.ref = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.ref_for_display).to eq(nil) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'loose foreign key on ci_pipeline_schedules.project_id' do
|
context 'loose foreign key on ci_pipeline_schedules.project_id' do
|
||||||
it_behaves_like 'cleanup by a loose foreign key' do
|
it_behaves_like 'cleanup by a loose foreign key' do
|
||||||
let!(:parent) { create(:project) }
|
let!(:parent) { create(:project) }
|
||||||
|
|
|
@ -489,6 +489,20 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
|
||||||
expect { run_rake_task('db:migrate:main') }.not_to raise_error
|
expect { run_rake_task('db:migrate:main') }.not_to raise_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'db:migrate:geo' do
|
||||||
|
it 'does not invoke gitlab:db:create_dynamic_partitions' do
|
||||||
|
skip 'Skipping because geo database is not setup' unless geo_configured?
|
||||||
|
|
||||||
|
expect(Rake::Task['gitlab:db:create_dynamic_partitions']).not_to receive(:invoke)
|
||||||
|
|
||||||
|
expect { run_rake_task('db:migrate:geo') }.not_to raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
def geo_configured?
|
||||||
|
!!ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'geo')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'gitlab:db:reset_as_non_superuser' do
|
describe 'gitlab:db:reset_as_non_superuser' do
|
||||||
|
|
Loading…
Reference in New Issue