Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 21:10:32 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 21:10:32 +0300
commitbced7d8bcc29bf5b75a03523e74a8e000c10371a (patch)
treed3df9e707fba772ae86370c49819e744880e53e1
parent133b8a64b6d5b57f3cd753f55059b2b90721695e (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/qa-common/main.gitlab-ci.yml2
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/ci_variable_list.js262
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/native_form_variable_list.js25
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue2
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target.vue7
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/take_ownership_modal_legacy.vue50
-rw-r--r--app/assets/javascripts/contribution_events/components/contribution_event/contribution_event_updated.vue25
-rw-r--r--app/assets/javascripts/contribution_events/components/contribution_events.vue5
-rw-r--r--app/assets/javascripts/contribution_events/constants.js14
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.vue2
-rw-r--r--app/assets/javascripts/environments/environment_details/deployments_table.vue2
-rw-r--r--app/assets/javascripts/environments/mount_show.js3
-rw-r--r--app/assets/javascripts/jobs/components/table/jobs_table.vue2
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/edit/index.js7
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js50
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/new/index.js7
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js94
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue3
-rw-r--r--app/assets/stylesheets/page_bundles/pipeline_schedules.scss82
-rw-r--r--app/controllers/projects/environments_controller.rb4
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb5
-rw-r--r--app/graphql/types/ci/pipeline_schedule_type.rb5
-rw-r--r--app/services/commits/create_service.rb7
-rw-r--r--app/views/ci/variables/_variable_row.html.haml36
-rw-r--r--app/views/projects/deployments/_commit.html.haml17
-rw-r--r--app/views/projects/deployments/_deployment.html.haml49
-rw-r--r--app/views/projects/deployments/_rollback.haml4
-rw-r--r--app/views/projects/environments/show.html.haml31
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml43
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml45
-rw-r--r--app/views/projects/pipeline_schedules/_table.html.haml12
-rw-r--r--app/views/projects/pipeline_schedules/_tabs.html.haml12
-rw-r--r--app/views/projects/pipeline_schedules/edit.html.haml6
-rw-r--r--app/views/projects/pipeline_schedules/index.html.haml24
-rw-r--r--app/views/projects/pipeline_schedules/new.html.haml6
-rw-r--r--config/feature_flags/development/environment_details_vue.yml8
-rw-r--r--config/feature_flags/development/errors_utf_8_encoding.yml (renamed from config/feature_flags/development/pipeline_schedules_vue.yml)10
-rw-r--r--config/feature_flags/development/explain_vulnerability_anthropic.yml (renamed from config/feature_flags/development/explain_vulnerability_vertex.yml)8
-rw-r--r--db/post_migrate/20230125093723_rebalance_partition_id_ci_pipeline.rb23
-rw-r--r--db/post_migrate/20230125093840_rebalance_partition_id_ci_build.rb23
-rw-r--r--db/post_migrate/20230208100917_fix_partition_ids_for_ci_pipeline_variable.rb23
-rw-r--r--db/post_migrate/20230208103009_fix_partition_ids_for_ci_job_artifact.rb23
-rw-r--r--db/post_migrate/20230208132608_fix_partition_ids_for_ci_stage.rb23
-rw-r--r--db/post_migrate/20230209090702_fix_partition_ids_for_ci_build_report_result.rb23
-rw-r--r--db/post_migrate/20230209092204_fix_partition_ids_for_ci_build_trace_metadata.rb23
-rw-r--r--db/post_migrate/20230209140102_fix_partition_ids_for_ci_build_metadata.rb23
-rw-r--r--db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb14
-rw-r--r--db/post_migrate/20230214154101_fix_partition_ids_on_ci_sources_pipelines.rb27
-rw-r--r--doc/api/api_resources.md10
-rw-r--r--doc/api/groups.md12
-rw-r--r--doc/api/issues.md2
-rw-r--r--doc/api/members.md2
-rw-r--r--doc/api/notification_settings.md6
-rw-r--r--doc/api/projects.md6
-rw-r--r--doc/development/go_guide/index.md2
-rw-r--r--doc/development/integrations/index.md2
-rw-r--r--doc/user/application_security/sast/analyzers.md2
-rw-r--r--lib/gitlab/background_migration/rebalance_partition_id.rb21
-rw-r--r--locale/gitlab.pot89
-rw-r--r--qa/lib/gitlab/page/group/settings/billing.rb2
-rw-r--r--spec/features/projects/environments/environment_spec.rb188
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb484
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb4
-rw-r--r--spec/frontend/ci/ci_variable_list/ci_variable_list/ci_variable_list_spec.js161
-rw-r--r--spec/frontend/ci/ci_variable_list/ci_variable_list/native_form_variable_list_spec.js41
-rw-r--r--spec/frontend/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target_spec.js36
-rw-r--r--spec/frontend/ci/pipeline_schedules/components/take_ownership_modal_legacy_spec.js42
-rw-r--r--spec/frontend/contribution_events/components/contribution_event/contribution_event_updated_spec.js31
-rw-r--r--spec/frontend/contribution_events/components/contribution_events_spec.js4
-rw-r--r--spec/frontend/contribution_events/utils.js85
-rw-r--r--spec/frontend/fixtures/pipeline_schedules.rb29
-rw-r--r--spec/frontend/jobs/components/table/jobs_table_spec.js9
-rw-r--r--spec/lib/gitlab/background_migration/rebalance_partition_id_spec.rb46
-rw-r--r--spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb58
-rw-r--r--spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb58
-rw-r--r--spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb58
-rw-r--r--spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb58
-rw-r--r--spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb58
-rw-r--r--spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb60
-rw-r--r--spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb60
-rw-r--r--spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb60
-rw-r--r--spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb51
-rw-r--r--spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb45
-rw-r--r--spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb49
85 files changed, 476 insertions, 2658 deletions
diff --git a/.gitlab/ci/qa-common/main.gitlab-ci.yml b/.gitlab/ci/qa-common/main.gitlab-ci.yml
index 5c9043f8694..b48c3f67a6f 100644
--- a/.gitlab/ci/qa-common/main.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/main.gitlab-ci.yml
@@ -6,7 +6,7 @@ workflow:
include:
- project: gitlab-org/quality/pipeline-common
- ref: 7.2.3
+ ref: 7.5.0
file:
- /ci/base.gitlab-ci.yml
- /ci/knapsack-report.yml
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index a7f17a90700..ae2e9dfcb03 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0183d30e998cfab0b4f93fd1aa60200fba8e3771
+46892cb4fa5b0e86b7e86fbb7acda5effac412d6
diff --git a/app/assets/javascripts/ci/ci_variable_list/ci_variable_list.js b/app/assets/javascripts/ci/ci_variable_list/ci_variable_list.js
deleted file mode 100644
index 574a5e7fd99..00000000000
--- a/app/assets/javascripts/ci/ci_variable_list/ci_variable_list.js
+++ /dev/null
@@ -1,262 +0,0 @@
-import $ from 'jquery';
-import SecretValues from '~/behaviors/secret_values';
-import CreateItemDropdown from '~/create_item_dropdown';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import { s__ } from '~/locale';
-
-const ALL_ENVIRONMENTS_STRING = s__('CiVariable|All environments');
-
-function createEnvironmentItem(value) {
- return {
- title: value === '*' ? ALL_ENVIRONMENTS_STRING : value,
- id: value,
- text: value === '*' ? s__('CiVariable|* (All environments)') : value,
- };
-}
-
-export default class VariableList {
- constructor({ container, formField, maskableRegex }) {
- this.$container = $(container);
- this.formField = formField;
- this.maskableRegex = new RegExp(maskableRegex);
- this.environmentDropdownMap = new WeakMap();
-
- this.inputMap = {
- id: {
- selector: '.js-ci-variable-input-id',
- default: '',
- },
- variable_type: {
- selector: '.js-ci-variable-input-variable-type',
- default: 'env_var',
- },
- key: {
- selector: '.js-ci-variable-input-key',
- default: '',
- },
- secret_value: {
- selector: '.js-ci-variable-input-value',
- default: '',
- },
- protected: {
- selector: '.js-ci-variable-input-protected',
- // use `attr` instead of `data` as we don't want the value to be
- // converted. we need the value as a string.
- default: $('.js-ci-variable-input-protected').attr('data-default'),
- },
- masked: {
- selector: '.js-ci-variable-input-masked',
- // use `attr` instead of `data` as we don't want the value to be
- // converted. we need the value as a string.
- default: $('.js-ci-variable-input-masked').attr('data-default'),
- },
- environment_scope: {
- // We can't use a `.js-` class here because
- // deprecated_jquery_dropdown replaces the <input> and doesn't copy over the class
- // See https://gitlab.com/gitlab-org/gitlab-foss/issues/42458
- selector: `input[name="${this.formField}[variables_attributes][][environment_scope]"]`,
- default: '*',
- },
- _destroy: {
- selector: '.js-ci-variable-input-destroy',
- default: '',
- },
- };
-
- this.secretValues = new SecretValues({
- container: this.$container[0],
- valueSelector: '.js-row:not(:last-child) .js-secret-value',
- placeholderSelector: '.js-row:not(:last-child) .js-secret-value-placeholder',
- });
- }
-
- init() {
- this.bindEvents();
- this.secretValues.init();
- }
-
- bindEvents() {
- this.$container.find('.js-row').each((index, rowEl) => {
- this.initRow(rowEl);
- });
-
- this.$container.on('click', '.js-row-remove-button', (e) => {
- e.preventDefault();
- this.removeRow($(e.currentTarget).closest('.js-row'));
- });
-
- const inputSelector = Object.keys(this.inputMap)
- .map((name) => this.inputMap[name].selector)
- .join(',');
-
- // Remove any empty rows except the last row
- this.$container.on('blur', inputSelector, (e) => {
- const $row = $(e.currentTarget).closest('.js-row');
-
- if ($row.is(':not(:last-child)') && !this.checkIfRowTouched($row)) {
- this.removeRow($row);
- }
- });
-
- this.$container.on('input trigger-change', inputSelector, (e) => {
- // Always make sure there is an empty last row
- const $lastRow = this.$container.find('.js-row').last();
-
- if (this.checkIfRowTouched($lastRow)) {
- this.insertRow($lastRow);
- }
-
- // If masked, validate value against regex
- this.validateMaskability($(e.currentTarget).closest('.js-row'));
- });
- }
-
- initRow(rowEl) {
- const $row = $(rowEl);
-
- // Reset the resizable textarea
- $row.find(this.inputMap.secret_value.selector).css('height', '');
-
- const $environmentSelect = $row.find('.js-variable-environment-toggle');
- if ($environmentSelect.length) {
- const createItemDropdown = new CreateItemDropdown({
- $dropdown: $environmentSelect,
- defaultToggleLabel: ALL_ENVIRONMENTS_STRING,
- fieldName: `${this.formField}[variables_attributes][][environment_scope]`,
- getData: (term, callback) => callback(this.getEnvironmentValues()),
- createNewItemFromValue: createEnvironmentItem,
- onSelect: () => {
- // Refresh the other dropdowns in the variable list
- // so they have the new value we just picked
- this.refreshDropdownData();
-
- $row.find(this.inputMap.environment_scope.selector).trigger('trigger-change');
- },
- });
-
- // Clear out any data that might have been left-over from the row clone
- createItemDropdown.clearDropdown();
-
- this.environmentDropdownMap.set($row[0], createItemDropdown);
- }
- }
-
- insertRow($row) {
- const $rowClone = $row.clone();
- $rowClone.removeAttr('data-is-persisted');
-
- // Reset the inputs to their defaults
- Object.keys(this.inputMap).forEach((name) => {
- const entry = this.inputMap[name];
- $rowClone.find(entry.selector).val(entry.default);
- });
-
- // Close any dropdowns
- $rowClone.find('.dropdown-menu.show').each((index, $dropdown) => {
- $dropdown.classList.remove('show');
- });
-
- this.initRow($rowClone);
-
- $row.after($rowClone);
- }
-
- removeRow(row) {
- const $row = $(row);
- const isPersisted = parseBoolean($row.attr('data-is-persisted'));
-
- if (isPersisted) {
- $row.hide();
- $row
- // eslint-disable-next-line no-underscore-dangle
- .find(this.inputMap._destroy.selector)
- .val(true);
- } else {
- $row.remove();
- }
-
- // Refresh the other dropdowns in the variable list
- // so any value with the variable deleted is gone
- this.refreshDropdownData();
- }
-
- checkIfRowTouched($row) {
- return Object.keys(this.inputMap).some((name) => {
- // Row should not qualify as touched if only switches have been touched
- if (['protected', 'masked'].includes(name)) return false;
-
- const entry = this.inputMap[name];
- const $el = $row.find(entry.selector);
- return $el.length && $el.val() !== entry.default;
- });
- }
-
- validateMaskability($row) {
- const invalidInputClass = 'gl-field-error-outline';
-
- const variableValue = $row.find(this.inputMap.secret_value.selector).val();
- const isValueMaskable = this.maskableRegex.test(variableValue) || variableValue === '';
- const isMaskedChecked = $row.find(this.inputMap.masked.selector).val() === 'true';
-
- // Show a validation error if the user wants to mask an unmaskable variable value
- $row
- .find(this.inputMap.secret_value.selector)
- .toggleClass(invalidInputClass, isMaskedChecked && !isValueMaskable);
- $row
- .find('.js-secret-value-placeholder')
- .toggleClass(invalidInputClass, isMaskedChecked && !isValueMaskable);
- $row.find('.masking-validation-error').toggle(isMaskedChecked && !isValueMaskable);
- }
-
- toggleEnableRow(isEnabled = true) {
- this.$container.find(this.inputMap.key.selector).attr('disabled', !isEnabled);
- this.$container.find('.js-row-remove-button').attr('disabled', !isEnabled);
- }
-
- hideValues() {
- this.secretValues.updateDom(false);
- }
-
- getAllData() {
- // Ignore the last empty row because we don't want to try persist
- // a blank variable and run into validation problems.
- const validRows = this.$container.find('.js-row').toArray().slice(0, -1);
-
- return validRows.map((rowEl) => {
- const resultant = {};
- Object.keys(this.inputMap).forEach((name) => {
- const entry = this.inputMap[name];
- const $input = $(rowEl).find(entry.selector);
- if ($input.length) {
- resultant[name] = $input.val();
- }
- });
-
- return resultant;
- });
- }
-
- getEnvironmentValues() {
- const valueMap = this.$container
- .find(this.inputMap.environment_scope.selector)
- .toArray()
- .reduce(
- (prevValueMap, envInput) => ({
- ...prevValueMap,
- [envInput.value]: envInput.value,
- }),
- {},
- );
-
- return Object.keys(valueMap).map(createEnvironmentItem);
- }
-
- refreshDropdownData() {
- this.$container.find('.js-row').each((index, rowEl) => {
- const environmentDropdown = this.environmentDropdownMap.get(rowEl);
- if (environmentDropdown) {
- environmentDropdown.refreshData();
- }
- });
- }
-}
diff --git a/app/assets/javascripts/ci/ci_variable_list/native_form_variable_list.js b/app/assets/javascripts/ci/ci_variable_list/native_form_variable_list.js
deleted file mode 100644
index fdbefd8c313..00000000000
--- a/app/assets/javascripts/ci/ci_variable_list/native_form_variable_list.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import $ from 'jquery';
-import VariableList from './ci_variable_list';
-
-// Used for the variable list on scheduled pipeline edit page
-export default function setupNativeFormVariableList({ container, formField = 'variables' }) {
- const $container = $(container);
-
- const variableList = new VariableList({
- container: $container,
- formField,
- });
- variableList.init();
-
- // Clear out the names in the empty last row so it
- // doesn't get submitted and throw validation errors
- $container.closest('form').on('submit trigger-submit', () => {
- const $lastRow = $container.find('.js-row').last();
-
- const isTouched = variableList.checkIfRowTouched($lastRow);
- if (!isTouched) {
- $lastRow.find('input, textarea').attr('name', '');
- $lastRow.find('select').attr('name', '');
- }
- });
-}
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue
index 396ff9808f2..ea019a95cd2 100644
--- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue
@@ -81,7 +81,7 @@ export default {
this.description = schedule.description;
this.cron = schedule.cron;
this.cronTimezone = schedule.cronTimezone;
- this.scheduleRef = schedule.ref;
+ this.scheduleRef = schedule.ref || this.defaultBranch;
this.variables = variables.map((variable) => {
return {
id: variable.id,
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target.vue b/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target.vue
index 08efa794bcc..56d50026f17 100644
--- a/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target.vue
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target.vue
@@ -27,10 +27,13 @@ export default {
</script>
<template>
- <div>
- <gl-icon :name="iconName" />
+ <div data-testid="pipeline-schedule-target">
<span v-if="refPath">
+ <gl-icon :name="iconName" />
<gl-link :href="refPath" class="gl-text-gray-900">{{ refDisplay }}</gl-link>
</span>
+ <span v-else>
+ {{ s__('PipelineSchedules|None') }}
+ </span>
</div>
</template>
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/take_ownership_modal_legacy.vue b/app/assets/javascripts/ci/pipeline_schedules/components/take_ownership_modal_legacy.vue
deleted file mode 100644
index b4d84309c5f..00000000000
--- a/app/assets/javascripts/ci/pipeline_schedules/components/take_ownership_modal_legacy.vue
+++ /dev/null
@@ -1,50 +0,0 @@
-<script>
-import { GlModal } from '@gitlab/ui';
-import { __, s__ } from '~/locale';
-
-export default {
- components: {
- GlModal,
- },
- props: {
- ownershipUrl: {
- type: String,
- required: true,
- },
- },
- modalId: 'pipeline-take-ownership-modal',
- i18n: {
- takeOwnership: s__('PipelineSchedules|Take ownership'),
- ownershipMessage: s__(
- 'PipelineSchedules|Only the owner of a pipeline schedule can make changes to it. Do you want to take ownership of this schedule?',
- ),
- cancelLabel: __('Cancel'),
- },
- computed: {
- actionCancel() {
- return { text: this.$options.i18n.cancelLabel };
- },
- actionPrimary() {
- return {
- text: this.$options.i18n.takeOwnership,
- attributes: {
- variant: 'confirm',
- category: 'primary',
- href: this.ownershipUrl,
- 'data-method': 'post',
- },
- };
- },
- },
-};
-</script>
-<template>
- <gl-modal
- :modal-id="$options.modalId"
- :action-primary="actionPrimary"
- :action-cancel="actionCancel"
- :title="$options.i18n.takeOwnership"
- >
- <p>{{ $options.i18n.ownershipMessage }}</p>
- </gl-modal>
-</template>
diff --git a/app/assets/javascripts/contribution_events/components/contribution_event/contribution_event_updated.vue b/app/assets/javascripts/contribution_events/components/contribution_event/contribution_event_updated.vue
new file mode 100644
index 00000000000..e795e611ee5
--- /dev/null
+++ b/app/assets/javascripts/contribution_events/components/contribution_event/contribution_event_updated.vue
@@ -0,0 +1,25 @@
+<script>
+import { EVENT_UPDATED_I18N } from '../../constants';
+import { getValueByEventTarget } from '../../utils';
+import ContributionEventBase from './contribution_event_base.vue';
+
+export default {
+ name: 'ContributionEventUpdated',
+ components: { ContributionEventBase },
+ props: {
+ event: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ message() {
+ return getValueByEventTarget(EVENT_UPDATED_I18N, this.event);
+ },
+ },
+};
+</script>
+
+<template>
+ <contribution-event-base :event="event" :message="message" icon-name="pencil" />
+</template>
diff --git a/app/assets/javascripts/contribution_events/components/contribution_events.vue b/app/assets/javascripts/contribution_events/components/contribution_events.vue
index 8b42d77675f..1abb33a4d7c 100644
--- a/app/assets/javascripts/contribution_events/components/contribution_events.vue
+++ b/app/assets/javascripts/contribution_events/components/contribution_events.vue
@@ -12,6 +12,7 @@ import {
EVENT_TYPE_CLOSED,
EVENT_TYPE_REOPENED,
EVENT_TYPE_COMMENTED,
+ EVENT_TYPE_UPDATED,
} from '../constants';
import ContributionEventApproved from './contribution_event/contribution_event_approved.vue';
import ContributionEventExpired from './contribution_event/contribution_event_expired.vue';
@@ -24,6 +25,7 @@ import ContributionEventCreated from './contribution_event/contribution_event_cr
import ContributionEventClosed from './contribution_event/contribution_event_closed.vue';
import ContributionEventReopened from './contribution_event/contribution_event_reopened.vue';
import ContributionEventCommented from './contribution_event/contribution_event_commented.vue';
+import ContributionEventUpdated from './contribution_event/contribution_event_updated.vue';
export default {
props: {
@@ -151,6 +153,9 @@ export default {
case EVENT_TYPE_COMMENTED:
return ContributionEventCommented;
+ case EVENT_TYPE_UPDATED:
+ return ContributionEventUpdated;
+
default:
return EmptyComponent;
}
diff --git a/app/assets/javascripts/contribution_events/constants.js b/app/assets/javascripts/contribution_events/constants.js
index b5eddbf7e25..94224b08e3c 100644
--- a/app/assets/javascripts/contribution_events/constants.js
+++ b/app/assets/javascripts/contribution_events/constants.js
@@ -119,14 +119,24 @@ export const EVENT_COMMENTED_I18N = Object.freeze({
[COMMIT_NOTEABLE_TYPE]: s__(
'ContributionEvent|Commented on commit %{noteableLink} in %{resourceParentLink}.',
),
- fallback: s__('ContributionEvent|Commented on %{noteableLink}.'),
+ [TYPE_FALLBACK]: s__('ContributionEvent|Commented on %{noteableLink}.'),
});
export const EVENT_COMMENTED_SNIPPET_I18N = Object.freeze({
[RESOURCE_PARENT_TYPE_PROJECT]: s__(
'ContributionEvent|Commented on snippet %{noteableLink} in %{resourceParentLink}.',
),
- fallback: s__('ContributionEvent|Commented on snippet %{noteableLink}.'),
+ [TYPE_FALLBACK]: s__('ContributionEvent|Commented on snippet %{noteableLink}.'),
+});
+
+export const EVENT_UPDATED_I18N = Object.freeze({
+ [TARGET_TYPE_DESIGN]: s__(
+ 'ContributionEvent|Updated design %{targetLink} in %{resourceParentLink}.',
+ ),
+ [TARGET_TYPE_WIKI]: s__(
+ 'ContributionEvent|Updated wiki page %{targetLink} in %{resourceParentLink}.',
+ ),
+ [TYPE_FALLBACK]: s__('ContributionEvent|Updated resource.'),
});
export const EVENT_CLOSED_ICONS = Object.freeze({
diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue
index d49598d2f21..926c556966c 100644
--- a/app/assets/javascripts/environments/components/environment_actions.vue
+++ b/app/assets/javascripts/environments/components/environment_actions.vue
@@ -87,7 +87,7 @@ export default {
</script>
<template>
<gl-disclosure-dropdown
- :text="title"
+ :toggle-text="title"
:title="title"
:loading="isLoading"
:aria-label="title"
diff --git a/app/assets/javascripts/environments/environment_details/deployments_table.vue b/app/assets/javascripts/environments/environment_details/deployments_table.vue
index f37f93798ae..261d8106438 100644
--- a/app/assets/javascripts/environments/environment_details/deployments_table.vue
+++ b/app/assets/javascripts/environments/environment_details/deployments_table.vue
@@ -36,7 +36,7 @@ export default {
<deployment-status-link :deployment-job="item.job" :status="item.status" />
</template>
<template #cell(id)="{ item }">
- <strong>{{ item.id }}</strong>
+ <strong data-testid="deployment-id">{{ item.id }}</strong>
</template>
<template #cell(triggerer)="{ item }">
<deployment-triggerer :triggerer="item.triggerer" />
diff --git a/app/assets/javascripts/environments/mount_show.js b/app/assets/javascripts/environments/mount_show.js
index fb9a7a02d07..9924e1c7d7b 100644
--- a/app/assets/javascripts/environments/mount_show.js
+++ b/app/assets/javascripts/environments/mount_show.js
@@ -59,9 +59,6 @@ export const initHeader = () => {
};
export const initPage = async () => {
- if (!gon.features.environmentDetailsVue) {
- return null;
- }
const EnvironmentsDetailPageModule = await import('./environment_details/index.vue');
const EnvironmentsDetailPage = EnvironmentsDetailPageModule.default;
const dataElement = document.getElementById('environments-detail-view');
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table.vue b/app/assets/javascripts/jobs/components/table/jobs_table.vue
index 84479ec421e..474131363b8 100644
--- a/app/assets/javascripts/jobs/components/table/jobs_table.vue
+++ b/app/assets/javascripts/jobs/components/table/jobs_table.vue
@@ -85,7 +85,7 @@ export default {
<template #cell(stage)="{ item }">
<div class="gl-text-truncate">
- <span data-testid="job-stage-name">{{ item.stage.name }}</span>
+ <span v-if="item.stage" data-testid="job-stage-name">{{ item.stage.name }}</span>
</div>
</template>
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/edit/index.js b/app/assets/javascripts/pages/projects/pipeline_schedules/edit/index.js
index a51c2e9c47b..f48c38b776f 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/edit/index.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/edit/index.js
@@ -1,8 +1,3 @@
import initPipelineSchedulesFormApp from '~/ci/pipeline_schedules/mount_pipeline_schedules_form_app';
-import initForm from '../shared/init_form';
-if (gon.features?.pipelineSchedulesVue) {
- initPipelineSchedulesFormApp('#pipeline-schedules-form-edit', true);
-} else {
- initForm();
-}
+initPipelineSchedulesFormApp('#pipeline-schedules-form-edit', true);
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
index 4bdbb70d942..ec183edda53 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
@@ -1,7 +1,5 @@
import Vue from 'vue';
-import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import initPipelineSchedulesApp from '~/ci/pipeline_schedules/mount_pipeline_schedules_app';
-import PipelineSchedulesTakeOwnershipModalLegacy from '~/ci/pipeline_schedules/components/take_ownership_modal_legacy.vue';
import PipelineSchedulesCallout from '../shared/components/pipeline_schedules_callout.vue';
function initPipelineSchedulesCallout() {
@@ -27,49 +25,5 @@ function initPipelineSchedulesCallout() {
});
}
-// TODO: move take ownership feature into new Vue app
-// located in directory app/assets/javascripts/pipeline_schedules/components
-function initTakeownershipModal() {
- const modalId = 'pipeline-take-ownership-modal';
- const buttonSelector = 'js-take-ownership-button';
- const el = document.getElementById(modalId);
- const takeOwnershipButtons = document.querySelectorAll(`.${buttonSelector}`);
-
- if (!el) {
- return;
- }
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- data() {
- return {
- url: '',
- };
- },
- mounted() {
- takeOwnershipButtons.forEach((button) => {
- button.addEventListener('click', () => {
- const { url } = button.dataset;
-
- this.url = url;
- this.$root.$emit(BV_SHOW_MODAL, modalId, `.${buttonSelector}`);
- });
- });
- },
- render(createElement) {
- return createElement(PipelineSchedulesTakeOwnershipModalLegacy, {
- props: {
- ownershipUrl: this.url,
- },
- });
- },
- });
-}
-
-if (gon.features?.pipelineSchedulesVue) {
- initPipelineSchedulesApp();
-} else {
- initPipelineSchedulesCallout();
- initTakeownershipModal();
-}
+initPipelineSchedulesApp();
+initPipelineSchedulesCallout();
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/new/index.js b/app/assets/javascripts/pages/projects/pipeline_schedules/new/index.js
index d8ba7bbd752..672e3d014bd 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/new/index.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/new/index.js
@@ -1,8 +1,3 @@
import initPipelineSchedulesFormApp from '~/ci/pipeline_schedules/mount_pipeline_schedules_form_app';
-import initForm from '../shared/init_form';
-if (gon.features?.pipelineSchedulesVue) {
- initPipelineSchedulesFormApp('#pipeline-schedules-form-new');
-} else {
- initForm();
-}
+initPipelineSchedulesFormApp('#pipeline-schedules-form-new');
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
deleted file mode 100644
index 8440d0e77cd..00000000000
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import $ from 'jquery';
-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/ci_variable_list/native_form_variable_list';
-import GlFieldErrors from '~/gl_field_errors';
-import Translate from '~/vue_shared/translate';
-import { initTimezoneDropdown } from '../../../profiles/init_timezone_dropdown';
-import IntervalPatternInput from './components/interval_pattern_input.vue';
-
-Vue.use(Translate);
-
-function initIntervalPatternInput() {
- const intervalPatternMount = document.getElementById('interval-pattern-input');
- const initialCronInterval = intervalPatternMount?.dataset?.initialInterval;
- const dailyLimit = intervalPatternMount.dataset?.dailyLimit;
-
- return new Vue({
- el: intervalPatternMount,
- components: {
- IntervalPatternInput,
- },
- render(createElement) {
- return createElement('interval-pattern-input', {
- props: {
- initialCronInterval,
- dailyLimit,
- },
- });
- },
- });
-}
-
-function getEnabledRefTypes() {
- return [REF_TYPE_BRANCHES, REF_TYPE_TAGS];
-}
-
-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: __('Select target branch or tag'),
- },
- },
- class: 'gl-w-full',
- });
- },
- });
-
- refDropdown.$children[0].$on('input', (newRef) => {
- $refField.value = newRef;
- });
-
- return refDropdown;
-}
-
-export default () => {
- /* 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
- * to share state, it may make sense to refactor the whole form to Vue */
-
- initIntervalPatternInput();
-
- // Initialize non-Vue JS components in the form
-
- const formElement = document.getElementById('new-pipeline-schedule-form');
-
- gl.pipelineScheduleFieldErrors = new GlFieldErrors(formElement);
-
- initTargetRefDropdown();
-
- setupNativeFormVariableList({
- container: $('.js-ci-variable-list-section'),
- formField: 'schedule',
- });
-};
-
-initTimezoneDropdown();
diff --git a/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue b/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue
index 4affcd926d4..3ce41121100 100644
--- a/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue
+++ b/app/assets/javascripts/projects/settings_service_desk/components/custom_email_form.vue
@@ -149,7 +149,6 @@ export default {
id="custom-email-form-forwarding"
ref="service-desk-incoming-email"
type="text"
- data-testid="custom-email-form-forwarding"
:aria-label="$options.I18N_FORM_FORWARDING_LABEL"
:value="incomingEmail"
:disabled="true"
@@ -167,7 +166,6 @@ export default {
<gl-form-group
:label="$options.I18N_FORM_CUSTOM_EMAIL_LABEL"
label-for="custom-email-form-custom-email"
- data-testid="form-group-custom-email"
:invalid-feedback="$options.I18N_FORM_INVALID_FEEDBACK_CUSTOM_EMAIL"
class="gl-mt-3"
:description="$options.I18N_FORM_CUSTOM_EMAIL_DESCRIPTION"
@@ -191,7 +189,6 @@ export default {
<gl-form-group
:label="$options.I18N_FORM_SMTP_ADDRESS_LABEL"
label-for="custom-email-form-smtp-address"
- data-testid="form-group-smtp-address"
:invalid-feedback="$options.I18N_FORM_INVALID_FEEDBACK_SMTP_ADDRESS"
class="gl-mt-3"
>
diff --git a/app/assets/stylesheets/page_bundles/pipeline_schedules.scss b/app/assets/stylesheets/page_bundles/pipeline_schedules.scss
deleted file mode 100644
index af2dac7739e..00000000000
--- a/app/assets/stylesheets/page_bundles/pipeline_schedules.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-@import 'mixins_and_variables_and_functions';
-
-.ci-variable-list {
- margin-left: 0;
- margin-bottom: 0;
- padding-left: 0;
- list-style: none;
- clear: both;
-}
-
-.ci-variable-row {
- display: flex;
- align-items: flex-start;
-
- @include media-breakpoint-down(xs) {
- align-items: flex-end;
- }
-
- &:not(:last-child) {
- margin-bottom: $gl-btn-padding;
-
- @include media-breakpoint-down(xs) {
- margin-bottom: 3 * $gl-btn-padding;
- }
- }
-
- &:last-child {
- .ci-variable-body-item:last-child {
- margin-right: $ci-variable-remove-button-width;
-
- @include media-breakpoint-down(xs) {
- margin-right: 0;
- }
- }
-
- .ci-variable-row-remove-button {
- display: none;
- }
-
- @include media-breakpoint-down(xs) {
- .ci-variable-row-body {
- margin-right: $ci-variable-remove-button-width;
- }
- }
- }
-}
-
-.ci-variable-row-body {
- display: flex;
- align-items: flex-start;
- width: 100%;
- padding-bottom: $gl-padding;
-
- @include media-breakpoint-down(xs) {
- display: block;
- }
-}
-
-.ci-variable-body-item {
- flex: 1;
-
- &:not(:last-child) {
- margin-right: $gl-btn-padding;
-
- @include media-breakpoint-down(xs) {
- margin-right: 0;
- margin-bottom: $gl-btn-padding;
- }
- }
-}
-
-.pipeline-schedule-form {
- .gl-field-error {
- margin: 10px 0 0;
- }
-}
-
-.pipeline-schedule-table-row {
- a {
- color: var(--gl-text-color, $gl-text-color);
- }
-}
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 127fe40b0e3..e1e0bb83b40 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -8,10 +8,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
layout 'project'
- before_action only: [:show] do
- push_frontend_feature_flag(:environment_details_vue, @project)
- end
-
before_action only: [:index, :edit, :new] do
push_frontend_feature_flag(:flux_resource_for_environment)
end
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index 42b6d83ee85..83a64579446 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -9,7 +9,6 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
before_action :authorize_create_pipeline_schedule!, only: [:new, :create]
before_action :authorize_update_pipeline_schedule!, only: [:edit, :update]
before_action :authorize_admin_pipeline_schedule!, only: [:take_ownership, :destroy]
- before_action :push_schedule_feature_flag, only: [:index, :new, :edit]
feature_category :continuous_integration
urgency :low
@@ -120,8 +119,4 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
def authorize_admin_pipeline_schedule!
return access_denied! unless can?(current_user, :admin_pipeline_schedule, schedule)
end
-
- def push_schedule_feature_flag
- push_frontend_feature_flag(:pipeline_schedules_vue, @project)
- end
end
diff --git a/app/graphql/types/ci/pipeline_schedule_type.rb b/app/graphql/types/ci/pipeline_schedule_type.rb
index 71a1f28ea38..e2e3bd8cfbd 100644
--- a/app/graphql/types/ci/pipeline_schedule_type.rb
+++ b/app/graphql/types/ci/pipeline_schedule_type.rb
@@ -68,7 +68,10 @@ module Types
null: false, description: 'Timestamp of when the pipeline schedule was last updated.'
def ref_path
- ::Gitlab::Routing.url_helpers.project_commits_path(object.project, object.ref_for_display)
+ ref_for_display = object.ref_for_display
+ return unless ref_for_display
+
+ ::Gitlab::Routing.url_helpers.project_commits_path(object.project, ref_for_display)
end
def edit_path
diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb
index a498d39d34e..89370bd8abb 100644
--- a/app/services/commits/create_service.rb
+++ b/app/services/commits/create_service.rb
@@ -39,7 +39,12 @@ module Commits
Gitlab::Git::PreReceiveError,
Gitlab::Git::CommandError => ex
Gitlab::ErrorTracking.log_exception(ex)
- error(ex.message)
+
+ if Feature.enabled?(:errors_utf_8_encoding)
+ error(Gitlab::EncodingHelper.encode_utf8_no_detect(ex.message))
+ else
+ error(ex.message)
+ end
end
private
diff --git a/app/views/ci/variables/_variable_row.html.haml b/app/views/ci/variables/_variable_row.html.haml
deleted file mode 100644
index a710655aa20..00000000000
--- a/app/views/ci/variables/_variable_row.html.haml
+++ /dev/null
@@ -1,36 +0,0 @@
-- form_field = local_assigns.fetch(:form_field, nil)
-- variable = local_assigns.fetch(:variable, nil)
-
-- id = variable&.id
-- variable_type = variable&.variable_type
-- key = variable&.key
-- value = variable&.value
-
-- id_input_name = "#{form_field}[variables_attributes][][id]"
-- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
-- variable_type_input_name = "#{form_field}[variables_attributes][][variable_type]"
-- key_input_name = "#{form_field}[variables_attributes][][key]"
-- value_input_name = "#{form_field}[variables_attributes][][secret_value]"
-
-%li.js-row.ci-variable-row{ data: { is_persisted: "#{!id.nil?}" } }
- .ci-variable-row-body.border-bottom
- %input.js-ci-variable-input-id{ type: "hidden", name: id_input_name, value: id }
- %input.js-ci-variable-input-destroy{ type: "hidden", name: destroy_input_name }
- %select.js-ci-variable-input-variable-type.ci-variable-body-item.form-control.select-control.custom-select.table-section.section-15{ name: variable_type_input_name }
- = options_for_select(ci_variable_type_options, variable_type)
- %input.js-ci-variable-input-key.ci-variable-body-item.form-control.gl-form-input.table-section.section-15{ type: "text",
- name: key_input_name,
- value: key,
- placeholder: s_('CiVariables|Input variable key') }
- .ci-variable-body-item.gl-show-field-errors.table-section.section-15.border-top-0.p-0
- .form-control.js-secret-value-placeholder.overflow-hidden{ class: ('hide' unless id) }
- = '*' * 17
- %textarea.js-ci-variable-input-value.js-secret-value.form-control.gl-form-input{ class: ('hide' if id),
- rows: 1,
- name: value_input_name,
- placeholder: s_('CiVariables|Input variable value') }
- = value
- %p.masking-validation-error.gl-field-error.hide
- = s_("CiVariables|Cannot use Masked Variable with current value")
- = link_to sprite_icon('question-o'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
- = render Pajamas::ButtonComponent.new(icon: 'close', button_options: { class: 'js-row-remove-button ci-variable-row-remove-button table-section', 'aria-label': s_('CiVariables|Remove variable row') })
diff --git a/app/views/projects/deployments/_commit.html.haml b/app/views/projects/deployments/_commit.html.haml
deleted file mode 100644
index 509ed62b39d..00000000000
--- a/app/views/projects/deployments/_commit.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-.table-mobile-content
- .branch-commit.cgray
- - if deployment.ref
- %span.icon-container.gl-display-inline-block
- = deployment.tag? ? sprite_icon('tag', css_class: 'sprite') : sprite_icon('fork', css_class: 'sprite')
- = link_to deployment.ref, project_ref_path(@project, deployment.ref), class: "ref-name"
- .icon-container.commit-icon
- = custom_icon("icon_commit")
- = link_to deployment.short_sha, project_commit_path(@project, deployment.sha), class: "commit-sha mr-0"
-
- %p.commit-title.flex-truncate-parent
- %span.flex-truncate-child
- - if commit_title = deployment.commit_title
- = author_avatar(deployment.commit, size: 20)
- = link_to_markdown commit_title, project_commit_path(@project, deployment.sha), class: "commit-row-message cgray"
- - else
- = _("Can't find HEAD commit for this branch")
diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml
deleted file mode 100644
index e3688c8d323..00000000000
--- a/app/views/projects/deployments/_deployment.html.haml
+++ /dev/null
@@ -1,49 +0,0 @@
-.gl-responsive-table-row.deployment{ role: 'row' }
- .table-section.section-15{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("Status")
- .table-mobile-content
- = render_deployment_status(deployment)
-
- .table-section.section-10{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("ID")
- %strong.table-mobile-content{ data: { testid: 'deployment-id' } } ##{deployment.iid}
-
- .table-section.section-10{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("Triggerer")
- .table-mobile-content
- - if deployment.deployed_by
- = user_avatar(user: deployment.deployed_by, size: 26, css_class: "mr-0 float-none")
-
- .table-section.section-25{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("Commit")
- = render 'projects/deployments/commit', deployment: deployment
-
- .table-section.section-10.build-column{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("Job")
- - if deployment.deployable
- .table-mobile-content
- .flex-truncate-parent
- .flex-truncate-child.has-tooltip.gl-white-space-normal.gl-md-white-space-nowrap{ :title => "#{deployment.deployable.name} (##{deployment.deployable.id})", data: { container: 'body' } }
- = link_to deployment_path(deployment), class: 'build-link' do
- #{deployment.deployable.name} (##{deployment.deployable.id})
- - else
- = gl_badge_tag s_('Deployment|API'), { variant: :info }, { class: 'gl-cursor-help', data: { toggle: 'tooltip' }, title: s_('Deployment|This deployment was created using the API') }
-
- .table-section.section-10{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("Created")
- %span.table-mobile-content.flex-truncate-parent
- %span.flex-truncate-child
- = time_ago_with_tooltip(deployment.created_at)
-
- .table-section.section-10{ role: 'gridcell' }
- .table-mobile-header{ role: 'rowheader' }= _("Deployed")
- - if deployment.deployed_at
- %span.table-mobile-content.flex-truncate-parent
- %span.flex-truncate-child
- = time_ago_with_tooltip(deployment.deployed_at)
-
- .table-section.section-10.table-button-footer{ role: 'gridcell' }
- .btn-group.table-action-buttons
- = render 'projects/deployments/actions', deployment: deployment
- = render 'projects/deployments/rollback', deployment: deployment
- = render_if_exists 'projects/deployments/approvals', deployment: deployment
diff --git a/app/views/projects/deployments/_rollback.haml b/app/views/projects/deployments/_rollback.haml
deleted file mode 100644
index e50fa1fa0f7..00000000000
--- a/app/views/projects/deployments/_rollback.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-- if deployment.deployable && can?(current_user, :play_job, deployment.deployable)
- - tooltip = deployment.last? ? s_('Environments|Re-deploy to environment') : s_('Environments|Rollback environment')
- - icon = deployment.last? ? 'repeat' : 'redo'
- = render Pajamas::ButtonComponent.new(icon: icon, button_options: { title: tooltip, class: 'js-confirm-rollback-modal-button has-tooltip', data: { environment_name: @environment.name, commit_short_sha: deployment.short_sha, commit_url: project_commit_path(@project, deployment.sha), is_last_deployment: deployment.last?.to_s, retry_path: retry_project_job_path(@environment.project, deployment.deployable) } })
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index e97cae911d9..46ec430cadb 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -8,33 +8,4 @@
#environments-detail-view{ data: { details: environments_detail_data_json(current_user, @project, @environment) } }
#environments-detail-view-header
- - if Feature.enabled?(:environment_details_vue, @project)
- #environment_details_page
- - else
- .environments-container
- - if @deployments.blank?
- .empty-state
- .text-content
- %h4.state-title
- = _("You don't have any deployments right now.")
- %p
- = html_escape(_("Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
- .text-center
- = render Pajamas::ButtonComponent.new(variant: :confirm, href: help_page_path("ci/environments/index.md")) do
- = _('Read more')
-
- - else
- .table-holder.gl-overflow-visible
- .ci-table.environments{ role: 'grid' }
- .gl-responsive-table-row.table-row-header{ role: 'row' }
- .table-section.section-15{ role: 'columnheader' }= _('Status')
- .table-section.section-10{ role: 'columnheader' }= _('ID')
- .table-section.section-10{ role: 'columnheader' }= _('Triggerer')
- .table-section.section-25{ role: 'columnheader' }= _('Commit')
- .table-section.section-10{ role: 'columnheader' }= _('Job')
- .table-section.section-10{ role: 'columnheader' }= _('Created')
- .table-section.section-10{ role: 'columnheader' }= _('Deployed')
-
- = render @deployments
-
- = paginate @deployments, theme: 'gitlab'
+ #environment_details_page
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
deleted file mode 100644
index df85963218d..00000000000
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ /dev/null
@@ -1,43 +0,0 @@
-= gitlab_ui_form_for [@project, @schedule], as: :schedule, html: { id: "new-pipeline-schedule-form", class: "js-pipeline-schedule-form pipeline-schedule-form" } do |f|
- = form_errors(@schedule)
- .form-group.row
- .col-md-9
- = f.label :description, _('Description'), class: 'label-bold'
- = f.text_field :description, class: 'form-control gl-form-input', required: true, autofocus: true, placeholder: s_('PipelineSchedules|Provide a short description for this pipeline')
- .form-group.row
- .col-md-9
- = f.label :cron, _('Interval Pattern'), class: 'label-bold'
- #interval-pattern-input{ data: { initial_interval: @schedule.cron, daily_limit: @schedule.daily_limit } }
- .form-group.row
- .col-md-9{ data: { testid: 'schedule-timezone' } }
- = f.label :cron_timezone, _("Cron Timezone")
- .js-timezone-dropdown{ data: { timezone_data: timezone_data.to_json, initial_value: @schedule.cron_timezone, name: 'schedule[cron_timezone]' } }
-
- .form-group.row
- .col-md-9
- = f.label :ref, _('Target branch or tag'), class: 'label-bold'
- %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
- .form-group.row.js-ci-variable-list-section
- .col-md-9
- %label.label-bold
- #{ s_('PipelineSchedules|Variables') }
- %ul.ci-variable-list
- - @schedule.variables.each do |variable|
- = render 'ci/variables/variable_row', form_field: 'schedule', variable: variable
- = render 'ci/variables/variable_row', form_field: 'schedule'
- - if @schedule.variables.size > 0
- = render Pajamas::ButtonComponent.new(category: :secondary, variant: :confirm, button_options: { class: 'gl-mt-3 js-secret-value-reveal-button', data: { secret_reveal_status: "#{@schedule.variables.size == 0}" }}) do
- - if @schedule.variables.size == 0
- = n_('Hide value', 'Hide values', @schedule.variables.size)
- - else
- = n_('Reveal value', 'Reveal values', @schedule.variables.size)
- .form-group.row
- .col-md-9
- = f.label :active, s_('PipelineSchedules|Activated'), class: 'label-bold'
- %div
- = f.gitlab_ui_checkbox_component :active, _('Active'), checkbox_options: { value: @schedule.active, required: false }
- .footer-block
- = f.submit _('Save pipeline schedule'), pajamas_button: true
- = link_button_to _('Cancel'), pipeline_schedules_path(@project)
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
deleted file mode 100644
index a050808f13c..00000000000
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ /dev/null
@@ -1,45 +0,0 @@
-- if pipeline_schedule
- %tr.pipeline-schedule-table-row
- %td{ role: 'cell', data: { label: _('Description') } }
- %div
- = pipeline_schedule.description
- %td.branch-name-cell.gl-text-truncate{ role: 'cell', data: { label: s_("PipelineSchedules|Target") } }
- %div
- - if pipeline_schedule.for_tag?
- = sprite_icon('tag', size: 12, css_class: 'gl-vertical-align-middle!')
- - else
- = sprite_icon('fork', size: 12, css_class: 'gl-vertical-align-middle!')
- - if pipeline_schedule.ref.present?
- = link_to pipeline_schedule.ref_for_display, project_ref_path(@project, pipeline_schedule.ref_for_display), class: "ref-name"
- %td{ role: 'cell', data: { label: _("Last Pipeline") } }
- %div
- - if pipeline_schedule.last_pipeline
- .status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" }
- = link_to project_pipeline_path(@project, pipeline_schedule.last_pipeline.id) do
- = ci_icon_for_status(pipeline_schedule.last_pipeline.status)
- %span.gl-text-blue-500! ##{pipeline_schedule.last_pipeline.id}
- - else
- = s_("PipelineSchedules|None")
- %td.gl-text-gray-500{ role: 'cell', data: { label: s_("PipelineSchedules|Next Run") }, 'data-testid': 'next-run-cell' }
- %div
- - if pipeline_schedule.active? && pipeline_schedule.next_run_at
- = time_ago_with_tooltip(pipeline_schedule.real_next_run)
- - else
- = s_("PipelineSchedules|Inactive")
- %td{ role: 'cell', data: { label: _("Owner") } }
- %div
- - if pipeline_schedule.owner
- = render Pajamas::AvatarComponent.new(pipeline_schedule.owner, size: 24, class: "gl-mr-2")
- = link_to user_path(pipeline_schedule.owner) do
- = pipeline_schedule.owner&.name
- %td{ role: 'cell', data: { label: _('Actions') } }
- .float-right.btn-group
- - if can?(current_user, :play_pipeline_schedule, pipeline_schedule)
- = link_button_to nil, play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), icon: 'play'
- - if can?(current_user, :admin_pipeline_schedule, pipeline_schedule) && pipeline_schedule.owner != current_user
- = render Pajamas::ButtonComponent.new(button_options: { class: 'js-take-ownership-button has-tooltip', title: s_('PipelineSchedule|Take ownership to edit'), data: { url: take_ownership_pipeline_schedule_path(pipeline_schedule) } }) do
- = s_('PipelineSchedules|Take ownership')
- - if can?(current_user, :update_pipeline_schedule, pipeline_schedule)
- = link_button_to nil, edit_pipeline_schedule_path(pipeline_schedule), title: _('Edit'), icon: 'pencil'
- - if can?(current_user, :admin_pipeline_schedule, pipeline_schedule)
- = link_button_to nil, pipeline_schedule_path(pipeline_schedule), title: _('Delete'), method: :delete, aria: { label: _('Delete pipeline schedule') }, data: { confirm: _("Are you sure you want to delete this pipeline schedule?"), confirm_btn_variant: 'danger' }, variant: :danger, icon: 'remove'
diff --git a/app/views/projects/pipeline_schedules/_table.html.haml b/app/views/projects/pipeline_schedules/_table.html.haml
deleted file mode 100644
index 2f96ac6a534..00000000000
--- a/app/views/projects/pipeline_schedules/_table.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-.table-holder
- %table.table.ci-table.responsive-table.b-table.gl-table.b-table-stacked-md{ role: 'table' }
- %thead{ role: 'rowgroup' }
- %tr{ role: 'row' }
- %th.table-th-transparent.border-bottom{ role: 'cell', style: 'width: 34%' }= _("Description")
- %th.table-th-transparent.border-bottom{ role: 'cell' }= s_("PipelineSchedules|Target")
- %th.table-th-transparent.border-bottom{ role: 'cell' }= _("Last Pipeline")
- %th.table-th-transparent.border-bottom{ role: 'cell' }= s_("PipelineSchedules|Next Run")
- %th.table-th-transparent.border-bottom{ role: 'cell' }= _("Owner")
- %th.table-th-transparent.border-bottom{ role: 'cell' }
- %tbody{ role: 'rowgroup' }
- = render partial: "pipeline_schedule", collection: @schedules
diff --git a/app/views/projects/pipeline_schedules/_tabs.html.haml b/app/views/projects/pipeline_schedules/_tabs.html.haml
deleted file mode 100644
index f825ef35902..00000000000
--- a/app/views/projects/pipeline_schedules/_tabs.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-= gl_tabs_nav({ class: 'gl-display-flex gl-flex-grow-1 gl-border-0' }) do
- = gl_tab_link_to schedule_path_proc.call(nil), { item_active: active_when(scope.nil?) } do
- = s_("PipelineSchedules|All")
- = gl_tab_counter_badge(number_with_delimiter(all_schedules.count(:id)), { class: 'js-totalbuilds-count' })
-
- = gl_tab_link_to schedule_path_proc.call('active'), { item_active: active_when(scope == 'active') } do
- = s_("PipelineSchedules|Active")
- = gl_tab_counter_badge(number_with_delimiter(all_schedules.active.count(:id)))
-
- = gl_tab_link_to schedule_path_proc.call('inactive'), { item_active: active_when(scope == 'inactive') } do
- = s_("PipelineSchedules|Inactive")
- = gl_tab_counter_badge(number_with_delimiter(all_schedules.inactive.count(:id)))
diff --git a/app/views/projects/pipeline_schedules/edit.html.haml b/app/views/projects/pipeline_schedules/edit.html.haml
index 4e1ae53a101..647c0272852 100644
--- a/app/views/projects/pipeline_schedules/edit.html.haml
+++ b/app/views/projects/pipeline_schedules/edit.html.haml
@@ -1,12 +1,8 @@
- add_to_breadcrumbs _("Schedules"), pipeline_schedules_path(@project)
- breadcrumb_title "##{@schedule.id}"
- page_title _("Edit"), @schedule.description, _("Pipeline Schedule")
-- add_page_specific_style 'page_bundles/pipeline_schedules'
%h1.page-title.gl-font-size-h-display
= _("Edit Pipeline Schedule")
-- if Feature.enabled?(:pipeline_schedules_vue, @project)
- #pipeline-schedules-form-edit{ data: js_pipeline_schedules_form_data(@project, @schedule) }
-- else
- = render "form"
+#pipeline-schedules-form-edit{ data: js_pipeline_schedules_form_data(@project, @schedule) }
diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml
index 5051fc6a5f5..8eb0f1edee7 100644
--- a/app/views/projects/pipeline_schedules/index.html.haml
+++ b/app/views/projects/pipeline_schedules/index.html.haml
@@ -1,28 +1,6 @@
- breadcrumb_title _("Schedules")
- page_title _("Pipeline Schedules")
-- add_page_specific_style 'page_bundles/pipeline_schedules'
-- add_page_specific_style 'page_bundles/ci_status'
-- add_page_specific_style 'page_bundles/merge_request'
#pipeline-schedules-callout{ data: { docs_url: help_page_path('ci/pipelines/schedules'), illustration_url: image_path('illustrations/pipeline_schedule_callout.svg') } }
-- if Feature.enabled?(:pipeline_schedules_vue, @project)
- #pipeline-schedules-app{ data: { full_path: @project.full_path, pipelines_path: project_pipelines_path(@project), new_schedule_path: new_project_pipeline_schedule_path(@project) } }
-- else
- .top-area
- - schedule_path_proc = ->(scope) { pipeline_schedules_path(@project, scope: scope) }
- = render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope
-
- - if can?(current_user, :create_pipeline_schedule, @project)
- .nav-controls
- = link_button_to new_project_pipeline_schedule_path(@project), variant: :confirm do
- = _('New schedule')
-
- - if @schedules.present?
- %ul.content-list
- = render partial: "table"
- - else
- .nothing-here-block
- = _("No schedules")
-
- #pipeline-take-ownership-modal
+#pipeline-schedules-app{ data: { full_path: @project.full_path, pipelines_path: project_pipelines_path(@project), new_schedule_path: new_project_pipeline_schedule_path(@project) } }
diff --git a/app/views/projects/pipeline_schedules/new.html.haml b/app/views/projects/pipeline_schedules/new.html.haml
index ef99a79b06f..2cd65521ae9 100644
--- a/app/views/projects/pipeline_schedules/new.html.haml
+++ b/app/views/projects/pipeline_schedules/new.html.haml
@@ -1,14 +1,10 @@
- breadcrumb_title _('Schedules')
- @breadcrumb_link = namespace_project_pipeline_schedules_path(@project.namespace, @project)
- page_title _("New Pipeline Schedule")
-- add_page_specific_style 'page_bundles/pipeline_schedules'
- add_to_breadcrumbs("Pipelines", project_pipelines_path(@project))
%h1.page-title.gl-font-size-h-display
= _("Schedule a new pipeline")
-- if Feature.enabled?(:pipeline_schedules_vue, @project)
- #pipeline-schedules-form-new{ data: js_pipeline_schedules_form_data(@project, @schedule) }
-- else
- = render "form"
+#pipeline-schedules-form-new{ data: js_pipeline_schedules_form_data(@project, @schedule) }
diff --git a/config/feature_flags/development/environment_details_vue.yml b/config/feature_flags/development/environment_details_vue.yml
deleted file mode 100644
index c90038a600c..00000000000
--- a/config/feature_flags/development/environment_details_vue.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: environment_details_vue
-introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105527"
-rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/384914"
-milestone: '15.7'
-type: development
-group: group::configure
-default_enabled: true
diff --git a/config/feature_flags/development/pipeline_schedules_vue.yml b/config/feature_flags/development/errors_utf_8_encoding.yml
index 69106660c35..1508f612f2a 100644
--- a/config/feature_flags/development/pipeline_schedules_vue.yml
+++ b/config/feature_flags/development/errors_utf_8_encoding.yml
@@ -1,8 +1,8 @@
---
-name: pipeline_schedules_vue
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/99155
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/375139
-milestone: '15.5'
+name: errors_utf_8_encoding
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129217
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/422061
+milestone: '16.4'
type: development
-group: group::pipeline execution
+group: group::source code
default_enabled: false
diff --git a/config/feature_flags/development/explain_vulnerability_vertex.yml b/config/feature_flags/development/explain_vulnerability_anthropic.yml
index f93be4fc22c..8e5ee714046 100644
--- a/config/feature_flags/development/explain_vulnerability_vertex.yml
+++ b/config/feature_flags/development/explain_vulnerability_anthropic.yml
@@ -1,8 +1,8 @@
---
-name: explain_vulnerability_vertex
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118754
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/409182
-milestone: '16.0'
+name: explain_vulnerability_anthropic
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128118
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/420608
+milestone: '16.4'
type: development
group: group::threat insights
default_enabled: false
diff --git a/db/post_migrate/20230125093723_rebalance_partition_id_ci_pipeline.rb b/db/post_migrate/20230125093723_rebalance_partition_id_ci_pipeline.rb
index aaea55ce331..c7a7d966911 100644
--- a/db/post_migrate/20230125093723_rebalance_partition_id_ci_pipeline.rb
+++ b/db/post_migrate/20230125093723_rebalance_partition_id_ci_pipeline.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class RebalancePartitionIdCiPipeline < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes
- TABLE = :ci_pipelines
- BATCH_SIZE = 2_000
- SUB_BATCH_SIZE = 200
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230125093840_rebalance_partition_id_ci_build.rb b/db/post_migrate/20230125093840_rebalance_partition_id_ci_build.rb
index 6165c266a82..a4514e958f9 100644
--- a/db/post_migrate/20230125093840_rebalance_partition_id_ci_build.rb
+++ b/db/post_migrate/20230125093840_rebalance_partition_id_ci_build.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class RebalancePartitionIdCiBuild < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes.freeze
- TABLE = :ci_builds
- BATCH_SIZE = 5_000
- SUB_BATCH_SIZE = 500
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230208100917_fix_partition_ids_for_ci_pipeline_variable.rb b/db/post_migrate/20230208100917_fix_partition_ids_for_ci_pipeline_variable.rb
index 9901e6af4ae..8bf1239146c 100644
--- a/db/post_migrate/20230208100917_fix_partition_ids_for_ci_pipeline_variable.rb
+++ b/db/post_migrate/20230208100917_fix_partition_ids_for_ci_pipeline_variable.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsForCiPipelineVariable < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes.freeze
- TABLE = :ci_pipeline_variables
- BATCH_SIZE = 2_000
- SUB_BATCH_SIZE = 200
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230208103009_fix_partition_ids_for_ci_job_artifact.rb b/db/post_migrate/20230208103009_fix_partition_ids_for_ci_job_artifact.rb
index d1b25639638..7c6ff6c3b4f 100644
--- a/db/post_migrate/20230208103009_fix_partition_ids_for_ci_job_artifact.rb
+++ b/db/post_migrate/20230208103009_fix_partition_ids_for_ci_job_artifact.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsForCiJobArtifact < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes
- TABLE = :ci_job_artifacts
- BATCH_SIZE = 5_000
- SUB_BATCH_SIZE = 500
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230208132608_fix_partition_ids_for_ci_stage.rb b/db/post_migrate/20230208132608_fix_partition_ids_for_ci_stage.rb
index c3ec614a37f..f05a53dda5f 100644
--- a/db/post_migrate/20230208132608_fix_partition_ids_for_ci_stage.rb
+++ b/db/post_migrate/20230208132608_fix_partition_ids_for_ci_stage.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsForCiStage < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes.freeze
- TABLE = :ci_stages
- BATCH_SIZE = 3_000
- SUB_BATCH_SIZE = 300
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230209090702_fix_partition_ids_for_ci_build_report_result.rb b/db/post_migrate/20230209090702_fix_partition_ids_for_ci_build_report_result.rb
index d21d986ee31..4ff3d1a2789 100644
--- a/db/post_migrate/20230209090702_fix_partition_ids_for_ci_build_report_result.rb
+++ b/db/post_migrate/20230209090702_fix_partition_ids_for_ci_build_report_result.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsForCiBuildReportResult < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes.freeze
- TABLE = :ci_build_report_results
- BATCH_SIZE = 2_000
- SUB_BATCH_SIZE = 200
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :build_id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :build_id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230209092204_fix_partition_ids_for_ci_build_trace_metadata.rb b/db/post_migrate/20230209092204_fix_partition_ids_for_ci_build_trace_metadata.rb
index 25087dcbfa4..f682527a296 100644
--- a/db/post_migrate/20230209092204_fix_partition_ids_for_ci_build_trace_metadata.rb
+++ b/db/post_migrate/20230209092204_fix_partition_ids_for_ci_build_trace_metadata.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsForCiBuildTraceMetadata < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes.freeze
- TABLE = :ci_build_trace_metadata
- BATCH_SIZE = 3_000
- SUB_BATCH_SIZE = 300
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :build_id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :build_id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230209140102_fix_partition_ids_for_ci_build_metadata.rb b/db/post_migrate/20230209140102_fix_partition_ids_for_ci_build_metadata.rb
index 07fcbcc3ad7..785db1be079 100644
--- a/db/post_migrate/20230209140102_fix_partition_ids_for_ci_build_metadata.rb
+++ b/db/post_migrate/20230209140102_fix_partition_ids_for_ci_build_metadata.rb
@@ -1,30 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsForCiBuildMetadata < Gitlab::Database::Migration[2.1]
- MIGRATION = 'RebalancePartitionId'
- DELAY_INTERVAL = 2.minutes
- TABLE = :p_ci_builds_metadata
- BATCH_SIZE = 5_000
- SUB_BATCH_SIZE = 500
-
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
def up
- return unless Gitlab.com?
-
- queue_batched_background_migration(
- MIGRATION,
- TABLE,
- :id,
- job_interval: DELAY_INTERVAL,
- batch_size: BATCH_SIZE,
- sub_batch_size: SUB_BATCH_SIZE
- )
+ # no-op
end
def down
- return unless Gitlab.com?
-
- delete_batched_background_migration(MIGRATION, TABLE, :id, [])
+ # no-op
end
end
diff --git a/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb b/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb
index 0a201c51467..64f5bc4bb5e 100644
--- a/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb
+++ b/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb
@@ -1,20 +1,8 @@
# frozen_string_literal: true
class FixPartitionIdsForCiJobVariables < Gitlab::Database::Migration[2.1]
- disable_ddl_transaction!
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
- BATCH_SIZE = 50
-
def up
- return unless Gitlab.com?
-
- define_batchable_model(:ci_job_variables)
- .where(partition_id: 101)
- .each_batch(of: BATCH_SIZE) do |batch|
- batch.update_all(partition_id: 100)
- sleep 0.1
- end
+ # no-op
end
def down
diff --git a/db/post_migrate/20230214154101_fix_partition_ids_on_ci_sources_pipelines.rb b/db/post_migrate/20230214154101_fix_partition_ids_on_ci_sources_pipelines.rb
index c05b759c2d0..bbacd13389b 100644
--- a/db/post_migrate/20230214154101_fix_partition_ids_on_ci_sources_pipelines.rb
+++ b/db/post_migrate/20230214154101_fix_partition_ids_on_ci_sources_pipelines.rb
@@ -1,36 +1,11 @@
# frozen_string_literal: true
class FixPartitionIdsOnCiSourcesPipelines < Gitlab::Database::Migration[2.1]
- disable_ddl_transaction!
- restrict_gitlab_migration gitlab_schema: :gitlab_ci
-
- BATCH_SIZE = 50
-
def up
- return unless Gitlab.com?
-
- model = define_batchable_model(:ci_sources_pipelines)
-
- batch_update_records(model, :partition_id, from: 101, to: 100, source_partition_id: 100)
- batch_update_records(model, :source_partition_id, from: 101, to: 100)
+ # no-op
end
def down
# no-op
end
-
- private
-
- def batch_update_records(model, column, from:, to:, **updates)
- updates.reverse_merge!(column => to)
-
- model
- .where(model.arel_table[column].eq(from))
- .each_batch(of: BATCH_SIZE) { |batch| update_records(batch, updates) }
- end
-
- def update_records(relation, updates)
- relation.update_all(updates)
- sleep 0.1
- end
end
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 5b918fa50ab..bea8dfca380 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -34,7 +34,7 @@ The following API resources are available in the project context:
| [Conan distributions](packages/conan.md) | `/projects/:id/packages/conan` (also available standalone) |
| [Debian distributions](packages/debian_project_distributions.md) | `/projects/:id/debian_distributions` (also available for groups) |
| [Debian packages](packages/debian.md) | `/projects/:id/packages/debian` (also available for groups) |
-| [Dependencies](dependencies.md) **(ULTIMATE)** | `/projects/:id/dependencies` |
+| [Dependencies](dependencies.md) **(ULTIMATE ALL)** | `/projects/:id/dependencies` |
| [Deploy keys](deploy_keys.md) | `/projects/:id/deploy_keys` (also available standalone) |
| [Deploy tokens](deploy_tokens.md) | `/projects/:id/deploy_tokens` (also available for groups and standalone) |
| [Deployments](deployments.md) | `/projects/:id/deployments` |
@@ -82,7 +82,7 @@ The following API resources are available in the project context:
| [Project milestones](milestones.md) | `/projects/:id/milestones` |
| [Project snippets](project_snippets.md) | `/projects/:id/snippets` |
| [Project templates](project_templates.md) | `/projects/:id/templates` |
-| [Project vulnerabilities](project_vulnerabilities.md) **(ULTIMATE)** | `/projects/:id/vulnerabilities` |
+| [Project vulnerabilities](project_vulnerabilities.md) **(ULTIMATE ALL)** | `/projects/:id/vulnerabilities` |
| [Project wikis](wikis.md) | `/projects/:id/wikis` |
| [Project-level variables](project_level_variables.md) | `/projects/:id/variables` |
| [Projects](projects.md) including setting Webhooks | `/projects`, `/projects/:id/hooks` (also available for users) |
@@ -104,9 +104,9 @@ The following API resources are available in the project context:
| [Terraform modules](packages/terraform-modules.md) | `/projects/:id/packages/terraform/modules` (also available standalone) |
| [User-starred metrics dashboards](metrics_user_starred_dashboards.md ) | `/projects/:id/metrics/user_starred_dashboards` |
| [Visual Review discussions](visual_review_discussions.md) **(PREMIUM)** | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
-| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE)** | `/vulnerabilities/:id` |
-| [Vulnerability exports](vulnerability_exports.md) **(ULTIMATE)** | `/projects/:id/vulnerability_exports` |
-| [Vulnerability findings](vulnerability_findings.md) **(ULTIMATE)** | `/projects/:id/vulnerability_findings` |
+| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE ALL)** | `/vulnerabilities/:id` |
+| [Vulnerability exports](vulnerability_exports.md) **(ULTIMATE ALL)** | `/projects/:id/vulnerability_exports` |
+| [Vulnerability findings](vulnerability_findings.md) **(ULTIMATE ALL)** | `/projects/:id/vulnerability_findings` |
## Group resources
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 930a682c157..77681f6de01 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -314,7 +314,7 @@ Parameters:
| `include_subgroups` | boolean | no | Include projects in subgroups of this group. Default is `false` |
| `min_access_level` | integer | no | Limit to projects where current user has at least this [role (`access_level`)](members.md#roles) |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (administrators only) |
-| `with_security_reports` **(ULTIMATE)** | boolean | no | Return only projects that have security reports artifacts present in any of their builds. This means "projects with security reports enabled". Default is `false` |
+| `with_security_reports` **(ULTIMATE ALL)** | boolean | no | Return only projects that have security reports artifacts present in any of their builds. This means "projects with security reports enabled". Default is `false` |
1. Order by similarity: Orders the results by a similarity score calculated from the provided `search`
URL parameter. When using `order_by=similarity`, the `sort` parameter is ignored. When the `search`
@@ -992,11 +992,11 @@ PUT /groups/:id
| `membership_lock` **(PREMIUM)** | boolean | no | Users cannot be added to projects in this group. |
| `prevent_forking_outside_group` **(PREMIUM)** | boolean | no | When enabled, users can **not** fork projects from this group to external namespaces. |
| `shared_runners_minutes_limit` **(PREMIUM SELF)** | integer | no | Can be set by administrators only. Maximum number of monthly compute minutes for this group. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. |
-| `unique_project_download_limit` **(ULTIMATE)** | integer | no | Maximum number of unique projects a user can download in the specified time period before they are banned. Available only on top-level groups. Default: 0, Maximum: 10,000. |
-| `unique_project_download_limit_interval_in_seconds` **(ULTIMATE)** | integer | no | Time period during which a user can download a maximum amount of projects before they are banned. Available only on top-level groups. Default: 0, Maximum: 864,000 seconds (10 days). |
-| `unique_project_download_limit_allowlist` **(ULTIMATE)** | array of strings | no | List of usernames excluded from the unique project download limit. Available only on top-level groups. Default: `[]`, Maximum: 100 usernames. |
-| `unique_project_download_limit_alertlist` **(ULTIMATE)** | array of integers | no | List of user IDs that are emailed when the unique project download limit is exceeded. Available only on top-level groups. Default: `[]`, Maximum: 100 user IDs. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110201) in GitLab 15.9. |
-| `auto_ban_user_on_excessive_projects_download` **(ULTIMATE)** | boolean | no | When enabled, users are automatically banned from the group when they download more than the maximum number of unique projects specified by `unique_project_download_limit` and `unique_project_download_limit_interval_in_seconds`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94159) in GitLab 15.4. |
+| `unique_project_download_limit` **(ULTIMATE ALL)** | integer | no | Maximum number of unique projects a user can download in the specified time period before they are banned. Available only on top-level groups. Default: 0, Maximum: 10,000. |
+| `unique_project_download_limit_interval_in_seconds` **(ULTIMATE ALL)** | integer | no | Time period during which a user can download a maximum amount of projects before they are banned. Available only on top-level groups. Default: 0, Maximum: 864,000 seconds (10 days). |
+| `unique_project_download_limit_allowlist` **(ULTIMATE ALL)** | array of strings | no | List of usernames excluded from the unique project download limit. Available only on top-level groups. Default: `[]`, Maximum: 100 usernames. |
+| `unique_project_download_limit_alertlist` **(ULTIMATE ALL)** | array of integers | no | List of user IDs that are emailed when the unique project download limit is exceeded. Available only on top-level groups. Default: `[]`, Maximum: 100 user IDs. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110201) in GitLab 15.9. |
+| `auto_ban_user_on_excessive_projects_download` **(ULTIMATE ALL)** | boolean | no | When enabled, users are automatically banned from the group when they download more than the maximum number of unique projects specified by `unique_project_download_limit` and `unique_project_download_limit_interval_in_seconds`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94159) in GitLab 15.4. |
| `ip_restriction_ranges` **(PREMIUM)** | string | no | Comma-separated list of IP addresses or subnet masks to restrict group access. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/351493) in GitLab 15.4. |
| `wiki_access_level` **(PREMIUM)** | string | no | The wiki access level. Can be `disabled`, `private`, or `enabled`. |
diff --git a/doc/api/issues.md b/doc/api/issues.md
index f318515e0a6..13499d1e92f 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -65,7 +65,7 @@ GET /issues?state=opened
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `any`, `today`, `tomorrow`, `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. |
| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
-| `health_status` **(ULTIMATE)** | string | no | Return issues with the specified `health_status`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/370721) in GitLab 15.4)._ In [GitLab 15.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/370721), `None` returns issues with no health status assigned, and `Any` returns issues with a health status assigned.
+| `health_status` **(ULTIMATE ALL)** | string | no | Return issues with the specified `health_status`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/370721) in GitLab 15.4)._ In [GitLab 15.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/370721), `None` returns issues with no health status assigned, and `Any` returns issues with a health status assigned.
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
diff --git a/doc/api/members.md b/doc/api/members.md
index f7e3d6898ec..fa85f69fea9 100644
--- a/doc/api/members.md
+++ b/doc/api/members.md
@@ -573,7 +573,7 @@ PUT /projects/:id/members/:user_id
| `user_id` | integer | yes | The user ID of the member |
| `access_level` | integer | yes | A valid access level |
| `expires_at` | string | no | A date string in the format `YEAR-MONTH-DAY` |
-| `member_role_id` | integer | no | The ID of a member role **(ULTIMATE)** |
+| `member_role_id` | integer | no | The ID of a member role **(ULTIMATE ALL)** |
```shell
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id?access_level=40"
diff --git a/doc/api/notification_settings.md b/doc/api/notification_settings.md
index c4b2d90f2c7..e498c3c91fb 100644
--- a/doc/api/notification_settings.md
+++ b/doc/api/notification_settings.md
@@ -38,7 +38,7 @@ If the `custom` level is used, specific email events can be controlled. Availabl
- `success_pipeline`
- `moved_project`
- `merge_when_pipeline_succeeds`
-- `new_epic` **(ULTIMATE)**
+- `new_epic` **(ULTIMATE ALL)**
## Global notification settings
@@ -94,7 +94,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab
| `success_pipeline` | boolean | no | Enable/disable this notification |
| `moved_project` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30371) in GitLab 13.3) |
| `merge_when_pipeline_succeeds` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/244840) in GitLab 13.9) |
-| `new_epic` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5863) in GitLab 11.3) **(ULTIMATE)** |
+| `new_epic` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5863) in GitLab 11.3) **(ULTIMATE ALL)** |
Example response:
@@ -166,7 +166,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab
| `success_pipeline` | boolean | no | Enable/disable this notification |
| `moved_project` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30371) in GitLab 13.3) |
| `merge_when_pipeline_succeeds` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/244840) in GitLab 13.9) |
-| `new_epic` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5863) in GitLab 11.3) **(ULTIMATE)** |
+| `new_epic` | boolean | no | Enable/disable this notification ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5863) in GitLab 11.3) **(ULTIMATE ALL)** |
Example responses:
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 5bd2ec07647..48f9e0472ce 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1495,7 +1495,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your-token>" \
| `name` | string | **{check-circle}** Yes (if `path` isn't provided) | The name of the new project. Equals path if not provided. |
| `path` | string | **{check-circle}** Yes (if `name` isn't provided) | Repository name for new project. Generated based on name if not provided (generated as lowercase with dashes). Starting with GitLab 14.9, path must not start or end with a special character and must not contain consecutive special characters. |
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
-| `only_allow_merge_if_all_status_checks_passed` **(ULTIMATE)** | boolean | **{dotted-circle}** No | Indicates that merges of merge requests should be blocked unless all status checks have passed. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369859) in GitLab 15.5 with feature flag `only_allow_merge_if_all_status_checks_passed` disabled by default. |
+| `only_allow_merge_if_all_status_checks_passed` **(ULTIMATE ALL)** | boolean | **{dotted-circle}** No | Indicates that merges of merge requests should be blocked unless all status checks have passed. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369859) in GitLab 15.5 with feature flag `only_allow_merge_if_all_status_checks_passed` disabled by default. |
| `analytics_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. To configure approval rules, see [Merge request approvals API](merge_request_approvals.md). [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097) in GitLab 16.0. |
| `auto_cancel_pending_pipelines` | string | **{dotted-circle}** No | Auto-cancel pending pipelines. This action toggles between an enabled state and a disabled state; it is not a boolean. |
@@ -1583,7 +1583,7 @@ POST /projects/user/:user_id
| `user_id` | integer | **{check-circle}** Yes | The user ID of the project owner. |
| `name` | string | **{check-circle}** Yes | The name of the new project. |
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
-| `only_allow_merge_if_all_status_checks_passed` **(ULTIMATE)** | boolean | **{dotted-circle}** No | Indicates that merges of merge requests should be blocked unless all status checks have passed. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369859) in GitLab 15.5 with feature flag `only_allow_merge_if_all_status_checks_passed` disabled by default. |
+| `only_allow_merge_if_all_status_checks_passed` **(ULTIMATE ALL)** | boolean | **{dotted-circle}** No | Indicates that merges of merge requests should be blocked unless all status checks have passed. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369859) in GitLab 15.5 with feature flag `only_allow_merge_if_all_status_checks_passed` disabled by default. |
| `analytics_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097) in GitLab 16.0. To configure approval rules, see [Merge request approvals API](merge_request_approvals.md). |
| `auto_cancel_pending_pipelines` | string | **{dotted-circle}** No | Auto-cancel pending pipelines. This action toggles between an enabled state and a disabled state; it is not a boolean. |
@@ -1684,7 +1684,7 @@ Supported attributes:
| `id` | integer or string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
| `allow_pipeline_trigger_approve_deployment` **(PREMIUM)** | boolean | **{dotted-circle}** No | Set whether or not a pipeline triggerer is allowed to approve deployments. |
-| `only_allow_merge_if_all_status_checks_passed` **(ULTIMATE)** | boolean | **{dotted-circle}** No | Indicates that merges of merge requests should be blocked unless all status checks have passed. Defaults to false.<br/><br/>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369859) in GitLab 15.5 with feature flag `only_allow_merge_if_all_status_checks_passed` disabled by default. The feature flag was enabled by default in GitLab 15.9. |
+| `only_allow_merge_if_all_status_checks_passed` **(ULTIMATE ALL)** | boolean | **{dotted-circle}** No | Indicates that merges of merge requests should be blocked unless all status checks have passed. Defaults to false.<br/><br/>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369859) in GitLab 15.5 with feature flag `only_allow_merge_if_all_status_checks_passed` disabled by default. The feature flag was enabled by default in GitLab 15.9. |
| `analytics_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/353097) in GitLab 16.0. To configure approval rules, see [Merge request approvals API](merge_request_approvals.md). |
| `auto_cancel_pending_pipelines` | string | **{dotted-circle}** No | Auto-cancel pending pipelines. This action toggles between an enabled state and a disabled state; it is not a boolean. |
diff --git a/doc/development/go_guide/index.md b/doc/development/go_guide/index.md
index 7648e84f5e8..e77af931a6f 100644
--- a/doc/development/go_guide/index.md
+++ b/doc/development/go_guide/index.md
@@ -73,7 +73,7 @@ of possible security breaches in our code:
Remember to run
[SAST](../../user/application_security/sast/index.md) and [Dependency Scanning](../../user/application_security/dependency_scanning/index.md)
-**(ULTIMATE)** on your project (or at least the
+**(ULTIMATE ALL)** on your project (or at least the
[`gosec` analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/gosec)),
and to follow our [Security requirements](../code_review.md#security).
diff --git a/doc/development/integrations/index.md b/doc/development/integrations/index.md
index dd73256ce11..8431354c2ee 100644
--- a/doc/development/integrations/index.md
+++ b/doc/development/integrations/index.md
@@ -94,7 +94,7 @@ The following events are supported for integrations:
| [Pipeline event](../../user/project/integrations/webhook_events.md#pipeline-events) | | `pipeline` | A pipeline status changes.
| [Push event](../../user/project/integrations/webhook_events.md#push-events) | ✓ | `push` | A push is made to the repository.
| [Tag push event](../../user/project/integrations/webhook_events.md#tag-events) | ✓ | `tag_push` | New tags are pushed to the repository.
-| Vulnerability event **(ULTIMATE)** | | `vulnerability` | A new, unique vulnerability is recorded.
+| Vulnerability event **(ULTIMATE ALL)** | | `vulnerability` | A new, unique vulnerability is recorded.
| [Wiki page event](../../user/project/integrations/webhook_events.md#wiki-page-events) | ✓ | `wiki_page` | A wiki page is created or updated.
#### Event examples
diff --git a/doc/user/application_security/sast/analyzers.md b/doc/user/application_security/sast/analyzers.md
index 832ad100701..f896616d537 100644
--- a/doc/user/application_security/sast/analyzers.md
+++ b/doc/user/application_security/sast/analyzers.md
@@ -64,7 +64,7 @@ content directly. Instead, it enhances the results with additional properties, i
- CWEs.
- Location tracking fields.
-- A means of identifying false positives or insignificant findings. **(ULTIMATE)**
+- A means of identifying false positives or insignificant findings. **(ULTIMATE ALL)**
## Transition to Semgrep-based scanning
diff --git a/lib/gitlab/background_migration/rebalance_partition_id.rb b/lib/gitlab/background_migration/rebalance_partition_id.rb
deleted file mode 100644
index 7000ae5a856..00000000000
--- a/lib/gitlab/background_migration/rebalance_partition_id.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BackgroundMigration
- # This rebalances partition_id to fix invalid records in production
- class RebalancePartitionId < BatchedMigrationJob
- INVALID_PARTITION_ID = 101
- VALID_PARTITION_ID = 100
-
- scope_to ->(relation) { relation.where(partition_id: INVALID_PARTITION_ID) }
- operation_name :update_all
- feature_category :continuous_integration
-
- def perform
- each_sub_batch do |sub_batch|
- sub_batch.update_all(partition_id: VALID_PARTITION_ID)
- end
- end
- end
- end
-end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 057ee9fb5b9..fcffb6dd420 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -45,6 +45,11 @@ msgstr ""
msgid " and %{sliced}"
msgstr ""
+msgid " except branch:"
+msgid_plural " except branches:"
+msgstr[0] ""
+msgstr[1] ""
+
msgid " or "
msgstr ""
@@ -1438,6 +1443,9 @@ msgstr ""
msgid "+ %{count} more"
msgstr ""
+msgid "+ %{hiddenBranchesLength} more"
+msgstr ""
+
msgid "+ %{moreCount} more"
msgstr ""
@@ -6215,9 +6223,6 @@ msgstr ""
msgid "Are you sure you want to delete this label?"
msgstr ""
-msgid "Are you sure you want to delete this pipeline schedule?"
-msgstr ""
-
msgid "Are you sure you want to delete this pipeline? Doing so will expire all pipeline caches and delete all related objects, such as builds, logs, artifacts, and triggers. This action cannot be undone."
msgstr ""
@@ -10132,9 +10137,6 @@ msgstr ""
msgid "CiVariables|Cancel"
msgstr ""
-msgid "CiVariables|Cannot use Masked Variable with current value"
-msgstr ""
-
msgid "CiVariables|Delete variable"
msgstr ""
@@ -10195,9 +10197,6 @@ msgstr ""
msgid "CiVariables|Remove variable"
msgstr ""
-msgid "CiVariables|Remove variable row"
-msgstr ""
-
msgid "CiVariables|Run job"
msgstr ""
@@ -10240,9 +10239,6 @@ msgstr ""
msgid "CiVariables|You have reached the maximum number of variables available. To add new variables, you must reduce the number of defined variables."
msgstr ""
-msgid "CiVariable|* (All environments)"
-msgstr ""
-
msgid "CiVariable|All environments"
msgstr ""
@@ -13218,6 +13214,15 @@ msgstr ""
msgid "ContributionEvent|Reopened test case %{targetLink} in %{resourceParentLink}."
msgstr ""
+msgid "ContributionEvent|Updated design %{targetLink} in %{resourceParentLink}."
+msgstr ""
+
+msgid "ContributionEvent|Updated resource."
+msgstr ""
+
+msgid "ContributionEvent|Updated wiki page %{targetLink} in %{resourceParentLink}."
+msgstr ""
+
msgid "ContributionEvent|…and %{count} more commits. %{linkStart}Compare%{linkEnd}."
msgstr ""
@@ -14142,9 +14147,6 @@ msgstr ""
msgid "Crm|Organization has been updated."
msgstr ""
-msgid "Cron Timezone"
-msgstr ""
-
msgid "Cron time zone"
msgstr ""
@@ -15478,9 +15480,6 @@ msgstr ""
msgid "Define custom rules for what constitutes spam, independent of Akismet"
msgstr ""
-msgid "Define environments in the deploy stage(s) in %{code_open}.gitlab-ci.yml%{code_close} to track deployments here."
-msgstr ""
-
msgid "Define how approval rules are applied to merge requests."
msgstr ""
@@ -15603,9 +15602,6 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete pipeline schedule"
-msgstr ""
-
msgid "Delete project"
msgstr ""
@@ -16344,9 +16340,6 @@ msgstr ""
msgid "Deployments|You don't have any deployments right now."
msgstr ""
-msgid "Deployment|API"
-msgstr ""
-
msgid "Deployment|Cancelled"
msgstr ""
@@ -16395,9 +16388,6 @@ msgstr ""
msgid "Deployment|Sync status is unknown. %{linkStart}How do I configure Flux for my deployment?%{linkEnd}"
msgstr ""
-msgid "Deployment|This deployment was created using the API"
-msgstr ""
-
msgid "Deployment|Triggerer"
msgstr ""
@@ -25565,9 +25555,6 @@ msgstr ""
msgid "Interval"
msgstr ""
-msgid "Interval Pattern"
-msgstr ""
-
msgid "Introducing Your DevOps Reports"
msgstr ""
@@ -27563,9 +27550,6 @@ msgstr ""
msgid "Last Name"
msgstr ""
-msgid "Last Pipeline"
-msgstr ""
-
msgid "Last Seen"
msgstr ""
@@ -31180,9 +31164,6 @@ msgstr ""
msgid "New runners registration token has been generated!"
msgstr ""
-msgid "New schedule"
-msgstr ""
-
msgid "New snippet"
msgstr ""
@@ -31501,9 +31482,6 @@ msgstr ""
msgid "No runner executable"
msgstr ""
-msgid "No schedules"
-msgstr ""
-
msgid "No service accounts"
msgstr ""
@@ -34295,9 +34273,6 @@ msgstr ""
msgid "PipelineSchedules|A scheduled pipeline starts automatically at regular intervals, like daily or weekly. The pipeline: "
msgstr ""
-msgid "PipelineSchedules|Activated"
-msgstr ""
-
msgid "PipelineSchedules|Active"
msgstr ""
@@ -34412,12 +34387,6 @@ msgstr ""
msgid "PipelineSchedules|There was a problem taking ownership of the pipeline schedule."
msgstr ""
-msgid "PipelineSchedules|Variables"
-msgstr ""
-
-msgid "PipelineSchedule|Take ownership to edit"
-msgstr ""
-
msgid "PipelineSource|API"
msgstr ""
@@ -41379,9 +41348,6 @@ msgstr ""
msgid "Save password"
msgstr ""
-msgid "Save pipeline schedule"
-msgstr ""
-
msgid "Saving"
msgstr ""
@@ -42214,6 +42180,12 @@ msgstr ""
msgid "SecurityOrchestration|%{agent} for %{namespaces}"
msgstr ""
+msgid "SecurityOrchestration|%{branchName}"
+msgstr ""
+
+msgid "SecurityOrchestration|%{branchName} (in %{codeStart}%{fullPath}%{codeEnd})"
+msgstr ""
+
msgid "SecurityOrchestration|%{cadence} on %{branches}"
msgstr ""
@@ -42361,6 +42333,9 @@ msgstr ""
msgid "SecurityOrchestration|Groups"
msgstr ""
+msgid "SecurityOrchestration|Hide extra branches"
+msgstr ""
+
msgid "SecurityOrchestration|If any scanner finds a newly detected critical vulnerability in an open merge request targeting the master branch, then require two approvals from any member of App security."
msgstr ""
@@ -42645,13 +42620,13 @@ msgstr ""
msgid "SecurityOrchestration|Vulnerability age requires previously existing vulnerability states (detected, confirmed, resolved, or dismissed)"
msgstr ""
-msgid "SecurityOrchestration|When %{scanners} %{vulnerabilitiesAllowed} %{vulnerability} in an open merge request %{targeting}%{branches}%{criteriaApply}"
+msgid "SecurityOrchestration|When %{scanners} %{vulnerabilitiesAllowed} %{vulnerability} in an open merge request %{targeting}%{branches}%{branchExceptionsString}%{criteriaApply}"
msgstr ""
-msgid "SecurityOrchestration|When license scanner finds any license except %{licenses}%{detection} in an open merge request %{targeting}%{branches}."
+msgid "SecurityOrchestration|When license scanner finds any license except %{licenses}%{detection} in an open merge request %{targeting}%{branches}%{branchExceptionsString}"
msgstr ""
-msgid "SecurityOrchestration|When license scanner finds any license matching %{licenses}%{detection} in an open merge request %{targeting}%{branches}."
+msgid "SecurityOrchestration|When license scanner finds any license matching %{licenses}%{detection} in an open merge request %{targeting}%{branches}%{branchExceptionsString}"
msgstr ""
msgid "SecurityOrchestration|When this policy is enabled, protected branches cannot be unprotected and users will not be allowed to force push to protected branches."
@@ -46639,9 +46614,6 @@ msgstr ""
msgid "Target branch"
msgstr ""
-msgid "Target branch or tag"
-msgstr ""
-
msgid "Target branch: %{target_branch}"
msgstr ""
@@ -54317,9 +54289,6 @@ msgstr ""
msgid "You don't have any authorized applications."
msgstr ""
-msgid "You don't have any deployments right now."
-msgstr ""
-
msgid "You don't have any open merge requests"
msgstr ""
diff --git a/qa/lib/gitlab/page/group/settings/billing.rb b/qa/lib/gitlab/page/group/settings/billing.rb
index 0d25a012db3..0565da0d353 100644
--- a/qa/lib/gitlab/page/group/settings/billing.rb
+++ b/qa/lib/gitlab/page/group/settings/billing.rb
@@ -11,7 +11,7 @@ module Gitlab
link :upgrade_to_ultimate
# Subscription details
- strong :subscription_header
+ h5 :subscription_header
button :refresh_seats
# Usage
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index 11ea72b87a2..3abe3ce1396 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -10,24 +10,19 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
before do
sign_in(user)
project.add_role(user, role)
- stub_feature_flags(environment_details_vue: false)
end
def auto_stop_button_selector
%q{button[title="Prevent environment from auto-stopping"]}
end
- describe 'environment details page vue' do
+ describe 'environment details page', :js do
let_it_be(:environment) { create(:environment, project: project) }
let!(:permissions) {}
let!(:deployment) {}
let!(:action) {}
let!(:cluster) {}
- before do
- stub_feature_flags(environment_details_vue: true)
- end
-
context 'with auto-stop' do
let_it_be(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) }
@@ -35,122 +30,16 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
visit_environment(environment)
end
- it 'shows auto stop info', :js do
- expect(page).to have_content('Auto stops')
- end
-
- it 'shows auto stop button', :js do
- expect(page).to have_selector(auto_stop_button_selector)
- expect(page.find(auto_stop_button_selector).find(:xpath, '..')['action']).to have_content(cancel_auto_stop_project_environment_path(environment.project, environment))
- end
-
- it 'allows user to cancel auto stop', :js do
- page.find(auto_stop_button_selector).click
- wait_for_all_requests
- expect(page).to have_content('Auto stop successfully canceled.')
- expect(page).not_to have_selector(auto_stop_button_selector)
- end
- end
-
- context 'without deployments' do
- before do
- visit_environment(environment)
- end
-
- it 'does not show deployments', :js do
- expect(page).to have_content('You don\'t have any deployments right now.')
- end
- end
-
- context 'with deployments' do
- before do
- visit_environment(environment)
- end
-
- context 'when there is a successful deployment' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
-
- let(:deployment) do
- create(:deployment, :success, environment: environment, deployable: build)
- end
-
- it 'does show deployments', :js do
- wait_for_requests
- expect(page).to have_link("#{build.name} (##{build.id})")
- end
- end
-
- context 'when there is a failed deployment' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
-
- let(:deployment) do
- create(:deployment, :failed, environment: environment, deployable: build)
- end
-
- it 'does show deployments', :js do
- wait_for_requests
- expect(page).to have_link("#{build.name} (##{build.id})")
- end
- end
-
- context 'with related deployable present' do
- let_it_be(:previous_pipeline) { create(:ci_pipeline, project: project) }
-
- let_it_be(:previous_build) do
- create(:ci_build, :success, pipeline: previous_pipeline, environment: environment.name)
- end
-
- let_it_be(:previous_deployment) do
- create(:deployment, :success, environment: environment, deployable: previous_build)
- end
-
- let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
- let_it_be(:build) { create(:ci_build, pipeline: pipeline, environment: environment.name) }
-
- let_it_be(:deployment) do
- create(:deployment, :success, environment: environment, deployable: build)
- end
-
- before do
- visit_environment(environment)
- end
-
- it 'shows deployment information and buttons', :js do
- wait_for_requests
- expect(page).to have_button('Re-deploy to environment')
- expect(page).to have_button('Rollback environment')
- expect(page).to have_link("#{build.name} (##{build.id})")
- end
- end
- end
- end
-
- describe 'environment details page' do
- let_it_be(:environment) { create(:environment, project: project) }
- let!(:permissions) {}
- let!(:deployment) {}
- let!(:action) {}
- let!(:cluster) {}
-
- context 'with auto-stop' do
- let!(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) }
-
- before do
- visit_environment(environment)
- end
-
- it 'shows auto stop info', :js do
+ it 'shows auto stop info' do
expect(page).to have_content('Auto stops')
end
- it 'shows auto stop button', :js do
+ it 'shows auto stop button' do
expect(page).to have_selector(auto_stop_button_selector)
expect(page.find(auto_stop_button_selector).find(:xpath, '..')['action']).to have_content(cancel_auto_stop_project_environment_path(environment.project, environment))
end
- it 'allows user to cancel auto stop', :js do
+ it 'allows user to cancel auto stop' do
page.find(auto_stop_button_selector).click
wait_for_all_requests
expect(page).to have_content('Auto stop successfully canceled.')
@@ -208,10 +97,6 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
it 'does show deployments' do
expect(page).to have_link("#{build.name} (##{build.id})")
end
-
- it 'shows a tooltip on the job name' do
- expect(page).to have_css("[title=\"#{build.name} (##{build.id})\"].has-tooltip")
- end
end
context 'when there is a failed deployment' do
@@ -227,26 +112,6 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
end
end
- context 'with many deployments' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
-
- let!(:second) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: Time.current) }
- let!(:first) { create(:deployment, environment: environment, deployable: build, status: :running) }
- let!(:last) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: 2.days.ago) }
- let!(:third) { create(:deployment, environment: environment, deployable: build, status: :canceled, finished_at: 1.day.ago) }
-
- before do
- visit_environment(environment)
- end
-
- it 'shows all of them in ordered way' do
- ids = find_all('[data-testid="deployment-id"]').map { |e| e.text }
- expected_ordered_ids = [first, second, third, last].map { |d| "##{d.iid}" }
- expect(ids).to eq(expected_ordered_ids)
- end
- end
-
context 'with upcoming deployments' do
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline) }
@@ -265,7 +130,7 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
# See https://gitlab.com/gitlab-org/gitlab/-/issues/350618 for more information.
it 'shows upcoming deployments in unordered way' do
displayed_ids = find_all('[data-testid="deployment-id"]').map { |e| e.text }
- internal_ids = [runnind_deployment_1, runnind_deployment_2, success_without_finished_at].map { |d| "##{d.iid}" }
+ internal_ids = [runnind_deployment_1, runnind_deployment_2, success_without_finished_at].map { |d| d.iid.to_s }
expect(displayed_ids).to match_array(internal_ids)
end
end
@@ -309,20 +174,19 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
end
it 'does show a play button' do
- expect(page).to have_link(action.name)
+ expect(page).to have_button(action.name, visible: :all)
end
- it 'does allow to play manual action', :js do
+ it 'does allow to play manual action' do
expect(action).to be_manual
- find('button.dropdown').click
+ click_button('Deploy to...')
- expect { click_link(action.name) }
+ expect { click_button(action.name) }
.not_to change { Ci::Pipeline.count }
wait_for_all_requests
- expect(page).to have_content(action.name)
expect(action.reload).to be_pending
end
end
@@ -347,38 +211,6 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
end
end
- context 'with terminal' do
- context 'when user configured kubernetes from CI/CD > Clusters' do
- let!(:cluster) do
- create(:cluster, :project, :provided_by_gcp, projects: [project])
- end
-
- context 'for project maintainer' do
- let(:role) { :maintainer }
-
- context 'web terminal', :js do
- before do
- # Stub #terminals as it causes js-enabled feature specs to
- # render the page incorrectly
- #
- # In EE we have to stub EE::Environment since it overwrites
- # the "terminals" method.
- allow_next_instance_of(Gitlab.ee? ? EE::Environment : Environment) do |instance|
- allow(instance).to receive(:terminals) { nil }
- end
-
- visit terminal_project_environment_path(project, environment)
- end
-
- it 'displays a web terminal' do
- expect(page).to have_selector('#terminal')
- expect(page).to have_link(nil, href: environment.external_url)
- end
- end
- end
- end
- end
-
context 'when environment is available' do
context 'with stop action' do
let(:build) { create(:ci_build, :success, pipeline: pipeline, environment: environment.name) }
@@ -446,6 +278,8 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do
visit folder_project_environments_path(project, id: 'staging-1.0')
end
+ wait_for_requests
+
expect(reqs.first.status_code).to eq(200)
expect(page).to have_content('Environments / staging-1.0')
end
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 358c55376d4..322d25ed052 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -12,389 +12,301 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :groups_and_projects
let!(:user) { create(:user) }
let!(:maintainer) { create(:user) }
- context 'with pipeline_schedules_vue feature flag turned off' do
+ context 'logged in as the pipeline schedule owner' do
before do
- stub_feature_flags(pipeline_schedules_vue: false)
+ project.add_developer(user)
+ pipeline_schedule.update!(owner: user)
+ gitlab_sign_in(user)
end
- context 'logged in as the pipeline schedule owner' do
+ describe 'GET /projects/pipeline_schedules' do
before do
- project.add_developer(user)
- pipeline_schedule.update!(owner: user)
- gitlab_sign_in(user)
+ visit_pipelines_schedules
end
- describe 'GET /projects/pipeline_schedules' do
- before do
- visit_pipelines_schedules
- end
-
- it 'edits the pipeline' do
- page.within('.pipeline-schedule-table-row') do
- click_link 'Edit'
- end
+ it 'edits the pipeline' do
+ page.find('[data-testid="edit-pipeline-schedule-btn"]').click
- expect(page).to have_content('Edit Pipeline Schedule')
- end
+ expect(page).to have_content(s_('PipelineSchedules|Edit pipeline schedule'))
end
+ end
- describe 'PATCH /projects/pipelines_schedules/:id/edit' do
- before do
- edit_pipeline_schedule
- end
-
- it 'displays existing properties' do
- description = find_field('schedule_description').value
- expect(description).to eq('pipeline schedule')
- expect(page).to have_button('master')
- expect(page).to have_button('Select timezone')
- end
+ describe 'PATCH /projects/pipelines_schedules/:id/edit' do
+ before do
+ edit_pipeline_schedule
+ end
- it 'edits the scheduled pipeline' do
- fill_in 'schedule_description', with: 'my brand new description'
+ it 'displays existing properties' do
+ description = find_field('schedule-description').value
+ expect(description).to eq('pipeline schedule')
+ expect(page).to have_button('master')
+ expect(page).to have_button(_('Select timezone'))
+ end
- save_pipeline_schedule
+ it 'edits the scheduled pipeline' do
+ fill_in 'schedule-description', with: 'my brand new description'
- expect(page).to have_content('my brand new description')
- end
+ save_pipeline_schedule
- context 'when ref is nil' do
- before do
- pipeline_schedule.update_attribute(:ref, nil)
- edit_pipeline_schedule
- end
+ expect(page).to have_content('my brand new description')
+ end
- it 'shows the pipeline schedule with default ref' do
- page.within('[data-testid="schedule-target-ref"]') do
- expect(first('.gl-button-text').text).to eq('master')
- end
- end
+ context 'when ref is nil' do
+ before do
+ pipeline_schedule.update_attribute(:ref, nil)
+ edit_pipeline_schedule
end
- context 'when ref is empty' do
- before do
- pipeline_schedule.update_attribute(:ref, '')
- edit_pipeline_schedule
- end
-
- it 'shows the pipeline schedule with default ref' do
- page.within('[data-testid="schedule-target-ref"]') do
- expect(first('.gl-button-text').text).to eq('master')
- end
+ it 'shows the pipeline schedule with default ref' do
+ page.within('#schedule-target-branch-tag') do
+ expect(first('.gl-button-text').text).to eq('master')
end
end
end
- end
-
- context 'logged in as a project maintainer' do
- before do
- project.add_maintainer(user)
- gitlab_sign_in(user)
- end
- describe 'GET /projects/pipeline_schedules' do
+ context 'when ref is empty' do
before do
- visit_pipelines_schedules
+ pipeline_schedule.update_attribute(:ref, '')
+ edit_pipeline_schedule
end
- describe 'The view' do
- it 'displays the required information description' do
- page.within('.pipeline-schedule-table-row') do
- expect(page).to have_content('pipeline schedule')
- expect(find("[data-testid='next-run-cell'] time")['title'])
- .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y'))
- expect(page).to have_link('master')
- expect(page).to have_link("##{pipeline.id}")
- end
- end
-
- it 'creates a new scheduled pipeline' do
- click_link 'New schedule'
-
- expect(page).to have_content('Schedule a new pipeline')
- end
-
- it 'changes ownership of the pipeline' do
- click_button 'Take ownership'
-
- page.within('#pipeline-take-ownership-modal') do
- click_link 'Take ownership'
- end
-
- page.within('.pipeline-schedule-table-row') do
- expect(page).not_to have_content('No owner')
- expect(page).to have_link('Sidney Jones')
- end
- end
-
- it 'deletes the pipeline' do
- click_link 'Delete'
-
- accept_gl_confirm(button_text: 'Delete pipeline schedule')
-
- expect(page).not_to have_css(".pipeline-schedule-table-row")
+ it 'shows the pipeline schedule with default ref' do
+ page.within('#schedule-target-branch-tag') do
+ expect(first('.gl-button-text').text).to eq('master')
end
end
+ end
+ end
+ end
- context 'when ref is nil' do
- before do
- pipeline_schedule.update_attribute(:ref, nil)
- visit_pipelines_schedules
- end
-
- it 'shows a list of the pipeline schedules with empty ref column' do
- expect(first('.branch-name-cell').text).to eq('')
- end
- end
+ context 'logged in as a project maintainer' do
+ before do
+ project.add_maintainer(user)
+ pipeline_schedule.update!(owner: maintainer)
+ gitlab_sign_in(user)
+ end
- context 'when ref is empty' do
- before do
- pipeline_schedule.update_attribute(:ref, '')
- visit_pipelines_schedules
- end
+ describe 'GET /projects/pipeline_schedules' do
+ before do
+ visit_pipelines_schedules
- it 'shows a list of the pipeline schedules with empty ref column' do
- expect(first('.branch-name-cell').text).to eq('')
- end
- end
+ wait_for_requests
end
- describe 'POST /projects/pipeline_schedules/new' do
- before do
- visit_new_pipeline_schedule
- end
-
- it 'sets defaults for timezone and target branch' do
- expect(page).to have_button('master')
- expect(page).to have_button('Select timezone')
+ describe 'The view' do
+ it 'displays the required information description' do
+ page.within('[data-testid="pipeline-schedule-table-row"]') do
+ expect(page).to have_content('pipeline schedule')
+ expect(find('[data-testid="next-run-cell"] time')['title'])
+ .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y'))
+ expect(page).to have_link('master')
+ expect(find("[data-testid='last-pipeline-status'] a")['href']).to include(pipeline.id.to_s)
+ end
end
it 'creates a new scheduled pipeline' do
- fill_in_schedule_form
- save_pipeline_schedule
+ click_link 'New schedule'
- expect(page).to have_content('my fancy description')
+ expect(page).to have_content('Schedule a new pipeline')
end
- it 'prevents an invalid form from being submitted' do
- save_pipeline_schedule
+ it 'changes ownership of the pipeline' do
+ find("[data-testid='take-ownership-pipeline-schedule-btn']").click
- expect(page).to have_content('This field is required')
- end
- end
+ page.within('#pipeline-take-ownership-modal') do
+ click_button s_('PipelineSchedules|Take ownership')
- context 'when user creates a new pipeline schedule with variables' do
- before do
- visit_pipelines_schedules
- click_link 'New schedule'
- fill_in_schedule_form
- all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA')
- all('[name="schedule[variables_attributes][][secret_value]"]')[0].set('AAA123')
- all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB')
- all('[name="schedule[variables_attributes][][secret_value]"]')[1].set('BBB123')
- save_pipeline_schedule
- end
+ wait_for_requests
+ end
- it 'user sees the new variable in edit window', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/397040' do
- find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
- page.within('.ci-variable-list') do
- expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('AAA')
- expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('AAA123')
- expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-key").value).to eq('BBB')
- expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-value", visible: false).value).to eq('BBB123')
+ page.within('[data-testid="pipeline-schedule-table-row"]') do
+ expect(page).not_to have_content('No owner')
+ expect(page).to have_link('Sidney Jones')
end
end
- end
- context 'when user edits a variable of a pipeline schedule' do
- before do
- create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
- create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule)
+ it 'deletes the pipeline' do
+ page.within('[data-testid="pipeline-schedule-table-row"]') do
+ click_button s_('PipelineSchedules|Delete pipeline schedule')
end
- visit_pipelines_schedules
- find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
- find('.js-ci-variable-list-section .js-secret-value-reveal-button').click
- first('.js-ci-variable-input-key').set('foo')
- first('.js-ci-variable-input-value').set('bar')
- click_button 'Save pipeline schedule'
- end
+ accept_gl_confirm(button_text: s_('PipelineSchedules|Delete pipeline schedule'))
- it 'user sees the updated variable in edit window' do
- find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
- page.within('.ci-variable-list') do
- expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('foo')
- expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('bar')
- end
+ expect(page).not_to have_css('[data-testid="pipeline-schedule-table-row"]')
end
end
- context 'when user removes a variable of a pipeline schedule' do
+ context 'when ref is nil' do
before do
- create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
- create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule)
- end
-
+ pipeline_schedule.update_attribute(:ref, nil)
visit_pipelines_schedules
- find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
- find('.ci-variable-list .ci-variable-row-remove-button').click
- click_button 'Save pipeline schedule'
+ wait_for_requests
end
- it 'user does not see the removed variable in edit window' do
- find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
- page.within('.ci-variable-list') do
- expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('')
- expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('')
+ it 'shows a list of the pipeline schedules with empty ref column' do
+ target = find('[data-testid="pipeline-schedule-target"]')
+
+ page.within('[data-testid="pipeline-schedule-table-row"]') do
+ expect(target.text).to eq(s_('PipelineSchedules|None'))
end
end
end
- context 'when active is true and next_run_at is NULL' do
+ context 'when ref is empty' do
before do
- create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
- pipeline_schedule.update_attribute(:next_run_at, nil) # Consequently next_run_at will be nil
- end
+ pipeline_schedule.update_attribute(:ref, '')
+ visit_pipelines_schedules
+ wait_for_requests
end
- it 'user edit and recover the problematic pipeline schedule' do
- visit_pipelines_schedules
- find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
- fill_in 'schedule_cron', with: '* 1 2 3 4'
- click_button 'Save pipeline schedule'
+ it 'shows a list of the pipeline schedules with empty ref column' do
+ target = find('[data-testid="pipeline-schedule-target"]')
- page.within('.pipeline-schedule-table-row:nth-child(1)') do
- expect(page).to have_css("[data-testid='next-run-cell'] time")
- end
+ expect(target.text).to eq(s_('PipelineSchedules|None'))
end
end
end
- context 'logged in as non-member' do
+ describe 'POST /projects/pipeline_schedules/new' do
before do
- gitlab_sign_in(user)
+ visit_new_pipeline_schedule
end
- describe 'GET /projects/pipeline_schedules' do
- before do
- visit_pipelines_schedules
- end
+ it 'sets defaults for timezone and target branch' do
+ expect(page).to have_button('master')
+ expect(page).to have_button('Select timezone')
+ end
- describe 'The view' do
- it 'does not show create schedule button' do
- expect(page).not_to have_link('New schedule')
- end
- end
+ it 'creates a new scheduled pipeline' do
+ fill_in_schedule_form
+ create_pipeline_schedule
+
+ expect(page).to have_content('my fancy description')
end
- end
- context 'not logged in' do
- describe 'GET /projects/pipeline_schedules' do
- before do
- visit_pipelines_schedules
- end
+ it 'prevents an invalid form from being submitted' do
+ create_pipeline_schedule
- describe 'The view' do
- it 'does not show create schedule button' do
- expect(page).not_to have_link('New schedule')
- end
- end
+ expect(page).to have_content("Cron timezone can't be blank")
end
end
- end
- context 'with pipeline_schedules_vue feature flag turned on' do
- context 'logged in as a project maintainer' do
+ context 'when user creates a new pipeline schedule with variables' do
before do
- project.add_maintainer(maintainer)
- pipeline_schedule.update!(owner: user)
- gitlab_sign_in(maintainer)
+ visit_pipelines_schedules
+ click_link 'New schedule'
+ fill_in_schedule_form
+ all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA')
+ all('[name="schedule[variables_attributes][][secret_value]"]')[0].set('AAA123')
+ all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB')
+ all('[name="schedule[variables_attributes][][secret_value]"]')[1].set('BBB123')
+ create_pipeline_schedule
end
- describe 'GET /projects/pipeline_schedules' do
- before do
- visit_pipelines_schedules
-
- wait_for_requests
+ it 'user sees the new variable in edit window', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/397040' do
+ find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
+ page.within('.ci-variable-list') do
+ expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('AAA')
+ expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('AAA123')
+ expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-key").value).to eq('BBB')
+ expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-value", visible: false).value).to eq('BBB123')
end
+ end
+ end
- describe 'The view' do
- it 'displays the required information description' do
- page.within('[data-testid="pipeline-schedule-table-row"]') do
- expect(page).to have_content('pipeline schedule')
- expect(find("[data-testid='next-run-cell'] time")['title'])
- .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y'))
- expect(page).to have_link('master')
- expect(find("[data-testid='last-pipeline-status'] a")['href']).to include(pipeline.id.to_s)
- end
- end
-
- it 'changes ownership of the pipeline' do
- click_button 'Take ownership'
+ context 'when user edits a variable of a pipeline schedule' do
+ before do
+ create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
+ create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule)
+ end
- page.within('#pipeline-take-ownership-modal') do
- click_button 'Take ownership'
+ visit_pipelines_schedules
+ first('[data-testid="edit-pipeline-schedule-btn"]').click
+ click_button _('Reveal values')
+ first('[data-testid="pipeline-form-ci-variable-key"]').set('foo')
+ first('[data-testid="pipeline-form-ci-variable-value"]').set('bar')
+ save_pipeline_schedule
+ end
- wait_for_requests
- end
+ it 'user sees the updated variable' do
+ first('[data-testid="edit-pipeline-schedule-btn"]').click
- page.within('[data-testid="pipeline-schedule-table-row"]') do
- expect(page).not_to have_content('No owner')
- expect(page).to have_link('Sidney Jones')
- end
- end
+ expect(first('[data-testid="pipeline-form-ci-variable-key"]').value).to eq('foo')
+ expect(first('[data-testid="pipeline-form-ci-variable-value"]').value).to eq('')
- it 'runs the pipeline' do
- click_button 'Run pipeline schedule'
+ click_button _('Reveal values')
- wait_for_requests
+ expect(first('[data-testid="pipeline-form-ci-variable-value"]').value).to eq('bar')
+ end
+ end
- expect(page).to have_content("Successfully scheduled a pipeline to run. Go to the Pipelines page for details.")
- end
+ context 'when user removes a variable of a pipeline schedule' do
+ before do
+ create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
+ create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule)
+ end
- it 'deletes the pipeline' do
- click_button 'Delete pipeline schedule'
+ visit_pipelines_schedules
+ first('[data-testid="edit-pipeline-schedule-btn"]').click
+ find('[data-testid="remove-ci-variable-row"]').click
+ save_pipeline_schedule
+ end
- accept_gl_confirm(button_text: 'Delete pipeline schedule')
+ it 'user does not see the removed variable in edit window' do
+ first('[data-testid="edit-pipeline-schedule-btn"]').click
- expect(page).not_to have_css('[data-testid="pipeline-schedule-table-row"]')
- end
- end
+ expect(first('[data-testid="pipeline-form-ci-variable-key"]').value).to eq('')
+ expect(first('[data-testid="pipeline-form-ci-variable-value"]').value).to eq('')
end
end
- context 'logged in as non-member' do
+ context 'when active is true and next_run_at is NULL' do
before do
- gitlab_sign_in(user)
+ create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
+ pipeline_schedule.update_attribute(:next_run_at, nil) # Consequently next_run_at will be nil
+ end
end
- describe 'GET /projects/pipeline_schedules' do
- before do
- visit_pipelines_schedules
+ it 'user edit and recover the problematic pipeline schedule' do
+ visit_pipelines_schedules
+ first('[data-testid="edit-pipeline-schedule-btn"]').click
+ fill_in 'schedule_cron', with: '* 1 2 3 4'
+ save_pipeline_schedule
- wait_for_requests
- end
-
- describe 'The view' do
- it 'does not show create schedule button' do
- expect(page).not_to have_link('New schedule')
- end
+ page.within(first('[data-testid="pipeline-schedule-table-row"]')) do
+ expect(page).to have_css("[data-testid='next-run-cell'] time")
end
end
end
+ end
- context 'not logged in' do
- describe 'GET /projects/pipeline_schedules' do
- before do
- visit_pipelines_schedules
+ context 'logged in as non-member' do
+ before do
+ gitlab_sign_in(user)
+ end
- wait_for_requests
+ describe 'GET /projects/pipeline_schedules' do
+ before do
+ visit_pipelines_schedules
+ end
+
+ describe 'The view' do
+ it 'does not show create schedule button' do
+ expect(page).not_to have_link('New schedule')
end
+ end
+ end
+ end
- describe 'The view' do
- it 'does not show create schedule button' do
- expect(page).not_to have_link('New schedule')
- end
+ context 'not logged in' do
+ describe 'GET /projects/pipeline_schedules' do
+ before do
+ visit_pipelines_schedules
+ end
+
+ describe 'The view' do
+ it 'does not show create schedule button' do
+ expect(page).not_to have_link('New schedule')
end
end
end
@@ -413,7 +325,7 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :groups_and_projects
end
def select_timezone
- find('[data-testid="schedule-timezone"] .gl-new-dropdown-toggle').click
+ find('#schedule-timezone .gl-new-dropdown-toggle').click
find("li", text: "Arizona").click
end
@@ -421,12 +333,16 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :groups_and_projects
click_button 'master'
end
+ def create_pipeline_schedule
+ click_button s_('PipelineSchedules|Create pipeline schedule')
+ end
+
def save_pipeline_schedule
- click_button 'Save pipeline schedule'
+ click_button s_('PipelineSchedules|Edit pipeline schedule')
end
def fill_in_schedule_form
- fill_in 'schedule_description', with: 'my fancy description'
+ fill_in 'schedule-description', with: 'my fancy description'
fill_in 'schedule_cron', with: '* 1 2 3 4'
select_timezone
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index bb49fb734d7..e078e3f7eea 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -843,12 +843,10 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
end
it 'displays the PipelineSchedule in an inactive state' do
- stub_feature_flags(pipeline_schedules_vue: false)
-
visit project_pipeline_schedules_path(project)
page.click_link('Inactive')
- expect(page).to have_selector('table.ci-table > tbody > tr > td', text: 'blocked user schedule')
+ expect(page).to have_selector('[data-testid="pipeline-schedule-description"]', text: 'blocked user schedule')
end
it 'does not create a new Pipeline', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/408215' do
diff --git a/spec/frontend/ci/ci_variable_list/ci_variable_list/ci_variable_list_spec.js b/spec/frontend/ci/ci_variable_list/ci_variable_list/ci_variable_list_spec.js
deleted file mode 100644
index 8990a70d4ef..00000000000
--- a/spec/frontend/ci/ci_variable_list/ci_variable_list/ci_variable_list_spec.js
+++ /dev/null
@@ -1,161 +0,0 @@
-import $ from 'jquery';
-import htmlPipelineSchedulesEdit from 'test_fixtures/pipeline_schedules/edit.html';
-import htmlPipelineSchedulesEditWithVariables from 'test_fixtures/pipeline_schedules/edit_with_variables.html';
-import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
-import VariableList from '~/ci/ci_variable_list/ci_variable_list';
-
-const HIDE_CLASS = 'hide';
-
-describe('VariableList', () => {
- let $wrapper;
- let variableList;
-
- describe('with only key/value inputs', () => {
- describe('with no variables', () => {
- beforeEach(() => {
- setHTMLFixture(htmlPipelineSchedulesEdit);
- $wrapper = $('.js-ci-variable-list-section');
-
- variableList = new VariableList({
- container: $wrapper,
- formField: 'schedule',
- });
- variableList.init();
- });
-
- afterEach(() => {
- resetHTMLFixture();
- });
-
- it('should remove the row when clicking the remove button', () => {
- $wrapper.find('.js-row-remove-button').trigger('click');
-
- expect($wrapper.find('.js-row').length).toBe(0);
- });
-
- it('should add another row when editing the last rows key input', () => {
- const $row = $wrapper.find('.js-row');
- $row.find('.js-ci-variable-input-key').val('foo').trigger('input');
-
- expect($wrapper.find('.js-row').length).toBe(2);
-
- // Check for the correct default in the new row
- const $keyInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-key');
-
- expect($keyInput.val()).toBe('');
- });
-
- it('should add another row when editing the last rows value textarea', () => {
- const $row = $wrapper.find('.js-row');
- $row.find('.js-ci-variable-input-value').val('foo').trigger('input');
-
- expect($wrapper.find('.js-row').length).toBe(2);
-
- // Check for the correct default in the new row
- const $valueInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-key');
-
- expect($valueInput.val()).toBe('');
- });
-
- it('should remove empty row after blurring', () => {
- const $row = $wrapper.find('.js-row');
- $row.find('.js-ci-variable-input-key').val('foo').trigger('input');
-
- expect($wrapper.find('.js-row').length).toBe(2);
-
- $row.find('.js-ci-variable-input-key').val('').trigger('input').trigger('blur');
-
- expect($wrapper.find('.js-row').length).toBe(1);
- });
- });
-
- describe('with persisted variables', () => {
- beforeEach(() => {
- setHTMLFixture(htmlPipelineSchedulesEditWithVariables);
- $wrapper = $('.js-ci-variable-list-section');
-
- variableList = new VariableList({
- container: $wrapper,
- formField: 'schedule',
- });
- variableList.init();
- });
-
- afterEach(() => {
- resetHTMLFixture();
- });
-
- it('should have "Reveal values" button initially when there are already variables', () => {
- expect($wrapper.find('.js-secret-value-reveal-button').text()).toBe('Reveal values');
- });
-
- it('should reveal hidden values', () => {
- const $row = $wrapper.find('.js-row:first-child');
- const $inputValue = $row.find('.js-ci-variable-input-value');
- const $placeholder = $row.find('.js-secret-value-placeholder');
-
- expect($placeholder.hasClass(HIDE_CLASS)).toBe(false);
- expect($inputValue.hasClass(HIDE_CLASS)).toBe(true);
-
- // Reveal values
- $wrapper.find('.js-secret-value-reveal-button').click();
-
- expect($placeholder.hasClass(HIDE_CLASS)).toBe(true);
- expect($inputValue.hasClass(HIDE_CLASS)).toBe(false);
- });
- });
- });
-
- describe('toggleEnableRow method', () => {
- beforeEach(() => {
- setHTMLFixture(htmlPipelineSchedulesEditWithVariables);
- $wrapper = $('.js-ci-variable-list-section');
-
- variableList = new VariableList({
- container: $wrapper,
- formField: 'variables',
- });
- variableList.init();
- });
-
- afterEach(() => {
- resetHTMLFixture();
- });
-
- it('should disable all key inputs', () => {
- expect($wrapper.find('.js-ci-variable-input-key:not([disabled])').length).toBe(3);
-
- variableList.toggleEnableRow(false);
-
- expect($wrapper.find('.js-ci-variable-input-key[disabled]').length).toBe(3);
- });
-
- it('should disable all remove buttons', () => {
- expect($wrapper.find('.js-row-remove-button:not([disabled])').length).toBe(3);
-
- variableList.toggleEnableRow(false);
-
- expect($wrapper.find('.js-row-remove-button[disabled]').length).toBe(3);
- });
-
- it('should enable all remove buttons', () => {
- variableList.toggleEnableRow(false);
-
- expect($wrapper.find('.js-row-remove-button[disabled]').length).toBe(3);
-
- variableList.toggleEnableRow(true);
-
- expect($wrapper.find('.js-row-remove-button:not([disabled])').length).toBe(3);
- });
-
- it('should enable all key inputs', () => {
- variableList.toggleEnableRow(false);
-
- expect($wrapper.find('.js-ci-variable-input-key[disabled]').length).toBe(3);
-
- variableList.toggleEnableRow(true);
-
- expect($wrapper.find('.js-ci-variable-input-key:not([disabled])').length).toBe(3);
- });
- });
-});
diff --git a/spec/frontend/ci/ci_variable_list/ci_variable_list/native_form_variable_list_spec.js b/spec/frontend/ci/ci_variable_list/ci_variable_list/native_form_variable_list_spec.js
deleted file mode 100644
index 3ef5427f288..00000000000
--- a/spec/frontend/ci/ci_variable_list/ci_variable_list/native_form_variable_list_spec.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import $ from 'jquery';
-import htmlPipelineSchedulesEdit from 'test_fixtures/pipeline_schedules/edit.html';
-import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
-import setupNativeFormVariableList from '~/ci/ci_variable_list/native_form_variable_list';
-
-describe('NativeFormVariableList', () => {
- let $wrapper;
-
- beforeEach(() => {
- setHTMLFixture(htmlPipelineSchedulesEdit);
- $wrapper = $('.js-ci-variable-list-section');
-
- setupNativeFormVariableList({
- container: $wrapper,
- formField: 'schedule',
- });
- });
-
- afterEach(() => {
- resetHTMLFixture();
- });
-
- describe('onFormSubmit', () => {
- it('should clear out the `name` attribute on the inputs for the last empty row on form submission (avoid BE validation)', () => {
- const $row = $wrapper.find('.js-row');
-
- expect($row.find('.js-ci-variable-input-key').attr('name')).toBe(
- 'schedule[variables_attributes][][key]',
- );
-
- expect($row.find('.js-ci-variable-input-value').attr('name')).toBe(
- 'schedule[variables_attributes][][secret_value]',
- );
-
- $wrapper.closest('form').trigger('trigger-submit');
-
- expect($row.find('.js-ci-variable-input-key').attr('name')).toBe('');
- expect($row.find('.js-ci-variable-input-value').attr('name')).toBe('');
- });
- });
-});
diff --git a/spec/frontend/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target_spec.js b/spec/frontend/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target_spec.js
index 5cc3829efbd..70b4c7a5224 100644
--- a/spec/frontend/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target_spec.js
+++ b/spec/frontend/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { s__ } from '~/locale';
import PipelineScheduleTarget from '~/ci/pipeline_schedules/components/table/cells/pipeline_schedule_target.vue';
import { mockPipelineScheduleNodes } from '../../../mock_data';
@@ -20,18 +21,35 @@ describe('Pipeline schedule target', () => {
const findIcon = () => wrapper.findComponent(GlIcon);
const findLink = () => wrapper.findComponent(GlLink);
+ const findTarget = () => wrapper.findComponent('[data-testid="pipeline-schedule-target"]');
- beforeEach(() => {
- createComponent();
- });
+ describe('with ref', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('displays icon', () => {
+ expect(findIcon().exists()).toBe(true);
+ expect(findIcon().props('name')).toBe('fork');
+ });
- it('displays icon', () => {
- expect(findIcon().exists()).toBe(true);
- expect(findIcon().props('name')).toBe('fork');
+ it('displays ref link', () => {
+ expect(findLink().attributes('href')).toBe(defaultProps.schedule.refPath);
+ expect(findLink().text()).toBe(defaultProps.schedule.refForDisplay);
+ });
});
- it('displays ref link', () => {
- expect(findLink().attributes('href')).toBe(defaultProps.schedule.refPath);
- expect(findLink().text()).toBe(defaultProps.schedule.refForDisplay);
+ describe('without refPath', () => {
+ beforeEach(() => {
+ createComponent({
+ schedule: { ...mockPipelineScheduleNodes[0], refPath: null, refForDisplay: null },
+ });
+ });
+
+ it('displays none for the target', () => {
+ expect(findIcon().exists()).toBe(false);
+ expect(findLink().exists()).toBe(false);
+ expect(findTarget().text()).toBe(s__('PipelineSchedules|None'));
+ });
});
});
diff --git a/spec/frontend/ci/pipeline_schedules/components/take_ownership_modal_legacy_spec.js b/spec/frontend/ci/pipeline_schedules/components/take_ownership_modal_legacy_spec.js
deleted file mode 100644
index e4ff9a0545b..00000000000
--- a/spec/frontend/ci/pipeline_schedules/components/take_ownership_modal_legacy_spec.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { GlModal } from '@gitlab/ui';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import TakeOwnershipModalLegacy from '~/ci/pipeline_schedules/components/take_ownership_modal_legacy.vue';
-
-describe('Take ownership modal', () => {
- let wrapper;
- const url = `/root/job-log-tester/-/pipeline_schedules/3/take_ownership`;
-
- const createComponent = (props = {}) => {
- wrapper = shallowMountExtended(TakeOwnershipModalLegacy, {
- propsData: {
- ownershipUrl: url,
- ...props,
- },
- });
- };
-
- const findModal = () => wrapper.findComponent(GlModal);
-
- beforeEach(() => {
- createComponent();
- });
-
- it('has a primary action set to a url and a post data-method', () => {
- const actionPrimary = findModal().props('actionPrimary');
-
- expect(actionPrimary.attributes).toEqual(
- expect.objectContaining({
- category: 'primary',
- variant: 'confirm',
- href: url,
- 'data-method': 'post',
- }),
- );
- });
-
- it('shows a take ownership message', () => {
- expect(findModal().text()).toBe(
- 'Only the owner of a pipeline schedule can make changes to it. Do you want to take ownership of this schedule?',
- );
- });
-});
diff --git a/spec/frontend/contribution_events/components/contribution_event/contribution_event_updated_spec.js b/spec/frontend/contribution_events/components/contribution_event/contribution_event_updated_spec.js
new file mode 100644
index 00000000000..e8e25b24dc9
--- /dev/null
+++ b/spec/frontend/contribution_events/components/contribution_event/contribution_event_updated_spec.js
@@ -0,0 +1,31 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import ContributionEventUpdated from '~/contribution_events/components/contribution_event/contribution_event_updated.vue';
+import ContributionEventBase from '~/contribution_events/components/contribution_event/contribution_event_base.vue';
+import { eventDesignUpdated, eventWikiPageUpdated } from '../../utils';
+
+describe('ContributionEventUpdated', () => {
+ let wrapper;
+
+ const createComponent = ({ propsData }) => {
+ wrapper = shallowMountExtended(ContributionEventUpdated, {
+ propsData,
+ });
+ };
+
+ describe.each`
+ event | expectedMessage
+ ${eventDesignUpdated()} | ${'Updated design %{targetLink} in %{resourceParentLink}.'}
+ ${eventWikiPageUpdated()} | ${'Updated wiki page %{targetLink} in %{resourceParentLink}.'}
+ ${{ target: { type: 'unsupported type' } }} | ${'Updated resource.'}
+ `('when event target type is $event.target.type', ({ event, expectedMessage }) => {
+ it('renders `ContributionEventBase` with correct props', () => {
+ createComponent({ propsData: { event } });
+
+ expect(wrapper.findComponent(ContributionEventBase).props()).toMatchObject({
+ event,
+ message: expectedMessage,
+ iconName: 'pencil',
+ });
+ });
+ });
+});
diff --git a/spec/frontend/contribution_events/components/contribution_events_spec.js b/spec/frontend/contribution_events/components/contribution_events_spec.js
index 7493d248e2b..84817d9c73f 100644
--- a/spec/frontend/contribution_events/components/contribution_events_spec.js
+++ b/spec/frontend/contribution_events/components/contribution_events_spec.js
@@ -11,6 +11,7 @@ import ContributionEventCreated from '~/contribution_events/components/contribut
import ContributionEventClosed from '~/contribution_events/components/contribution_event/contribution_event_closed.vue';
import ContributionEventReopened from '~/contribution_events/components/contribution_event/contribution_event_reopened.vue';
import ContributionEventCommented from '~/contribution_events/components/contribution_event/contribution_event_commented.vue';
+import ContributionEventUpdated from '~/contribution_events/components/contribution_event/contribution_event_updated.vue';
import {
eventApproved,
eventExpired,
@@ -23,6 +24,7 @@ import {
eventClosed,
eventReopened,
eventCommented,
+ eventUpdated,
} from '../utils';
describe('ContributionEvents', () => {
@@ -43,6 +45,7 @@ describe('ContributionEvents', () => {
eventClosed(),
eventReopened(),
eventCommented(),
+ eventUpdated(),
],
},
});
@@ -61,6 +64,7 @@ describe('ContributionEvents', () => {
${ContributionEventClosed} | ${eventClosed()}
${ContributionEventReopened} | ${eventReopened()}
${ContributionEventCommented} | ${eventCommented()}
+ ${ContributionEventUpdated} | ${eventUpdated()}
`(
'renders `$expectedComponent.name` component and passes expected event',
({ expectedComponent, expectedEvent }) => {
diff --git a/spec/frontend/contribution_events/utils.js b/spec/frontend/contribution_events/utils.js
index 8b34506c6ac..b267c2c8605 100644
--- a/spec/frontend/contribution_events/utils.js
+++ b/spec/frontend/contribution_events/utils.js
@@ -10,6 +10,7 @@ import {
EVENT_TYPE_CLOSED,
EVENT_TYPE_REOPENED,
EVENT_TYPE_COMMENTED,
+ EVENT_TYPE_UPDATED,
PUSH_EVENT_REF_TYPE_BRANCH,
PUSH_EVENT_REF_TYPE_TAG,
EVENT_TYPE_CREATED,
@@ -32,22 +33,12 @@ import {
COMMIT_NOTEABLE_TYPE,
} from '~/notes/constants';
+// Private finders
const findEventByAction = (action) => () => events.find((event) => event.action === action);
const findEventByActionAndTargetType = (action, targetType) => () =>
events.find((event) => event.action === action && event.target?.type === targetType);
const findEventByActionAndIssueType = (action, issueType) => () =>
events.find((event) => event.action === action && event.target.issue_type === issueType);
-
-export const eventApproved = findEventByAction(EVENT_TYPE_APPROVED);
-
-export const eventExpired = findEventByAction(EVENT_TYPE_EXPIRED);
-
-export const eventJoined = findEventByAction(EVENT_TYPE_JOINED);
-
-export const eventLeft = findEventByAction(EVENT_TYPE_LEFT);
-
-export const eventMerged = findEventByAction(EVENT_TYPE_MERGED);
-
const findPushEvent = ({
isNew = false,
isRemoved = false,
@@ -62,6 +53,43 @@ const findPushEvent = ({
ref.type === refType &&
commit.count === commitCount,
);
+const findEventByActionAndNoteableType = (action, noteableType) => () =>
+ events.find((event) => event.action === action && event.noteable?.type === noteableType);
+const findCommentedSnippet = (resourceParentType) => () =>
+ events.find(
+ (event) =>
+ event.action === EVENT_TYPE_COMMENTED &&
+ event.noteable?.type === SNIPPET_NOTEABLE_TYPE &&
+ event.resource_parent?.type === resourceParentType,
+ );
+const findUpdatedEvent = (targetType) =>
+ findEventByActionAndTargetType(EVENT_TYPE_UPDATED, targetType);
+
+// Finders that are used by EE
+export const findCreatedEvent = (targetType) =>
+ findEventByActionAndTargetType(EVENT_TYPE_CREATED, targetType);
+export const findWorkItemCreatedEvent = (issueType) =>
+ findEventByActionAndIssueType(EVENT_TYPE_CREATED, issueType);
+export const findClosedEvent = (targetType) =>
+ findEventByActionAndTargetType(EVENT_TYPE_CREATED, targetType);
+export const findWorkItemClosedEvent = (issueType) =>
+ findEventByActionAndIssueType(EVENT_TYPE_CLOSED, issueType);
+export const findReopenedEvent = (targetType) =>
+ findEventByActionAndTargetType(EVENT_TYPE_REOPENED, targetType);
+export const findWorkItemReopenedEvent = (issueType) =>
+ findEventByActionAndIssueType(EVENT_TYPE_REOPENED, issueType);
+export const findCommentedEvent = (noteableType) =>
+ findEventByActionAndNoteableType(EVENT_TYPE_COMMENTED, noteableType);
+
+export const eventApproved = findEventByAction(EVENT_TYPE_APPROVED);
+
+export const eventExpired = findEventByAction(EVENT_TYPE_EXPIRED);
+
+export const eventJoined = findEventByAction(EVENT_TYPE_JOINED);
+
+export const eventLeft = findEventByAction(EVENT_TYPE_LEFT);
+
+export const eventMerged = findEventByAction(EVENT_TYPE_MERGED);
export const eventPushedNewBranch = findPushEvent({ isNew: true });
export const eventPushedNewTag = findPushEvent({ isNew: true, refType: PUSH_EVENT_REF_TYPE_TAG });
@@ -77,12 +105,6 @@ export const eventBulkPushedBranch = findPushEvent({ commitCount: 5 });
export const eventPrivate = () => ({ ...events[0], action: EVENT_TYPE_PRIVATE });
export const eventCreated = findEventByAction(EVENT_TYPE_CREATED);
-
-export const findCreatedEvent = (targetType) =>
- findEventByActionAndTargetType(EVENT_TYPE_CREATED, targetType);
-export const findWorkItemCreatedEvent = (issueType) =>
- findEventByActionAndIssueType(EVENT_TYPE_CREATED, issueType);
-
export const eventProjectCreated = findCreatedEvent(undefined);
export const eventMilestoneCreated = findCreatedEvent(TARGET_TYPE_MILESTONE);
export const eventIssueCreated = findCreatedEvent(TARGET_TYPE_ISSUE);
@@ -93,12 +115,6 @@ export const eventTaskCreated = findWorkItemCreatedEvent(WORK_ITEM_ISSUE_TYPE_TA
export const eventIncidentCreated = findWorkItemCreatedEvent(WORK_ITEM_ISSUE_TYPE_INCIDENT);
export const eventClosed = findEventByAction(EVENT_TYPE_CLOSED);
-
-export const findClosedEvent = (targetType) =>
- findEventByActionAndTargetType(EVENT_TYPE_CREATED, targetType);
-export const findWorkItemClosedEvent = (issueType) =>
- findEventByActionAndIssueType(EVENT_TYPE_CLOSED, issueType);
-
export const eventMilestoneClosed = findClosedEvent(TARGET_TYPE_MILESTONE);
export const eventIssueClosed = findClosedEvent(TARGET_TYPE_ISSUE);
export const eventMergeRequestClosed = findClosedEvent(TARGET_TYPE_MERGE_REQUEST);
@@ -108,12 +124,6 @@ export const eventTaskClosed = findWorkItemClosedEvent(WORK_ITEM_ISSUE_TYPE_TASK
export const eventIncidentClosed = findWorkItemClosedEvent(WORK_ITEM_ISSUE_TYPE_INCIDENT);
export const eventReopened = findEventByAction(EVENT_TYPE_REOPENED);
-
-export const findReopenedEvent = (targetType) =>
- findEventByActionAndTargetType(EVENT_TYPE_REOPENED, targetType);
-export const findWorkItemReopenedEvent = (issueType) =>
- findEventByActionAndIssueType(EVENT_TYPE_REOPENED, issueType);
-
export const eventMilestoneReopened = findReopenedEvent(TARGET_TYPE_MILESTONE);
export const eventMergeRequestReopened = findReopenedEvent(TARGET_TYPE_MERGE_REQUEST);
export const eventWikiPageReopened = findReopenedEvent(TARGET_TYPE_WIKI);
@@ -123,19 +133,6 @@ export const eventTaskReopened = findWorkItemReopenedEvent(WORK_ITEM_ISSUE_TYPE_
export const eventIncidentReopened = findWorkItemReopenedEvent(WORK_ITEM_ISSUE_TYPE_INCIDENT);
export const eventCommented = findEventByAction(EVENT_TYPE_COMMENTED);
-
-const findEventByActionAndNoteableType = (action, noteableType) => () =>
- events.find((event) => event.action === action && event.noteable?.type === noteableType);
-export const findCommentedEvent = (noteableType) =>
- findEventByActionAndNoteableType(EVENT_TYPE_COMMENTED, noteableType);
-export const findCommentedSnippet = (resourceParentType) => () =>
- events.find(
- (event) =>
- event.action === EVENT_TYPE_COMMENTED &&
- event.noteable?.type === SNIPPET_NOTEABLE_TYPE &&
- event.resource_parent?.type === resourceParentType,
- );
-
export const eventCommentedIssue = findCommentedEvent(ISSUE_NOTEABLE_TYPE);
export const eventCommentedMergeRequest = findCommentedEvent(MERGE_REQUEST_NOTEABLE_TYPE);
export const eventCommentedSnippet = findCommentedEvent(SNIPPET_NOTEABLE_TYPE);
@@ -153,3 +150,7 @@ export const eventCommentedCommit = () => ({
first_line_in_markdown: '\u003cp\u003eMy title 9\u003c/p\u003e',
},
});
+
+export const eventUpdated = findEventByAction(EVENT_TYPE_UPDATED);
+export const eventDesignUpdated = findUpdatedEvent(TARGET_TYPE_DESIGN);
+export const eventWikiPageUpdated = findUpdatedEvent(TARGET_TYPE_WIKI);
diff --git a/spec/frontend/fixtures/pipeline_schedules.rb b/spec/frontend/fixtures/pipeline_schedules.rb
index 7bba7910b87..4c95e7ecd20 100644
--- a/spec/frontend/fixtures/pipeline_schedules.rb
+++ b/spec/frontend/fixtures/pipeline_schedules.rb
@@ -16,35 +16,6 @@ RSpec.describe 'Pipeline schedules (JavaScript fixtures)' do
let!(:pipeline_schedule_variable1) { create(:ci_pipeline_schedule_variable, key: 'foo', value: 'foovalue', pipeline_schedule: pipeline_schedule_populated) }
let!(:pipeline_schedule_variable2) { create(:ci_pipeline_schedule_variable, key: 'bar', value: 'barvalue', pipeline_schedule: pipeline_schedule_populated) }
- describe Projects::PipelineSchedulesController, type: :controller do
- render_views
-
- before do
- sign_in(user)
- stub_feature_flags(pipeline_schedules_vue: false)
- end
-
- it 'pipeline_schedules/edit.html' do
- get :edit, params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: pipeline_schedule.id
- }
-
- expect(response).to be_successful
- end
-
- it 'pipeline_schedules/edit_with_variables.html' do
- get :edit, params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: pipeline_schedule_populated.id
- }
-
- expect(response).to be_successful
- end
- end
-
describe GraphQL::Query, type: :request do
before do
pipeline_schedule.pipelines << build(:ci_pipeline, project: project)
diff --git a/spec/frontend/jobs/components/table/jobs_table_spec.js b/spec/frontend/jobs/components/table/jobs_table_spec.js
index 654b6d1c130..6808e4d061d 100644
--- a/spec/frontend/jobs/components/table/jobs_table_spec.js
+++ b/spec/frontend/jobs/components/table/jobs_table_spec.js
@@ -62,6 +62,15 @@ describe('Jobs Table', () => {
});
expect(findAllCoverageJobs()).toHaveLength(jobsThatHaveCoverage.length);
});
+
+ describe('when stage of a job is missing', () => {
+ it('shows no stage', () => {
+ const stagelessJob = { ...mockJobsNodes[0], stage: null };
+ createComponent({ jobs: [stagelessJob] });
+
+ expect(findJobStage().exists()).toBe(false);
+ });
+ });
});
describe('regular user', () => {
diff --git a/spec/lib/gitlab/background_migration/rebalance_partition_id_spec.rb b/spec/lib/gitlab/background_migration/rebalance_partition_id_spec.rb
deleted file mode 100644
index 195e57e4e59..00000000000
--- a/spec/lib/gitlab/background_migration/rebalance_partition_id_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::RebalancePartitionId,
- :migration,
- schema: 20230125093723,
- feature_category: :continuous_integration do
- let(:ci_builds_table) { table(:ci_builds, database: :ci) }
- let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
-
- let!(:valid_ci_pipeline) { ci_pipelines_table.create!(id: 1, partition_id: 100) }
- let!(:invalid_ci_pipeline) { ci_pipelines_table.create!(id: 2, partition_id: 101) }
-
- describe '#perform' do
- using RSpec::Parameterized::TableSyntax
-
- where(:table_name, :invalid_record, :valid_record) do
- :ci_pipelines | invalid_ci_pipeline | valid_ci_pipeline
- end
-
- subject(:perform) do
- described_class.new(
- start_id: 1,
- end_id: 2,
- batch_table: table_name,
- batch_column: :id,
- sub_batch_size: 1,
- pause_ms: 0,
- connection: Ci::ApplicationRecord.connection
- ).perform
- end
-
- shared_examples 'fix invalid records' do
- it 'rebalances partition_id to 100 when partition_id is 101' do
- expect { perform }
- .to change { invalid_record.reload.partition_id }.from(101).to(100)
- .and not_change { valid_record.reload.partition_id }
- end
- end
-
- with_them do
- it_behaves_like 'fix invalid records'
- end
- end
-end
diff --git a/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb b/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb
deleted file mode 100644
index 3ccd92e15a4..00000000000
--- a/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RebalancePartitionIdCiPipeline, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_builds' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_pipelines,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb b/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb
deleted file mode 100644
index b983564a2d9..00000000000
--- a/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RebalancePartitionIdCiBuild, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_builds' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_builds,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb b/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb
deleted file mode 100644
index fb0e1fe17ec..00000000000
--- a/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiPipelineVariable, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_pipeline_variables' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_pipeline_variables,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb b/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb
deleted file mode 100644
index de2386c6a0d..00000000000
--- a/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiJobArtifact, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_job_artifacts' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_job_artifacts,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb b/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb
deleted file mode 100644
index 8b057afc1e9..00000000000
--- a/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiStage, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_stages' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_stages,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb b/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb
deleted file mode 100644
index f0ac8239f58..00000000000
--- a/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiBuildReportResult,
- migration: :gitlab_ci,
- feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_build_report_results' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_build_report_results,
- column_name: :build_id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb b/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb
deleted file mode 100644
index a93ba36d9ae..00000000000
--- a/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiBuildTraceMetadata,
- migration: :gitlab_ci,
- feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_build_trace_metadata' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_build_trace_metadata,
- column_name: :build_id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb b/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb
deleted file mode 100644
index c354d68749f..00000000000
--- a/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiBuildMetadata,
- migration: :gitlab_ci,
- feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of p_ci_builds_metadata' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :p_ci_builds_metadata,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb b/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb
deleted file mode 100644
index 64275855262..00000000000
--- a/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiJobVariables, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:builds) { table(:ci_builds, database: :ci) }
- let(:job_variables) { table(:ci_job_variables, database: :ci) }
- let(:connection) { job_variables.connection }
-
- around do |example|
- connection.execute "ALTER TABLE #{job_variables.quoted_table_name} DISABLE TRIGGER ALL;"
-
- example.run
- ensure
- connection.execute "ALTER TABLE #{job_variables.quoted_table_name} ENABLE TRIGGER ALL;"
- end
-
- before do
- job = builds.create!(partition_id: 100)
-
- job_variables.insert_all!([
- { job_id: job.id, partition_id: 100, key: 'variable-100' },
- { job_id: job.id, partition_id: 101, key: 'variable-101' }
- ])
- end
-
- describe '#up', :aggregate_failures do
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- it 'fixes partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(job_variables.where(partition_id: 100).count).to eq(2)
- expect(job_variables.where(partition_id: 101).count).to eq(0)
- end
- end
-
- context 'when on self managed' do
- it 'does not change partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(job_variables.where(partition_id: 100).count).to eq(1)
- expect(job_variables.where(partition_id: 101).count).to eq(1)
- end
- end
- end
-end
diff --git a/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb b/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb
deleted file mode 100644
index 44031175497..00000000000
--- a/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsOnCiSourcesPipelines, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:sources_pipelines) { table(:ci_sources_pipelines, database: :ci) }
-
- before do
- sources_pipelines.insert_all!([
- { partition_id: 100, source_partition_id: 100 },
- { partition_id: 100, source_partition_id: 101 },
- { partition_id: 101, source_partition_id: 100 },
- { partition_id: 101, source_partition_id: 101 }
- ])
- end
-
- describe '#up' do
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- it 'fixes partition_id and source_partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(sources_pipelines.where(partition_id: 100).count).to eq(4)
- expect(sources_pipelines.where(partition_id: 101).count).to eq(0)
- expect(sources_pipelines.where(source_partition_id: 100).count).to eq(4)
- expect(sources_pipelines.where(source_partition_id: 101).count).to eq(0)
- end
- end
-
- context 'when on self managed' do
- it 'does not change partition_id or source_partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(sources_pipelines.where(partition_id: 100).count).to eq(2)
- expect(sources_pipelines.where(partition_id: 100).count).to eq(2)
- expect(sources_pipelines.where(source_partition_id: 101).count).to eq(2)
- expect(sources_pipelines.where(source_partition_id: 101).count).to eq(2)
- end
- end
- end
-end
diff --git a/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb b/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb
deleted file mode 100644
index 13ec7207ec9..00000000000
--- a/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'projects/pipeline_schedules/_pipeline_schedule' do
- let(:owner) { create(:user) }
- let(:maintainer) { create(:user) }
- let(:project) { create(:project) }
- let(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project) }
-
- before do
- assign(:project, project)
-
- allow(view).to receive(:current_user).and_return(user)
- allow(view).to receive(:pipeline_schedule).and_return(pipeline_schedule)
-
- allow(view).to receive(:can?).and_return(true)
- end
-
- context 'taking ownership of schedule' do
- context 'when non-owner is signed in' do
- let(:user) { maintainer }
-
- before do
- allow(view).to receive(:can?).with(maintainer, :admin_pipeline_schedule, pipeline_schedule).and_return(true)
- end
-
- it 'non-owner can take ownership of pipeline' do
- render
-
- expect(rendered).to have_button('Take ownership')
- end
- end
-
- context 'when owner is signed in' do
- let(:user) { owner }
-
- before do
- allow(view).to receive(:can?).with(owner, :admin_pipeline_schedule, pipeline_schedule).and_return(false)
- end
-
- it 'owner cannot take ownership of pipeline' do
- render
-
- expect(rendered).not_to have_button('Take ownership')
- end
- end
- end
-end