diff options
50 files changed, 222 insertions, 180 deletions
@@ -17,7 +17,7 @@ gem 'view_component', '~> 2.50.0' gem 'default_value_for', '~> 3.4.0' # Supported DBs -gem 'pg', '~> 1.1' +gem 'pg', '~> 1.3.0' gem 'rugged', '~> 1.2' gem 'grape-path-helpers', '~> 1.7.0' @@ -311,7 +311,7 @@ gem 'sentry-sidekiq', '~> 5.1.1' # PostgreSQL query parsing # -gem 'pg_query', '~> 2.1' +gem 'pg_query', '~> 2.1.0' gem 'premailer-rails', '~> 1.10.3' diff --git a/Gemfile.lock b/Gemfile.lock index d21c8de0f2a..0db64ebc911 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -947,9 +947,9 @@ GEM tty-color (~> 0.5) peek (1.1.0) railties (>= 4.0.0) - pg (1.2.3) - pg_query (2.1.1) - google-protobuf (>= 3.17.1) + pg (1.3.5) + pg_query (2.1.3) + google-protobuf (>= 3.19.2) plist (3.6.0) png_quantizator (0.2.1) po_to_json (1.0.1) @@ -1630,8 +1630,8 @@ DEPENDENCIES parallel (~> 1.19) parslet (~> 1.8) peek (~> 1.1) - pg (~> 1.1) - pg_query (~> 2.1) + pg (~> 1.3.0) + pg_query (~> 2.1.0) png_quantizator (~> 0.2.1) premailer-rails (~> 1.10.3) prometheus-client-mmap (~> 0.15.0) diff --git a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue index 5fe285c0896..944a2ef7f64 100644 --- a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue +++ b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue @@ -10,6 +10,7 @@ import { EVENT_SUCCESS, FIELDS, FORM_SELECTOR, INITIAL_PAGE, PAGE_SIZE } from '. export default { EVENT_SUCCESS, + FORM_SELECTOR, PAGE_SIZE, name: 'AccessTokenTableApp', components: { @@ -55,9 +56,6 @@ export default { filteredFields() { return this.showRole ? FIELDS : FIELDS.filter((field) => field.key !== 'role'); }, - formSelector() { - return `#${FORM_SELECTOR}`; - }, header() { return sprintf(this.$options.i18n.header, { accessTokenTypePlural: this.accessTokenTypePlural, @@ -97,7 +95,7 @@ export default { </script> <template> - <dom-element-listener :selector="formSelector" @[$options.EVENT_SUCCESS]="onSuccess"> + <dom-element-listener :selector="$options.FORM_SELECTOR" @[$options.EVENT_SUCCESS]="onSuccess"> <div> <hr /> <h5>{{ header }}</h5> diff --git a/app/assets/javascripts/access_tokens/components/constants.js b/app/assets/javascripts/access_tokens/components/constants.js index 197f20ae24c..84e50bc099f 100644 --- a/app/assets/javascripts/access_tokens/components/constants.js +++ b/app/assets/javascripts/access_tokens/components/constants.js @@ -2,7 +2,7 @@ import { __, s__ } from '~/locale'; export const EVENT_ERROR = 'ajax:error'; export const EVENT_SUCCESS = 'ajax:success'; -export const FORM_SELECTOR = 'js-new-access-token-form'; +export const FORM_SELECTOR = '#js-new-access-token-form'; export const INITIAL_PAGE = 1; export const PAGE_SIZE = 100; diff --git a/app/assets/javascripts/access_tokens/components/new_access_token_app.vue b/app/assets/javascripts/access_tokens/components/new_access_token_app.vue index a34f3c7dedf..904052688f3 100644 --- a/app/assets/javascripts/access_tokens/components/new_access_token_app.vue +++ b/app/assets/javascripts/access_tokens/components/new_access_token_app.vue @@ -9,6 +9,7 @@ import { EVENT_ERROR, EVENT_SUCCESS, FORM_SELECTOR } from './constants'; export default { EVENT_ERROR, EVENT_SUCCESS, + FORM_SELECTOR, name: 'NewAccessTokenApp', components: { DomElementListener, GlAlert, InputCopyToggleVisibility }, i18n: { @@ -46,16 +47,13 @@ export default { name: this.$options.tokenInputId, }; }, - formSelector() { - return `#${FORM_SELECTOR}`; - }, label() { return sprintf(this.$options.i18n.label, { accessTokenType: this.accessTokenType }); }, }, mounted() { /** @type {HTMLFormElement} */ - this.form = document.getElementById(FORM_SELECTOR); + this.form = document.querySelector(FORM_SELECTOR); /** @type {HTMLInputElement} */ this.submitButton = this.form.querySelector('input[type=submit]'); @@ -92,7 +90,7 @@ export default { <template> <dom-element-listener - :selector="formSelector" + :selector="$options.FORM_SELECTOR" @[$options.EVENT_ERROR]="onError" @[$options.EVENT_SUCCESS]="onSuccess" > diff --git a/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue b/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue index 3ebcde817f9..0bbbc795fff 100644 --- a/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue +++ b/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue @@ -87,7 +87,7 @@ export default { :disabled="!previousDesign" :title="$options.i18n.previousButton" :aria-label="$options.i18n.previousButton" - icon="angle-left" + icon="chevron-lg-left" class="js-previous-design" @click="navigateToDesign(previousDesign)" /> @@ -96,7 +96,7 @@ export default { :disabled="!nextDesign" :title="$options.i18n.nextButton" :aria-label="$options.i18n.nextButton" - icon="angle-right" + icon="chevron-lg-right" class="js-next-design" @click="navigateToDesign(nextDesign)" /> diff --git a/app/assets/javascripts/projects/pipelines/charts/components/app.vue b/app/assets/javascripts/projects/pipelines/charts/components/app.vue index 0c4ce5dab65..35e7554aee2 100644 --- a/app/assets/javascripts/projects/pipelines/charts/components/app.vue +++ b/app/assets/javascripts/projects/pipelines/charts/components/app.vue @@ -12,6 +12,8 @@ export default { DeploymentFrequencyCharts: () => import('ee_component/dora/components/deployment_frequency_charts.vue'), LeadTimeCharts: () => import('ee_component/dora/components/lead_time_charts.vue'), + TimeToRestoreServiceCharts: () => + import('ee_component/dora/components/time_to_restore_service_charts.vue'), ProjectQualitySummary: () => import('ee_component/project_quality_summary/app.vue'), }, piplelinesTabEvent: 'p_analytics_ci_cd_pipelines', @@ -96,6 +98,13 @@ export default { > <lead-time-charts /> </gl-tab> + <gl-tab + :title="s__('DORA4Metrics|Time to restore service')" + data-testid="time-to-restore-service-tab" + @click="trackTabClick($options.timeToRestoreServiceTabEvent)" + > + <time-to-restore-service-charts /> + </gl-tab> </template> <gl-tab v-if="shouldRenderQualitySummary" :title="s__('QualitySummary|Project quality')"> <project-quality-summary /> diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index cb5693bbb6a..c68437b9879 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -594,7 +594,7 @@ export default { </div> <extensions-container :mr="mr" /> <grouped-codequality-reports-app - v-if="shouldRenderCodeQuality && !shouldShowExtension" + v-if="shouldRenderCodeQuality && !shouldShowCodeQualityExtension" :head-blob-path="mr.headBlobPath" :base-blob-path="mr.baseBlobPath" :codequality-reports-path="mr.codequalityReportsPath" diff --git a/app/models/concerns/sensitive_serializable_hash.rb b/app/models/concerns/sensitive_serializable_hash.rb index 94451fcd2c2..4ad8d16fcb9 100644 --- a/app/models/concerns/sensitive_serializable_hash.rb +++ b/app/models/concerns/sensitive_serializable_hash.rb @@ -10,7 +10,7 @@ module SensitiveSerializableHash class_methods do def prevent_from_serialization(*keys) self.attributes_exempt_from_serializable_hash ||= [] - self.attributes_exempt_from_serializable_hash.concat keys + self.attributes_exempt_from_serializable_hash += keys end end diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml index bd6ff9b426f..87353890aae 100644 --- a/app/views/admin/application_settings/_eks.html.haml +++ b/app/views/admin/application_settings/_eks.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('Amazon EKS') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = _('Amazon EKS integration allows you to provision EKS clusters from GitLab.') diff --git a/app/views/admin/application_settings/_external_authorization_service_form.html.haml b/app/views/admin/application_settings/_external_authorization_service_form.html.haml index 1abf8f78060..8be52168fdb 100644 --- a/app/views/admin/application_settings/_external_authorization_service_form.html.haml +++ b/app/views/admin/application_settings/_external_authorization_service_form.html.haml @@ -2,8 +2,8 @@ .settings-header %h4 = s_('ExternalAuthorization|External authorization') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? 'Collapse' : 'Expand' + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do + = expanded ? _('Collapse') : _('Expand') %p = s_('ExternalAuthorization|External classification policy authorization.') = link_to _('Learn more.'), help_page_path('user/admin_area/settings/external_authorization'), target: '_blank', rel: 'noopener noreferrer' diff --git a/app/views/admin/application_settings/_floc.html.haml b/app/views/admin/application_settings/_floc.html.haml index 14b1a58c1ad..125ed569463 100644 --- a/app/views/admin/application_settings/_floc.html.haml +++ b/app/views/admin/application_settings/_floc.html.haml @@ -4,7 +4,7 @@ .settings-header %h4 = s_('FloC|Federated Learning of Cohorts') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = s_('FloC|Configure whether you want to participate in FloC.').html_safe diff --git a/app/views/admin/application_settings/_gitpod.html.haml b/app/views/admin/application_settings/_gitpod.html.haml index 515b3691324..eb47d177701 100644 --- a/app/views/admin/application_settings/_gitpod.html.haml +++ b/app/views/admin/application_settings/_gitpod.html.haml @@ -4,7 +4,7 @@ .settings-header %h4 = _('Gitpod') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p #js-gitpod-settings-help-text{ data: {"message" => gitpod_enable_description, "message-url" => "https://gitpod.io/" } } diff --git a/app/views/admin/application_settings/_jira_connect_application_key.html.haml b/app/views/admin/application_settings/_jira_connect_application_key.html.haml index b57dea3c388..e395741dcaa 100644 --- a/app/views/admin/application_settings/_jira_connect_application_key.html.haml +++ b/app/views/admin/application_settings/_jira_connect_application_key.html.haml @@ -4,7 +4,7 @@ .settings-header %h4 = s_('JiraConnect|GitLab for Jira App') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = s_('JiraConnect|Configure your Jira Connect Application ID.') diff --git a/app/views/admin/application_settings/_kroki.html.haml b/app/views/admin/application_settings/_kroki.html.haml index 61469d87656..ad9e7ca5fea 100644 --- a/app/views/admin/application_settings/_kroki.html.haml +++ b/app/views/admin/application_settings/_kroki.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('Kroki') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = _('Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Textile documents using Kroki.') diff --git a/app/views/admin/application_settings/_mailgun.html.haml b/app/views/admin/application_settings/_mailgun.html.haml index 7afb35bc9cb..e84fdc56f93 100644 --- a/app/views/admin/application_settings/_mailgun.html.haml +++ b/app/views/admin/application_settings/_mailgun.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('Mailgun') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = _('Configure the %{link} integration.').html_safe % { link: link_to(_('Mailgun events'), 'https://documentation.mailgun.com/en/latest/user_manual.html#webhooks', target: '_blank', rel: 'noopener noreferrer') } diff --git a/app/views/admin/application_settings/_package_registry.html.haml b/app/views/admin/application_settings/_package_registry.html.haml index 398e63cdfdc..4858353f3b6 100644 --- a/app/views/admin/application_settings/_package_registry.html.haml +++ b/app/views/admin/application_settings/_package_registry.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('Package Registry') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _("Control how the GitLab Package Registry functions.") diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml index 42914652655..57931544e65 100644 --- a/app/views/admin/application_settings/_plantuml.html.haml +++ b/app/views/admin/application_settings/_plantuml.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('PlantUML') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = _('Render diagrams in your documents using PlantUML.') diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml index 378c1712ae0..e9387ab3f26 100644 --- a/app/views/admin/application_settings/_snowplow.html.haml +++ b/app/views/admin/application_settings/_snowplow.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('Snowplow') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('development/snowplow/index') } diff --git a/app/views/admin/application_settings/_sourcegraph.html.haml b/app/views/admin/application_settings/_sourcegraph.html.haml index 391f79e431b..7aff7309e07 100644 --- a/app/views/admin/application_settings/_sourcegraph.html.haml +++ b/app/views/admin/application_settings/_sourcegraph.html.haml @@ -5,7 +5,7 @@ .settings-header %h4 = _('Sourcegraph') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://sourcegraph.com/' } diff --git a/app/views/admin/application_settings/_third_party_offers.html.haml b/app/views/admin/application_settings/_third_party_offers.html.haml index a62e730ee89..205e14fb8ab 100644 --- a/app/views/admin/application_settings/_third_party_offers.html.haml +++ b/app/views/admin/application_settings/_third_party_offers.html.haml @@ -3,7 +3,7 @@ .settings-header %h4 = _('Customer experience improvement and third-party offers') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p = _('Control whether to display customer experience improvement content and third-party offers in GitLab.') diff --git a/app/views/admin/application_settings/ci/_header.html.haml b/app/views/admin/application_settings/ci/_header.html.haml index a22e67b0522..5e3f0d6f2aa 100644 --- a/app/views/admin/application_settings/ci/_header.html.haml +++ b/app/views/admin/application_settings/ci/_header.html.haml @@ -3,7 +3,7 @@ %h4 = _('Variables') -%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } += render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') %p diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml index e925175b7ea..b635e7198cb 100644 --- a/app/views/admin/application_settings/ci_cd.html.haml +++ b/app/views/admin/application_settings/ci_cd.html.haml @@ -16,7 +16,7 @@ .settings-header %h4 = _('Continuous Integration and Deployment') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Customize CI/CD settings, including Auto DevOps, shared runners, and job artifacts.') @@ -31,7 +31,7 @@ .settings-header %h4 = _('Container Registry') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Various container registry settings.') @@ -43,7 +43,7 @@ .settings-header %h4 = s_('Runners|Runner registration') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? 'Collapse' : 'Expand' .settings-content = render 'runner_registrars_form' diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index 9f1f29efeca..36b9ad189d8 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -17,7 +17,7 @@ .settings-header %h4 = _('Account and limit') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan.') @@ -28,7 +28,7 @@ .settings-header %h4 = _('Diff limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set size limits for displaying diffs in the browser.') @@ -39,7 +39,7 @@ .settings-header %h4 = _('Sign-up restrictions') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure the way a user creates a new account.') @@ -50,7 +50,7 @@ .settings-header %h4 = _('Sign-in restrictions') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set sign-in restrictions for all users.') @@ -62,7 +62,7 @@ .settings-header %h4 = _('Terms of Service and Privacy Policy') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance.') @@ -76,7 +76,7 @@ .settings-header %h4 = _('Web terminal') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set the maximum session time for a web terminal.') @@ -88,7 +88,7 @@ .settings-header %h4 = _('Web IDE') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Manage Web IDE features.') diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml index 8e4b0b53f28..7cc0ff2c28e 100644 --- a/app/views/admin/application_settings/metrics_and_profiling.html.haml +++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml @@ -8,7 +8,7 @@ .settings-header %h4 = _('Metrics - Prometheus') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Monitor the health and performance of GitLab with Prometheus.') @@ -19,7 +19,7 @@ .settings-header %h4 = _('Metrics - Grafana') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Link to your Grafana instance.') @@ -32,7 +32,7 @@ .settings-header %h4 = _('Profiling - Performance bar') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Enable access to the performance bar for non-administrators in a given group.') @@ -46,7 +46,7 @@ .settings-header#usage-statistics %h4 = _('Usage statistics') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Enable or disable version check and Service Ping.') @@ -58,7 +58,7 @@ .settings-header %h4 = _('Sentry') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure Sentry integration for error tracking') diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml index a2497fe122b..f3264f733ab 100644 --- a/app/views/admin/application_settings/network.html.haml +++ b/app/views/admin/application_settings/network.html.haml @@ -6,7 +6,7 @@ .settings-header %h4 = _('Performance optimization') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Various settings that affect GitLab performance.') @@ -17,7 +17,7 @@ .settings-header %h4 = _('User and IP rate limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set limits for web and API requests.') @@ -29,7 +29,7 @@ .settings-header %h4 = _('Package registry rate limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set rate limits for package registry API requests that supersede the general user and IP rate limits.') @@ -41,7 +41,7 @@ .settings-header %h4 = _('Files API Rate Limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure specific limits for Files API requests that supersede the general user and IP rate limits.') @@ -52,7 +52,7 @@ .settings-header %h4 = _('Search rate limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set rate limits for searches performed by web or API requests.') @@ -63,7 +63,7 @@ .settings-header %h4 = _('Deprecated API rate limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure specific limits for deprecated API requests that supersede the general user and IP rate limits.') @@ -75,7 +75,7 @@ .settings-header %h4 = _('Git LFS Rate Limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure specific limits for Git LFS requests that supersede the general user and IP rate limits.') @@ -88,7 +88,7 @@ %h4 = s_('OutboundRequests|Outbound requests') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = s_('OutboundRequests|Allow requests to the local network from hooks and services.') @@ -100,7 +100,7 @@ .settings-header %h4 = _('Protected paths') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Rate limit access to specified paths.') @@ -113,7 +113,7 @@ .settings-header %h4 = _('Issues Rate Limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Limit the number of issues and epics per minute a user can create through web and API requests.') @@ -125,7 +125,7 @@ .settings-header %h4 = _('Notes rate limit') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set the per-user rate limit for notes created by web or API requests.') @@ -137,7 +137,7 @@ .settings-header %h4 = _('Users API rate limit') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set the per-user rate limit for getting a user by ID via the API.') @@ -149,7 +149,7 @@ .settings-header %h4 = _('Import and export rate limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Set per-user rate limits for imports and exports of projects and groups.') @@ -161,7 +161,7 @@ .settings-header %h4 = _('Pipeline creation rate limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Limit the number of pipeline creation requests per minute. This limit includes pipelines created through the UI, the API, and by background processing.') diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml index af4bfd28a01..858f96fc0d0 100644 --- a/app/views/admin/application_settings/preferences.html.haml +++ b/app/views/admin/application_settings/preferences.html.haml @@ -6,7 +6,7 @@ .settings-header %h4 = _('Email') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Various email settings.') @@ -17,7 +17,7 @@ .settings-header %h4 = _("What's new") - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _("Configure %{italic_start}What's new%{italic_end} drawer and content.").html_safe % { italic_start: '<i>'.html_safe, italic_end: '</i>'.html_safe } @@ -28,7 +28,7 @@ .settings-header %h4 = _('Sign-in and Help page') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Additional text for the sign-in and Help page.') @@ -40,7 +40,7 @@ .settings-header %h4 = _('Pages') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = s_('AdminSettings|Size and domain settings for Pages static sites.') @@ -51,7 +51,7 @@ .settings-header %h4 = _('Polling interval multiplier') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Adjust how frequently the GitLab UI polls for updates.') @@ -63,7 +63,7 @@ .settings-header %h4 = _('Gitaly timeouts') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure Gitaly timeouts.') @@ -76,7 +76,7 @@ .settings-header %h4 = _('Localization') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure the default first day of the week and time tracking units.') @@ -87,7 +87,7 @@ .settings-header %h4 = _('Sidekiq job size limits') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Limit the size of Sidekiq jobs stored in Redis.') diff --git a/app/views/admin/application_settings/reporting.html.haml b/app/views/admin/application_settings/reporting.html.haml index ae6243c3b50..b15fcd93d1a 100644 --- a/app/views/admin/application_settings/reporting.html.haml +++ b/app/views/admin/application_settings/reporting.html.haml @@ -6,7 +6,7 @@ .settings-header %h4 = _('Spam and Anti-bot Protection') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure CAPTCHAs, IP address limits, and other anti-spam measures.') @@ -20,7 +20,7 @@ .settings-header %h4 = _('Abuse reports') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Receive notification of abuse reports by email.') diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml index ce7972827d3..785261b4c7b 100644 --- a/app/views/admin/application_settings/repository.html.haml +++ b/app/views/admin/application_settings/repository.html.haml @@ -6,7 +6,7 @@ .settings-header %h4 = _('Default branch') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = s_('AdminSettings|Set the initial name and protections for the default branch of new repositories created in the instance.') @@ -17,7 +17,7 @@ .settings-header %h4 = _('Repository mirroring') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? 'Collapse' : 'Expand' %p = _('Configure repository mirroring.') @@ -29,7 +29,7 @@ .settings-header %h4 = _('Repository storage') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Configure repository storage.') @@ -41,7 +41,7 @@ .settings-header %h4 = _('Repository maintenance') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p - repository_checks_link_url = help_page_path('administration/repository_checks.md') @@ -56,7 +56,7 @@ .settings-header %h4 = _('External storage for repository static objects') - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') %p = _('Serve repository static objects (for example, archives and blobs) from external storage.') diff --git a/app/views/admin/hooks/_form.html.haml b/app/views/admin/hooks/_form.html.haml index a309e874317..cf3b6e6e0e0 100644 --- a/app/views/admin/hooks/_form.html.haml +++ b/app/views/admin/hooks/_form.html.haml @@ -1,4 +1,4 @@ -= form_errors(hook) += form_errors(hook, pajamas_alert: true) .form-group = form.label :url, _('URL'), class: 'label-bold' diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index f947e174990..0fae92610f6 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -22,6 +22,5 @@ = render 'shared/projects/dropdown' = link_to new_project_path, class: 'gl-button btn btn-confirm' do = _('New Project') - = button_tag _("Search"), class: "gl-button btn btn-confirm btn-search hide" = render 'projects' diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml index 378caf803dd..529692df0b6 100644 --- a/app/views/admin/users/_head.html.haml +++ b/app/views/admin/users/_head.html.haml @@ -32,7 +32,7 @@ - if impersonation_enabled? && @user.can?(:log_in) = link_to _('Impersonate'), impersonate_admin_user_path(@user), method: :post, class: "btn btn-default gl-button", data: { qa_selector: 'impersonate_user_link' } - if can_force_email_confirmation?(@user) - %button.btn.gl-button.btn-confirm.js-confirm-modal-button{ data: confirm_user_data(@user) } + = render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { class: 'js-confirm-modal-button', data: confirm_user_data(@user) }) do = _('Confirm user') .gl-p-2 #js-admin-user-actions{ data: admin_user_actions_data_attributes(@user) } diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml index 355f7f4d32e..d3951c91329 100644 --- a/app/views/projects/pipeline_schedules/_form.html.haml +++ b/app/views/projects/pipeline_schedules/_form.html.haml @@ -1,5 +1,5 @@ = 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_errors(@schedule, pajamas_alert: true) .form-group.row .col-md-9 = f.label :description, _('Description'), class: 'label-bold' diff --git a/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml b/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml index 4e3b6b2afc4..8431a38a69b 100644 --- a/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml +++ b/app/views/shared/namespaces/cascading_settings/_lock_icon.html.haml @@ -1,4 +1 @@ -%button.position-absolute.gl-top-3.gl-right-0.gl-translate-y-n50.gl-cursor-default.btn.btn-default.btn-sm.gl-button.btn-default-tertiary.js-cascading-settings-lock-popover-target{ class: 'gl-p-1! gl-text-gray-600! gl-bg-transparent!', - type: 'button', - data: cascading_namespace_settings_popover_data(attribute, group, settings_path_helper) } - = sprite_icon('lock', size: 16) += render Pajamas::ButtonComponent.new(category: 'tertiary', icon: 'lock', button_options: { class: 'position-absolute gl-top-3 gl-right-0 gl-translate-y-n50 gl-p-1! gl-bg-transparent! gl-cursor-default! js-cascading-settings-lock-popover-target', data: cascading_namespace_settings_popover_data(attribute, group, settings_path_helper) }) diff --git a/doc/api/bulk_imports.md b/doc/api/bulk_imports.md index cae23b35fbe..8c5c4574206 100644 --- a/doc/api/bulk_imports.md +++ b/doc/api/bulk_imports.md @@ -27,7 +27,7 @@ POST /bulk_imports | `entities` | Array | yes | List of entities to import. | | `entities[source_type]` | String | yes | Source entity type (only `group_entity` is supported). | | `entities[source_full_path]` | String | yes | Source full path of the entity to import. | -| `entities[destination_name]` | String | yes | Destination name for the entity. | +| `entities[destination_name]` | String | yes | Destination slug for the entity. | | `entities[destination_namespace]` | String | no | Destination namespace for the entity. | ```shell @@ -41,7 +41,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitla { "source_full_path": "source/full/path", "source_type": "group_entity", - "destination_name": "destination_name", + "destination_name": "destination_slug", "destination_namespace": "destination/namespace/path" } ] @@ -126,7 +126,7 @@ curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab "bulk_import_id": 1, "status": "finished", "source_full_path": "source_group", - "destination_name": "destination_name", + "destination_name": "destination_slug", "destination_namespace": "destination_path", "parent_id": null, "namespace_id": 1, @@ -140,7 +140,7 @@ curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab "bulk_import_id": 2, "status": "failed", "source_full_path": "another_group", - "destination_name": "another_name", + "destination_name": "another_slug", "destination_namespace": "another_namespace", "parent_id": null, "namespace_id": null, diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index b07e3ca328b..1e343801120 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -2803,7 +2803,7 @@ This example creates a release: **Related topics**: -- [CI/CD example of the `release` keyword](../../user/project/releases/index.md#cicd-example-of-the-release-keyword). +- [CI/CD example of the `release` keyword](../../user/project/releases/index.md#creating-a-release-by-using-a-cicd-job). - [Create multiple releases in a single pipeline](../../user/project/releases/index.md#create-multiple-releases-in-a-single-pipeline). - [Use a custom SSL CA certificate authority](../../user/project/releases/index.md#use-a-custom-ssl-ca-certificate-authority). diff --git a/doc/user/analytics/ci_cd_analytics.md b/doc/user/analytics/ci_cd_analytics.md index 36faab4922b..9e390142cc6 100644 --- a/doc/user/analytics/ci_cd_analytics.md +++ b/doc/user/analytics/ci_cd_analytics.md @@ -6,6 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w # CI/CD analytics **(FREE)** +Use the CI/CD analytics page to view pipeline success rates and duration, and the history of [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) over time. + ## Pipeline success and duration charts CI/CD analytics shows the history of your pipeline successes and failures, as well as how long each pipeline @@ -42,6 +44,8 @@ frequency to the `production` environment. The environment must be part of the [production deployment tier](../../ci/environments/index.md#deployment-tier-of-environments) for its deployment information to appear on the graphs. + Deployment frequency is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery. + The deployment frequency chart is available for groups and projects. To view the deployment frequency chart: @@ -64,6 +68,8 @@ merge requests to be deployed to a production environment. This chart is availab - For time periods in which no merge requests were deployed, the charts render a red, dashed line. + lead time for changes is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery. + To view the lead time for changes chart: 1. On the top bar, select **Menu > Projects** and find your project. @@ -71,3 +77,19 @@ To view the lead time for changes chart: 1. Select the **Lead time** tab. ![Lead time](img/lead_time_chart_v13_11.png) + +## View time to restore service chart **(ULTIMATE)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356959) in GitLab 15.1 + +The time to restore service chart shows information about the median time an incident was open in a production environment. This chart is available for groups and projects. + +Time to restore service is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery. + +To view the time to restore service chart: + +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Analytics > CI/CD Analytics**. +1. Select the **Time to restore service** tab. + +![Lead time](img/time_to_restore_service_charts_v15_1.png) diff --git a/doc/user/analytics/img/time_to_restore_service_charts_v15_1.png b/doc/user/analytics/img/time_to_restore_service_charts_v15_1.png Binary files differnew file mode 100644 index 00000000000..25aac385750 --- /dev/null +++ b/doc/user/analytics/img/time_to_restore_service_charts_v15_1.png diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md index 6d0b87d29e2..91d9bd918b6 100644 --- a/doc/user/analytics/index.md +++ b/doc/user/analytics/index.md @@ -97,6 +97,12 @@ in the given time period. This assumes: - Incidents and deployments have a strictly one-to-one relationship. An incident is related to only one production deployment, and any production deployment is related to no more than one incident). +Time to restore service displays in several charts: + +- [Group-level value stream analytics](../group/value_stream_analytics/index.md) +- [Project-level value stream analytics](value_stream_analytics.md) +- [CI/CD analytics](ci_cd_analytics.md) + To retrieve metrics for time to restore service, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs. ### Change failure rate diff --git a/doc/user/clusters/agent/vulnerabilities.md b/doc/user/clusters/agent/vulnerabilities.md index a3fe80ecd4b..e56167de4ae 100644 --- a/doc/user/clusters/agent/vulnerabilities.md +++ b/doc/user/clusters/agent/vulnerabilities.md @@ -16,8 +16,6 @@ You can also configure your agent so the vulnerabilities are displayed with othe Prerequisite: - You must have at least the Developer role. -- [Cluster image scanning](../../application_security/cluster_image_scanning/index.md) - must be part of your build process. To view vulnerability information in GitLab: diff --git a/doc/user/infrastructure/clusters/connect/new_gke_cluster.md b/doc/user/infrastructure/clusters/connect/new_gke_cluster.md index 1899f90c069..07d0c722d8b 100644 --- a/doc/user/infrastructure/clusters/connect/new_gke_cluster.md +++ b/doc/user/infrastructure/clusters/connect/new_gke_cluster.md @@ -148,11 +148,12 @@ To remove all resources: - init - validate - build + - test - deploy - cleanup destroy: - extends: .destroy + extends: .terraform:destroy needs: [] ``` diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md index 9deeadd2247..d5ddc0468e1 100644 --- a/doc/user/project/releases/index.md +++ b/doc/user/project/releases/index.md @@ -63,7 +63,7 @@ switch between ascending or descending order, select **Sort order**. You can create a release: -- [Using a job in your CI/CD pipeline](#create-a-release-by-using-a-cicd-job). +- [Using a job in your CI/CD pipeline](#creating-a-release-by-using-a-cicd-job). - [In the Releases page](#create-a-release-in-the-releases-page). - [In the Tags page](#create-a-release-in-the-tags-page). - Using the [Releases API](../../../api/releases/index.md#create-a-release). @@ -118,100 +118,71 @@ To edit release notes of an existing Git tag: You can use Markdown and drag and drop files to this text box. 1. Select **Save changes**. -### Create a release by using a CI/CD job +### Creating a release by using a CI/CD job -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19298) in GitLab 12.7. - -You can create a release directly as part of the GitLab CI/CD pipeline -by using the [`release` keyword](../../../ci/yaml/index.md#release) in the job definition. +You can create a release directly as part of the GitLab CI/CD pipeline by using the +[`release` keyword](../../../ci/yaml/index.md#release) in the job definition. The release is created only if the job processes without error. If the API returns an error during release creation, the release job fails. -#### CI/CD example of the `release` keyword +Methods for creating a release using a CI/CD job include: + +- Create a release when a Git tag is created. +- Create a release when a commit is merged to the default branch. + +#### Create a release when a Git tag is created -To create a release when you push a Git tag, or when you add a Git tag -in the UI by going to **Repository > Tags**: +In this CI/CD example, pushing a Git tag to the repository, or creating a Git tag in the UI triggers +the release. You can use this method if you prefer to create the Git tag manually, and create a +release as a result. NOTE: -Do not provide **Release notes** when you create the Git tag in the UI. -Providing release notes creates a release, resulting in the pipeline failing. +Do not provide Release notes when you create the Git tag in the UI. Providing release notes +creates a release, resulting in the pipeline failing. + +Key points in the following _extract_ of an example `.gitlab-ci.yml` file: + +- The `rules` stanza defines when the job is added to the pipeline. +- The Git tag is used in the release's name and description. ```yaml release_job: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest rules: - - if: $CI_COMMIT_TAG # Run this job when a tag is created manually + - if: $CI_COMMIT_TAG # Run this job when a tag is created script: - echo "running release_job" - release: - name: 'Release $CI_COMMIT_TAG' - description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined - tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline. - ref: '$CI_COMMIT_TAG' - milestones: - - 'm1' - - 'm2' - - 'm3' - released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable. - assets: # Optional, multiple asset links - links: - - name: 'asset1' - url: 'https://example.com/assets/1' - - name: 'asset2' - url: 'https://example.com/assets/2' - filepath: '/pretty/url/1' # optional - link_type: 'other' # optional + release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties + tag_name: '$CI_COMMIT_TAG' + description: '$CI_COMMIT_TAG' ``` -To create a release automatically when commits are pushed or merged to the default branch, -using a new Git tag that is defined with variables: +#### Create a release when a commit is merged to the default branch -```yaml -prepare_job: - stage: prepare # This stage must run before the release stage - rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch - script: - - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables - - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file - artifacts: - reports: - dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs +In this CI/CD example, merging a commit to the default branch triggers the pipeline. You can use +this method if your release workflow does not create a tag manually. +Key points in the following _extract_ of an example `.gitlab-ci.yml` file: + +- The Git tag, description, and reference are created automatically in the pipeline. +- If you manually create a tag, the `release_job` job does not run. + +```yaml release_job: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest - needs: - - job: prepare_job - artifacts: true rules: - if: $CI_COMMIT_TAG when: never # Do not run this job when a tag is created manually - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - echo "running release_job for $TAG" - release: - name: 'Release $TAG' - description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG - tag_name: '$TAG' # variables must be defined elsewhere - ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the - milestones: # prepare_job - - 'm1' - - 'm2' - - 'm3' - released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable. - assets: - links: - - name: 'asset1' - url: 'https://example.com/assets/1' - - name: 'asset2' - url: 'https://example.com/assets/2' - filepath: '/pretty/url/1' # optional - link_type: 'other' # optional + release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties + tag_name: 'v0.$CI_PIPELINE_IID' # The version is incremented per pipeline. + description: 'v0.$CI_PIPELINE_IID' + ref: '$CI_COMMIT_SHA' # The tag is created from the pipeline SHA. ``` NOTE: diff --git a/lib/api/bulk_imports.rb b/lib/api/bulk_imports.rb index 766e05eca23..b1cb84c97cb 100644 --- a/lib/api/bulk_imports.rb +++ b/lib/api/bulk_imports.rb @@ -47,7 +47,7 @@ module API requires :source_type, type: String, desc: 'Source entity type (only `group_entity` is supported)', values: %w[group_entity] requires :source_full_path, type: String, desc: 'Source full path of the entity to import' - requires :destination_name, type: String, desc: 'Destination name for the entity' + requires :destination_name, type: String, desc: 'Destination slug for the entity' requires :destination_namespace, type: String, desc: 'Destination namespace for the entity' end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 33bd6346cdc..b60d84ad66f 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6909,6 +6909,9 @@ msgstr "" msgid "CICDAnalytics|Something went wrong while fetching release statistics" msgstr "" +msgid "CICDAnalytics|Time to restore service" +msgstr "" + msgid "CICDAnalytics|What is shared runner duration?" msgstr "" @@ -11697,6 +11700,9 @@ msgstr "" msgid "DastSiteValidation|Meta tag validation" msgstr "" +msgid "DastSiteValidation|Not validated" +msgstr "" + msgid "DastSiteValidation|Retry validation" msgstr "" diff --git a/spec/frontend/access_tokens/components/new_access_token_app_spec.js b/spec/frontend/access_tokens/components/new_access_token_app_spec.js index 0fdd77ef6f2..9ccadbebf7a 100644 --- a/spec/frontend/access_tokens/components/new_access_token_app_spec.js +++ b/spec/frontend/access_tokens/components/new_access_token_app_spec.js @@ -34,7 +34,7 @@ describe('~/access_tokens/components/new_access_token_app', () => { beforeEach(() => { // NewAccessTokenApp observes a form element - setHTMLFixture(`<form id="${FORM_SELECTOR}"><input type="submit"/></form>`); + setHTMLFixture(`<form id="${FORM_SELECTOR.slice(1)}"><input type="submit"/></form>`); createComponent(); }); diff --git a/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap b/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap index 3cb48d7632f..b5a69b28a88 100644 --- a/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap +++ b/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap @@ -18,7 +18,7 @@ exports[`Design management pagination component renders navigation buttons 1`] = category="primary" class="js-previous-design" disabled="true" - icon="angle-left" + icon="chevron-lg-left" size="medium" title="Go to previous design" variant="default" @@ -29,7 +29,7 @@ exports[`Design management pagination component renders navigation buttons 1`] = buttontextclasses="" category="primary" class="js-next-design" - icon="angle-right" + icon="chevron-lg-right" size="medium" title="Go to next design" variant="default" diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js index 9c94925c817..98c7856a61a 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js @@ -13,6 +13,7 @@ jest.mock('~/lib/utils/url_utility'); const DeploymentFrequencyChartsStub = { name: 'DeploymentFrequencyCharts', render: () => {} }; const LeadTimeChartsStub = { name: 'LeadTimeCharts', render: () => {} }; +const TimeToRestoreServiceChartsStub = { name: 'TimeToRestoreServiceCharts', render: () => {} }; const ProjectQualitySummaryStub = { name: 'ProjectQualitySummary', render: () => {} }; describe('ProjectsPipelinesChartsApp', () => { @@ -31,6 +32,7 @@ describe('ProjectsPipelinesChartsApp', () => { stubs: { DeploymentFrequencyCharts: DeploymentFrequencyChartsStub, LeadTimeCharts: LeadTimeChartsStub, + TimeToRestoreServiceCharts: TimeToRestoreServiceChartsStub, ProjectQualitySummary: ProjectQualitySummaryStub, }, }, @@ -47,6 +49,7 @@ describe('ProjectsPipelinesChartsApp', () => { const findAllGlTabs = () => wrapper.findAll(GlTab); const findGlTabAtIndex = (index) => findAllGlTabs().at(index); const findLeadTimeCharts = () => wrapper.find(LeadTimeChartsStub); + const findTimeToRestoreServiceCharts = () => wrapper.find(TimeToRestoreServiceChartsStub); const findDeploymentFrequencyCharts = () => wrapper.find(DeploymentFrequencyChartsStub); const findPipelineCharts = () => wrapper.find(PipelineCharts); const findProjectQualitySummary = () => wrapper.find(ProjectQualitySummaryStub); @@ -62,6 +65,7 @@ describe('ProjectsPipelinesChartsApp', () => { expect(findGlTabAtIndex(0).attributes('title')).toBe('Pipelines'); expect(findGlTabAtIndex(1).attributes('title')).toBe('Deployment frequency'); expect(findGlTabAtIndex(2).attributes('title')).toBe('Lead time'); + expect(findGlTabAtIndex(3).attributes('title')).toBe('Time to restore service'); }); it('renders the pipeline charts', () => { @@ -76,6 +80,10 @@ describe('ProjectsPipelinesChartsApp', () => { expect(findLeadTimeCharts().exists()).toBe(true); }); + it('renders the time to restore service charts', () => { + expect(findTimeToRestoreServiceCharts().exists()).toBe(true); + }); + it('renders the project quality summary', () => { expect(findProjectQualitySummary().exists()).toBe(true); }); @@ -123,10 +131,11 @@ describe('ProjectsPipelinesChartsApp', () => { describe('event tracking', () => { it.each` - testId | event - ${'pipelines-tab'} | ${'p_analytics_ci_cd_pipelines'} - ${'deployment-frequency-tab'} | ${'p_analytics_ci_cd_deployment_frequency'} - ${'lead-time-tab'} | ${'p_analytics_ci_cd_lead_time'} + testId | event + ${'pipelines-tab'} | ${'p_analytics_ci_cd_pipelines'} + ${'deployment-frequency-tab'} | ${'p_analytics_ci_cd_deployment_frequency'} + ${'lead-time-tab'} | ${'p_analytics_ci_cd_lead_time'} + ${'time-to-restore-service-tab'} | ${'p_analytics_ci_cd_time_to_restore_service'} `('tracks the $event event when clicked', ({ testId, event }) => { jest.spyOn(API, 'trackRedisHllUserEvent'); @@ -141,12 +150,13 @@ describe('ProjectsPipelinesChartsApp', () => { describe('when provided with a query param', () => { it.each` - chart | tab - ${'lead-time'} | ${'2'} - ${'deployment-frequency'} | ${'1'} - ${'pipelines'} | ${'0'} - ${'fake'} | ${'0'} - ${''} | ${'0'} + chart | tab + ${'time-to-restore-service'} | ${'3'} + ${'lead-time'} | ${'2'} + ${'deployment-frequency'} | ${'1'} + ${'pipelines'} | ${'0'} + ${'fake'} | ${'0'} + ${''} | ${'0'} `('shows the correct tab for URL parameter "$chart"', ({ chart, tab }) => { setWindowLocation(`${TEST_HOST}/gitlab-org/gitlab-test/-/pipelines/charts?chart=${chart}`); getParameterValues.mockImplementation((name) => { diff --git a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js index a8c55c2c735..298ac764d73 100644 --- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js @@ -68,7 +68,7 @@ describe('MrWidgetOptions', () => { gon.features = {}; }); - const createComponent = (mrData = mockData, options = {}) => { + const createComponent = (mrData = mockData, options = {}, glFeatures = {}) => { if (wrapper) { wrapper.destroy(); } @@ -77,6 +77,9 @@ describe('MrWidgetOptions', () => { propsData: { mrData: { ...mrData }, }, + provide: { + glFeatures, + }, ...options, }); @@ -622,7 +625,16 @@ describe('MrWidgetOptions', () => { }); describe('code quality widget', () => { - it('renders the component', () => { + beforeEach(() => { + jest.spyOn(document, 'dispatchEvent'); + }); + it('renders the component when refactorCodeQualityExtension is false', () => { + createComponent(mockData, {}, { refactorCodeQualityExtension: false }); + expect(wrapper.find('.js-codequality-widget').exists()).toBe(true); + }); + + it('does not render the component when refactorCodeQualityExtension is true', () => { + createComponent(mockData, {}, { refactorCodeQualityExtension: true }); expect(wrapper.find('.js-codequality-widget').exists()).toBe(true); }); }); diff --git a/spec/models/concerns/sensitive_serializable_hash_spec.rb b/spec/models/concerns/sensitive_serializable_hash_spec.rb index 646691dd091..3c9199ce18f 100644 --- a/spec/models/concerns/sensitive_serializable_hash_spec.rb +++ b/spec/models/concerns/sensitive_serializable_hash_spec.rb @@ -4,11 +4,15 @@ require 'spec_helper' RSpec.describe SensitiveSerializableHash do describe '.prevent_from_serialization' do - let(:test_class) do + let(:base_class) do Class.new do include ActiveModel::Serialization include SensitiveSerializableHash + end + end + let(:test_class) do + Class.new(base_class) do attr_accessor :name, :super_secret prevent_from_serialization :super_secret @@ -19,6 +23,12 @@ RSpec.describe SensitiveSerializableHash do end end + let(:another_class) do + Class.new(base_class) do + prevent_from_serialization :sub_secret + end + end + let(:model) { test_class.new } it 'does not include the field in serializable_hash' do @@ -30,6 +40,11 @@ RSpec.describe SensitiveSerializableHash do expect(model.serializable_hash(unsafe_serialization_hash: true)).to include('super_secret') end end + + it 'does not change parent class attributes_exempt_from_serializable_hash' do + expect(test_class.attributes_exempt_from_serializable_hash).to contain_exactly(:super_secret) + expect(another_class.attributes_exempt_from_serializable_hash).to contain_exactly(:sub_secret) + end end describe '#serializable_hash' do diff --git a/spec/requests/api/bulk_imports_spec.rb b/spec/requests/api/bulk_imports_spec.rb index 3b8136f265b..9f9907f4f00 100644 --- a/spec/requests/api/bulk_imports_spec.rb +++ b/spec/requests/api/bulk_imports_spec.rb @@ -62,7 +62,7 @@ RSpec.describe API::BulkImports do entities: [ source_type: 'group_entity', source_full_path: 'full_path', - destination_name: 'destination_name', + destination_name: 'destination_slug', destination_namespace: 'destination_namespace' ] } @@ -82,7 +82,7 @@ RSpec.describe API::BulkImports do entities: [ source_type: 'group_entity', source_full_path: 'full_path', - destination_name: 'destination_name', + destination_name: 'destination_slug', destination_namespace: 'destination_namespace' ] } |