diff options
47 files changed, 441 insertions, 188 deletions
diff --git a/.rubocop_todo/layout/space_around_method_call_operator.yml b/.rubocop_todo/layout/space_around_method_call_operator.yml deleted file mode 100644 index bc174a43d77..00000000000 --- a/.rubocop_todo/layout/space_around_method_call_operator.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -# Cop supports --auto-correct. -Layout/SpaceAroundMethodCallOperator: - # Offense count: 35 - # Temporarily disabled due to too many offenses - Enabled: false - Exclude: - - 'app/helpers/badges_helper.rb' - - 'app/services/google_cloud/create_service_accounts_service.rb' - - 'app/services/google_cloud/enable_cloud_run_service.rb' - - 'app/services/google_cloud/generate_pipeline_service.rb' - - 'ee/spec/lib/gitlab/ci/config/entry/dast_configuration_spec.rb' - - 'ee/spec/migrations/geo/set_resync_flag_for_retried_projects_spec.rb' - - 'ee/spec/models/approval_project_rule_spec.rb' - - 'ee/spec/models/integrations/github/status_message_spec.rb' - - 'ee/spec/services/ee/boards/issues/move_service_spec.rb' - - 'ee/spec/services/ee/issues/create_service_spec.rb' - - 'ee/spec/services/geo/repository_base_sync_service_spec.rb' - - 'ee/spec/services/requirements_management/create_requirement_service_spec.rb' - - 'ee/spec/services/requirements_management/update_requirement_service_spec.rb' - - 'spec/graphql/types/base_field_spec.rb' - - 'spec/lib/gitlab/ci/pipeline/chain/command_spec.rb' - - 'spec/lib/gitlab/database/shared_model_spec.rb' - - 'spec/lib/gitlab/diff/highlight_spec.rb' - - 'spec/lib/gitlab/spamcheck/client_spec.rb' - - 'spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb' - - 'spec/models/integrations/chat_message/issue_message_spec.rb' - - 'spec/models/milestone_spec.rb' - - 'spec/presenters/alert_management/alert_presenter_spec.rb' - - 'spec/requests/api/graphql/custom_emoji_query_spec.rb' - - 'spec/tasks/gitlab/db_rake_spec.rb' - - 'spec/workers/concerns/limited_capacity/job_tracker_spec.rb' diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 7cc7ed09682..c074ed50eee 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -cef54e67714844049ec017b38cd6be2fd3db74b8 +0fa08d953e0d5497fe5366836d0ed54b9ff557d8 diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue index 4ff49433749..95ee3a0d90e 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.vue +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue @@ -1,5 +1,6 @@ <script> -import { GlButton, GlEmptyState, GlLoadingIcon, GlModal, GlLink } from '@gitlab/ui'; +import { GlButton, GlEmptyState, GlLoadingIcon, GlModal, GlLink, GlSprintf } from '@gitlab/ui'; +import { helpPagePath } from '~/helpers/help_page_helper'; import { getParameterByName } from '~/lib/utils/url_utility'; import PipelinesTableComponent from '~/pipelines/components/pipelines_list/pipelines_table.vue'; import { PipelineKeyOptions } from '~/pipelines/constants'; @@ -19,6 +20,7 @@ export default { GlLink, GlLoadingIcon, GlModal, + GlSprintf, PipelinesTableComponent, TablePagination, }, @@ -32,6 +34,10 @@ export default { type: String, required: true, }, + emptyStateSvgPath: { + type: String, + required: true, + }, viewType: { type: String, required: false, @@ -83,6 +89,9 @@ export default { shouldRenderErrorState() { return this.hasError && !this.isLoading; }, + shouldRenderEmptyState() { + return this.state.pipelines.length === 0 && !this.shouldRenderErrorState; + }, /** * The "Run pipeline" button can only be rendered when: * - In MR view - we use `canCreatePipelineInTargetProject` for that purpose @@ -185,6 +194,17 @@ export default { }, }, }, + i18n: { + runPipelinePopoverTitle: s__('Pipeline|Run merge request pipeline'), + runPipelinePopoverDescription: s__( + 'Pipeline|To run a merge request pipeline, the jobs in the CI/CD configuration file %{linkStart}must be configured%{linkEnd} to run in merge request pipelines.', + ), + runPipelineText: s__('Pipeline|Run pipeline'), + emptyStateTitle: s__('Pipelines|There are currently no pipelines.'), + }, + mrPipelinesDocsPath: helpPagePath('ci/pipelines/merge_request_pipelines.md', { + anchor: 'prerequisites', + }), }; </script> <template> @@ -203,7 +223,41 @@ export default { s__(`Pipelines|There was an error fetching the pipelines. Try again in a few moments or contact your support team.`) " + data-testid="pipeline-error-empty-state" /> + <template v-else-if="shouldRenderEmptyState"> + <gl-empty-state + :svg-path="emptyStateSvgPath" + :title="$options.i18n.emptyStateTitle" + data-testid="pipeline-empty-state" + > + <template #description> + <gl-sprintf :message="$options.i18n.runPipelinePopoverDescription"> + <template #link="{ content }"> + <gl-link + :href="$options.mrPipelinesDocsPath" + target="_blank" + data-testid="mr-pipelines-docs-link" + >{{ content }}</gl-link + > + </template> + </gl-sprintf> + </template> + + <template #actions> + <div class="gl-vertical-align-middle"> + <gl-button + variant="confirm" + :loading="state.isRunningMergeRequestPipeline" + data-testid="run_pipeline_button" + @click="tryRunPipeline" + > + {{ $options.i18n.runPipelineText }} + </gl-button> + </div> + </template> + </gl-empty-state> + </template> <div v-else-if="shouldRenderTable"> <gl-button @@ -215,7 +269,7 @@ export default { :loading="state.isRunningMergeRequestPipeline" @click="tryRunPipeline" > - {{ s__('Pipeline|Run pipeline') }} + {{ $options.i18n.runPipelineText }} </gl-button> <pipelines-table-component @@ -231,7 +285,7 @@ export default { :loading="state.isRunningMergeRequestPipeline" @click="tryRunPipeline" > - {{ s__('Pipeline|Run pipeline') }} + {{ $options.i18n.runPipelineText }} </gl-button> </div> </template> diff --git a/app/assets/javascripts/pipelines/components/performance_insights_modal.vue b/app/assets/javascripts/pipelines/components/performance_insights_modal.vue index ae6b9186930..fdbf0ca19bc 100644 --- a/app/assets/javascripts/pipelines/components/performance_insights_modal.vue +++ b/app/assets/javascripts/pipelines/components/performance_insights_modal.vue @@ -97,13 +97,16 @@ export default { <gl-loading-icon v-if="$apollo.queries.jobs.loading" size="lg" /> <template v-else> - <gl-alert v-if="showLimitMessage" class="gl-mb-4" :dismissible="false"> - <p>{{ $options.i18n.insightsLimit }}</p> + <gl-alert class="gl-mb-4" :dismissible="false"> + <p v-if="showLimitMessage" data-testid="limit-alert-text"> + {{ $options.i18n.insightsLimit }} + </p> <gl-link href="https://gitlab.com/gitlab-org/gitlab/-/issues/365902" class="gl-mt-5"> {{ $options.i18n.feeback }} </gl-link> </gl-alert> - <div class="gl-display-flex gl-justify-content-space-between gl-mb-7"> + + <div class="gl-display-flex gl-justify-content-space-between gl-mt-2 gl-mb-7"> <gl-card class="gl-w-half gl-mr-7 gl-text-center"> <template #header> <span class="gl-font-weight-bold">{{ $options.i18n.queuedCardHeader }}</span> diff --git a/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js b/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js index c4f7665c91d..e8e49cc652e 100644 --- a/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js +++ b/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js @@ -1,5 +1,6 @@ import Visibility from 'visibilityjs'; -import createFlash from '~/flash'; +import createFlash, { createAlert } from '~/flash'; +import { helpPagePath } from '~/helpers/help_page_helper'; import { historyPushState, buildUrlWithCurrentLocation } from '~/lib/utils/common_utils'; import httpStatusCodes from '~/lib/utils/http_status'; import Poll from '~/lib/utils/poll'; @@ -198,18 +199,20 @@ export default { }) .catch((e) => { const unauthorized = e.response.status === httpStatusCodes.UNAUTHORIZED; - const badRequest = e.response.status === httpStatusCodes.BAD_REQUEST; - let errorMessage = __( 'An error occurred while trying to run a new pipeline for this merge request.', ); - if (unauthorized || badRequest) { + if (unauthorized) { errorMessage = __('You do not have permission to run a pipeline on this branch.'); } - createFlash({ + createAlert({ message: errorMessage, + primaryButton: { + text: __('Learn more'), + link: helpPagePath('ci/pipelines/merge_request_pipelines.md'), + }, }); }) .finally(() => this.store.toggleIsRunningPipeline(false)); diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb index 64738608b60..b52a4cc0ab4 100644 --- a/app/graphql/resolvers/ci/runners_resolver.rb +++ b/app/graphql/resolvers/ci/runners_resolver.rb @@ -36,7 +36,7 @@ module Resolvers required: false, description: 'Sort order of results.' - argument :upgrade_status, ::Types::Ci::RunnerUpgradeStatusTypeEnum, + argument :upgrade_status, ::Types::Ci::RunnerUpgradeStatusEnum, required: false, description: 'Filter by upgrade status.' diff --git a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb b/app/graphql/types/ci/runner_upgrade_status_enum.rb index 8e32eee5e6e..34a931c8f79 100644 --- a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb +++ b/app/graphql/types/ci/runner_upgrade_status_enum.rb @@ -2,8 +2,8 @@ module Types module Ci - class RunnerUpgradeStatusTypeEnum < BaseEnum - graphql_name 'CiRunnerUpgradeStatusType' + class RunnerUpgradeStatusEnum < BaseEnum + graphql_name 'CiRunnerUpgradeStatus' ::Ci::RunnerVersion::STATUS_DESCRIPTIONS.each do |status, description| status_name_src = diff --git a/app/helpers/badges_helper.rb b/app/helpers/badges_helper.rb index 26ebe8a6470..46f0b043770 100644 --- a/app/helpers/badges_helper.rb +++ b/app/helpers/badges_helper.rb @@ -8,13 +8,13 @@ module BadgesHelper success: "badge-success", warning: "badge-warning", danger: "badge-danger" - }.tap { |hash| hash.default = hash.fetch(:muted) } .freeze + }.tap { |hash| hash.default = hash.fetch(:muted) }.freeze SIZE_CLASSES = { sm: "sm", md: "md", lg: "lg" - }.tap { |hash| hash.default = hash.fetch(:md) } .freeze + }.tap { |hash| hash.default = hash.fetch(:md) }.freeze GL_BADGE_CLASSES = %w[gl-badge badge badge-pill].freeze diff --git a/app/models/concerns/database_event_tracking.rb b/app/models/concerns/database_event_tracking.rb new file mode 100644 index 00000000000..04cefc7acf9 --- /dev/null +++ b/app/models/concerns/database_event_tracking.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module DatabaseEventTracking + extend ActiveSupport::Concern + + included do + after_create_commit :publish_database_create_event + after_destroy_commit :publish_database_destroy_event + after_update_commit :publish_database_update_event + end + + def publish_database_create_event + publish_database_event('create') + end + + def publish_database_destroy_event + publish_database_event('destroy') + end + + def publish_database_update_event + publish_database_event('update') + end + + def publish_database_event(name) + return unless Feature.enabled?(:product_intelligence_database_event_tracking) + + # Gitlab::Tracking#event is triggering Snowplow event + # Snowplow events are sent with usage of + # https://snowplow.github.io/snowplow-ruby-tracker/SnowplowTracker/AsyncEmitter.html + # that reports data asynchronously and does not impact performance nor carries a risk of + # rollback in case of error + + Gitlab::Tracking.event( + self.class.to_s, + "database_event_#{name}", + label: self.class.table_name, + namespace: try(:group) || try(:namespace), + property: name, + **filtered_record_attributes + ) + rescue StandardError => err + # this rescue should be a dead code due to utilization of AsyncEmitter, however + # since this concern is expected to be included in every model, it is better to + # prevent against any unexpected outcome + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(err) + end + + def filtered_record_attributes + attributes.select do |key, _value| + self.class::SNOWPLOW_ATTRIBUTES.include?(key) + end + end +end diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index 87e222754e5..4a79c7d5cbb 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -32,7 +32,7 @@ = tab_link_for @merge_request, :commits do = _("Commits") = gl_badge_tag @commits_count, { size: :sm } - - if @number_of_pipelines.nonzero? + - if @project.builds_enabled? = render "projects/merge_requests/tabs/tab", name: "pipelines", class: "pipelines-tab" do = tab_link_for @merge_request, :pipelines do = _("Pipelines") @@ -80,7 +80,7 @@ = render "projects/merge_requests/tabs/pane", name: "commits", id: "commits", class: "commits" do -# This tab is always loaded via AJAX = render "projects/merge_requests/tabs/pane", name: "pipelines", id: "pipelines", class: "pipelines" do - - if @number_of_pipelines.nonzero? + - if @project.builds_enabled? = render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_project_merge_request_path(@project, @merge_request) - params = request.query_parameters.merge(diff_head: true) = render "projects/merge_requests/tabs/pane", name: "diffs", id: "js-diffs-app", class: "diffs", data: diffs_tab_pane_data(@project, @merge_request, params) diff --git a/config/feature_flags/development/product_intelligence_database_event_tracking.yml b/config/feature_flags/development/product_intelligence_database_event_tracking.yml new file mode 100644 index 00000000000..83a65398e87 --- /dev/null +++ b/config/feature_flags/development/product_intelligence_database_event_tracking.yml @@ -0,0 +1,9 @@ +--- +name: product_intelligence_database_event_tracking +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92079 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/368976 +rollout_issue_url: +milestone: '15.3' +type: development +group: group::product intelligence +default_enabled: false diff --git a/db/post_migrate/20220715185348_add_index_on_security_findings_id_and_partition_number.rb b/db/post_migrate/20220715185348_add_index_on_security_findings_id_and_partition_number.rb new file mode 100644 index 00000000000..e867ef81381 --- /dev/null +++ b/db/post_migrate/20220715185348_add_index_on_security_findings_id_and_partition_number.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddIndexOnSecurityFindingsIdAndPartitionNumber < Gitlab::Database::Migration[2.0] + INDEX_NAME = 'security_findings_partitioned_pkey' + + disable_ddl_transaction! + + def up + add_concurrent_index :security_findings, [:id, :partition_number], unique: true, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :security_findings, INDEX_NAME + end +end diff --git a/db/post_migrate/20220715185436_add_index_on_security_findings_unique_columns.rb b/db/post_migrate/20220715185436_add_index_on_security_findings_unique_columns.rb new file mode 100644 index 00000000000..33b069a27d4 --- /dev/null +++ b/db/post_migrate/20220715185436_add_index_on_security_findings_unique_columns.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddIndexOnSecurityFindingsUniqueColumns < Gitlab::Database::Migration[2.0] + INDEX_NAME = 'index_security_findings_on_unique_columns' + + disable_ddl_transaction! + + def up + add_concurrent_index :security_findings, [:uuid, :scan_id, :partition_number], unique: true, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :security_findings, INDEX_NAME + end +end diff --git a/db/post_migrate/20220715190612_drop_index_on_security_findings_uuid_and_scan_id.rb b/db/post_migrate/20220715190612_drop_index_on_security_findings_uuid_and_scan_id.rb new file mode 100644 index 00000000000..a8a9bab2c84 --- /dev/null +++ b/db/post_migrate/20220715190612_drop_index_on_security_findings_uuid_and_scan_id.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class DropIndexOnSecurityFindingsUuidAndScanId < Gitlab::Database::Migration[2.0] + INDEX_NAME = 'index_security_findings_on_uuid_and_scan_id' + + disable_ddl_transaction! + + def up + remove_concurrent_index_by_name :security_findings, INDEX_NAME + end + + def down + add_concurrent_index :security_findings, [:uuid, :scan_id], unique: true, name: INDEX_NAME + end +end diff --git a/db/post_migrate/20220715191629_change_primary_key_of_security_findings_table.rb b/db/post_migrate/20220715191629_change_primary_key_of_security_findings_table.rb new file mode 100644 index 00000000000..c2859c68c52 --- /dev/null +++ b/db/post_migrate/20220715191629_change_primary_key_of_security_findings_table.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class ChangePrimaryKeyOfSecurityFindingsTable < Gitlab::Database::Migration[2.0] + enable_lock_retries! + + def up + execute(<<~SQL) + ALTER TABLE security_findings DROP CONSTRAINT security_findings_pkey; + SQL + + execute(<<~SQL) + ALTER TABLE security_findings ADD CONSTRAINT security_findings_pkey PRIMARY KEY USING index security_findings_partitioned_pkey; + SQL + end + + def down + execute(<<~SQL) + ALTER TABLE security_findings DROP CONSTRAINT security_findings_pkey; + SQL + + execute(<<~SQL) + ALTER TABLE security_findings ADD CONSTRAINT security_findings_pkey PRIMARY KEY (id); + SQL + + execute(<<~SQL) + CREATE UNIQUE INDEX security_findings_partitioned_pkey ON security_findings USING btree(id, partition_number); + SQL + end +end diff --git a/db/schema_migrations/20220715185348 b/db/schema_migrations/20220715185348 new file mode 100644 index 00000000000..6df20d578f0 --- /dev/null +++ b/db/schema_migrations/20220715185348 @@ -0,0 +1 @@ +5a8e178601b1b88bef0186269bc62f8e3b10eacb0fe8a9a11e322c244883cfde
\ No newline at end of file diff --git a/db/schema_migrations/20220715185436 b/db/schema_migrations/20220715185436 new file mode 100644 index 00000000000..31f9a069d31 --- /dev/null +++ b/db/schema_migrations/20220715185436 @@ -0,0 +1 @@ +673e77eb5ffa49ab70088a7a43119c5f388d199e69504994c8c0a2a867ee1da3
\ No newline at end of file diff --git a/db/schema_migrations/20220715190612 b/db/schema_migrations/20220715190612 new file mode 100644 index 00000000000..ffafb037b43 --- /dev/null +++ b/db/schema_migrations/20220715190612 @@ -0,0 +1 @@ +bbb07db2554d2b1c7083341efcdc065a3a25ba4b042b0b3ea3cb26ec25e1e023
\ No newline at end of file diff --git a/db/schema_migrations/20220715191629 b/db/schema_migrations/20220715191629 new file mode 100644 index 00000000000..88874ec93d3 --- /dev/null +++ b/db/schema_migrations/20220715191629 @@ -0,0 +1 @@ +e300a6144e63f734e41b3a3ad40089dea5764ea2636ea11f5782fe86b6574229
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 5d349c4450b..301b5b50871 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -25796,7 +25796,7 @@ ALTER TABLE ONLY scim_oauth_access_tokens ADD CONSTRAINT scim_oauth_access_tokens_pkey PRIMARY KEY (id); ALTER TABLE ONLY security_findings - ADD CONSTRAINT security_findings_pkey PRIMARY KEY (id); + ADD CONSTRAINT security_findings_pkey PRIMARY KEY (id, partition_number); ALTER TABLE ONLY security_orchestration_policy_configurations ADD CONSTRAINT security_orchestration_policy_configurations_pkey PRIMARY KEY (id); @@ -29692,7 +29692,7 @@ CREATE INDEX index_security_findings_on_scanner_id ON security_findings USING bt CREATE INDEX index_security_findings_on_severity ON security_findings USING btree (severity); -CREATE UNIQUE INDEX index_security_findings_on_uuid_and_scan_id ON security_findings USING btree (uuid, scan_id); +CREATE UNIQUE INDEX index_security_findings_on_unique_columns ON security_findings USING btree (uuid, scan_id, partition_number); CREATE INDEX index_security_scans_on_created_at ON security_scans USING btree (created_at); diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 7ee604207a0..00c329253e5 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -387,7 +387,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="queryrunnersstatus"></a>`status` | [`CiRunnerStatus`](#cirunnerstatus) | Filter runners by status. | | <a id="queryrunnerstaglist"></a>`tagList` | [`[String!]`](#string) | Filter by tags associated with the runner (comma-separated or array). | | <a id="queryrunnerstype"></a>`type` | [`CiRunnerType`](#cirunnertype) | Filter runners by type. | -| <a id="queryrunnersupgradestatus"></a>`upgradeStatus` | [`CiRunnerUpgradeStatusType`](#cirunnerupgradestatustype) | Filter by upgrade status. | +| <a id="queryrunnersupgradestatus"></a>`upgradeStatus` | [`CiRunnerUpgradeStatus`](#cirunnerupgradestatus) | Filter by upgrade status. | ### `Query.snippets` @@ -10244,7 +10244,7 @@ CI/CD variables for a project. | <a id="cirunnershortsha"></a>`shortSha` | [`String`](#string) | First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID. | | <a id="cirunnertaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. | | <a id="cirunnertokenexpiresat"></a>`tokenExpiresAt` | [`Time`](#time) | Runner token expiration time. | -| <a id="cirunnerupgradestatus"></a>`upgradeStatus` **{warning-solid}** | [`CiRunnerUpgradeStatusType`](#cirunnerupgradestatustype) | **Introduced** in 14.10. This feature is in Alpha. It can be changed or removed at any time. | +| <a id="cirunnerupgradestatus"></a>`upgradeStatus` **{warning-solid}** | [`CiRunnerUpgradeStatus`](#cirunnerupgradestatus) | **Introduced** in 14.10. This feature is in Alpha. It can be changed or removed at any time. | | <a id="cirunneruserpermissions"></a>`userPermissions` | [`RunnerPermissions!`](#runnerpermissions) | Permissions for the current user on the resource. | | <a id="cirunnerversion"></a>`version` | [`String`](#string) | Version of the runner. | @@ -12681,7 +12681,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="grouprunnersstatus"></a>`status` | [`CiRunnerStatus`](#cirunnerstatus) | Filter runners by status. | | <a id="grouprunnerstaglist"></a>`tagList` | [`[String!]`](#string) | Filter by tags associated with the runner (comma-separated or array). | | <a id="grouprunnerstype"></a>`type` | [`CiRunnerType`](#cirunnertype) | Filter runners by type. | -| <a id="grouprunnersupgradestatus"></a>`upgradeStatus` | [`CiRunnerUpgradeStatusType`](#cirunnerupgradestatustype) | Filter by upgrade status. | +| <a id="grouprunnersupgradestatus"></a>`upgradeStatus` | [`CiRunnerUpgradeStatus`](#cirunnerupgradestatus) | Filter by upgrade status. | ##### `Group.scanExecutionPolicies` @@ -19124,14 +19124,14 @@ Values for sorting runners. | <a id="cirunnertypeinstance_type"></a>`INSTANCE_TYPE` | A runner that is instance type. | | <a id="cirunnertypeproject_type"></a>`PROJECT_TYPE` | A runner that is project type. | -### `CiRunnerUpgradeStatusType` +### `CiRunnerUpgradeStatus` | Value | Description | | ----- | ----------- | -| <a id="cirunnerupgradestatustypeavailable"></a>`AVAILABLE` | Upgrade is available for the runner. | -| <a id="cirunnerupgradestatustypeinvalid"></a>`INVALID` | Runner version is not valid. | -| <a id="cirunnerupgradestatustypenot_available"></a>`NOT_AVAILABLE` | Upgrade is not available for the runner. | -| <a id="cirunnerupgradestatustyperecommended"></a>`RECOMMENDED` | Upgrade is available and recommended for the runner. | +| <a id="cirunnerupgradestatusavailable"></a>`AVAILABLE` | Upgrade is available for the runner. | +| <a id="cirunnerupgradestatusinvalid"></a>`INVALID` | Runner version is not valid. | +| <a id="cirunnerupgradestatusnot_available"></a>`NOT_AVAILABLE` | Upgrade is not available for the runner. | +| <a id="cirunnerupgradestatusrecommended"></a>`RECOMMENDED` | Upgrade is available and recommended for the runner. | ### `CiVariableType` diff --git a/doc/development/fips_compliance.md b/doc/development/fips_compliance.md index d1c2520b496..44a3c0cb45d 100644 --- a/doc/development/fips_compliance.md +++ b/doc/development/fips_compliance.md @@ -40,15 +40,15 @@ when FIPS mode is enabled. | Ubuntu 20.04 Libgcrypt Cryptographic Module | [3902](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3902) | EC2 instances | `gpg`, `sshd` | | Amazon Linux 2 Kernel Crypto API Cryptographic Module | [3709](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3709) | EKS nodes | Linux kernel | | Amazon Linux 2 OpenSSL Cryptographic Module | [3553](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3553) | EKS nodes | NGINX | -| RedHat Enterprise Linux 8 OpenSSL Cryptographic Module | [3852](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3852) | EKS nodes | UBI containers: Workhorse, Pages, Container Registry, Rails (Puma/Sidekiq), Security Analyzers | +| RedHat Enterprise Linux 8 OpenSSL Cryptographic Module | [4271](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4271) | EKS nodes | UBI containers: Workhorse, Pages, Container Registry, Rails (Puma/Sidekiq), Security Analyzers | | RedHat Enterprise Linux 8 Libgcrypt Cryptographic Module | [3784](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3784) | EKS nodes | UBI containers: GitLab Shell, `gpg` | ### Supported Operating Systems -The supported hybrid environments are: +The supported hybrid platforms are: -- Omnibus: Ubuntu 20.04 FIPS -- EKS: Amazon Linux 2 +- Omnibus GitLab: Ubuntu 20.04 LTS +- Cloud Native GitLab: Amazon Linux 2 (EKS) ### Unsupported features in FIPS mode diff --git a/doc/integration/jenkins_deprecated.md b/doc/integration/jenkins_deprecated.md index 57219b18047..5010545b73a 100644 --- a/doc/integration/jenkins_deprecated.md +++ b/doc/integration/jenkins_deprecated.md @@ -2,62 +2,12 @@ stage: Ecosystem group: Integrations info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +remove_date: '2022-10-29' +redirect_to: 'jenkins.md' --- -# Jenkins CI (deprecated) service **(FREE)** +# Jenkins CI service (removed) **(FREE)** -NOTE: -In GitLab 8.3, Jenkins integration using the -[GitLab Hook Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Hook+Plugin) -was deprecated in favor of the -[GitLab Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Plugin). -Please use documentation for the new [Jenkins CI service](jenkins.md). - -NOTE: -This service was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1600) in GitLab 13.0 - -Integration includes: - -- Trigger Jenkins build after push to repository -- Show build status on Merge request page - -Requirements: - -- [Jenkins GitLab Hook plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Hook+Plugin) -- Git clone access for Jenkins from GitLab repository (via SSH key) - -## Jenkins - -1. Install [GitLab Hook plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Hook+Plugin) -1. Set up Jenkins project - -![screen](img/jenkins_project.png) - -## GitLab - -In GitLab, perform the following steps. - -### Read access to repository - -Jenkins needs read access to the GitLab repository. We already specified a -private key to use in Jenkins, now we must add a public one to the GitLab -project. For that case we need a Deploy key. Read the documentation on -[how to set up a Deploy key](../user/project/deploy_keys/index.md). - -### Jenkins service - -Now navigate to GitLab services page and activate Jenkins - -![screen](img/jenkins_gitlab_service.png) - -Done! When you push to GitLab, it creates a build for Jenkins. You can view the -merge request build status with a link to the Jenkins build. - -### Multi-project Configuration - -The GitLab Hook plugin in Jenkins supports the automatic creation of a project -for each feature branch. After configuration GitLab triggers feature branch -builds and a corresponding project is created in Jenkins. - -Configure the GitLab Hook plugin in Jenkins. Go to 'Manage Jenkins' and then -'Configure System'. Find the 'GitLab Web Hook' section and configure as shown below. +This feature was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1600) +in GitLab 13.0. +Use the [Jenkins integration](jenkins.md) instead. diff --git a/lib/gitlab/graphql/type_name_deprecations.rb b/lib/gitlab/graphql/type_name_deprecations.rb index 4c75a0e7bd3..c27ad1d54f5 100644 --- a/lib/gitlab/graphql/type_name_deprecations.rb +++ b/lib/gitlab/graphql/type_name_deprecations.rb @@ -11,7 +11,11 @@ module Gitlab # old_name: 'CiRunnerUpgradeStatusType', new_name: 'CiRunnerUpgradeStatus', milestone: '15.3' # ) # ].freeze - DEPRECATIONS = [].freeze + DEPRECATIONS = [ + Gitlab::Graphql::DeprecationsBase::NameDeprecation.new( + old_name: 'CiRunnerUpgradeStatusType', new_name: 'CiRunnerUpgradeStatus', milestone: '15.3' + ) + ].freeze def self.map_graphql_name(name) name diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 193a8fffb77..a7a28880e63 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -966,6 +966,16 @@ msgid_plural "%{securityScanner} results are not available because a pipeline ha msgstr[0] "" msgstr[1] "" +msgid "%{selectedLabelsCount} label" +msgid_plural "%{selectedLabelsCount} labels" +msgstr[0] "" +msgstr[1] "" + +msgid "%{selectedProjectsCount} project" +msgid_plural "%{selectedProjectsCount} projects" +msgstr[0] "" +msgstr[1] "" + msgid "%{size} %{unit}" msgstr "" @@ -29047,6 +29057,9 @@ msgstr "" msgid "Pipeline|Run for branch name or tag" msgstr "" +msgid "Pipeline|Run merge request pipeline" +msgstr "" + msgid "Pipeline|Run pipeline" msgstr "" @@ -29104,6 +29117,9 @@ msgstr "" msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch." msgstr "" +msgid "Pipeline|To run a merge request pipeline, the jobs in the CI/CD configuration file %{linkStart}must be configured%{linkEnd} to run in merge request pipelines." +msgstr "" + msgid "Pipeline|Trigger author" msgstr "" @@ -36246,10 +36262,10 @@ msgstr "" msgid "Showing version #%{versionNumber}" msgstr "" -msgid "Shows issues and %{labels_count} label for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019" +msgid "Shows issues and 1 label for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019" msgstr "" -msgid "Shows issues and %{labels_count} labels for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019" +msgid "Shows issues for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019" msgstr "" msgid "Side-by-side" @@ -42650,11 +42666,6 @@ msgstr "" msgid "ValueStreamAnalytics|%{stageCount}+ items" msgstr "" -msgid "ValueStreamAnalytics|%{subjectFilterText} and %{selectedLabelsCount} label" -msgid_plural "ValueStreamAnalytics|%{subjectFilterText} and %{selectedLabelsCount} labels" -msgstr[0] "" -msgstr[1] "" - msgid "ValueStreamAnalytics|%{value}M" msgstr "" @@ -42709,10 +42720,16 @@ msgstr "" msgid "ValueStreamAnalytics|Percentage of deployments that cause an incident in production." msgstr "" -msgid "ValueStreamAnalytics|Shows %{selectedFiltersDescription} for group '%{groupName}' and %{selectedProjectCount} projects from %{createdAfter} to %{createdBefore}" +msgid "ValueStreamAnalytics|Shows %{selectedSubjectFilterText} and %{labelsCount} for group '%{groupName}' and %{projectsCount} from %{createdAfter} to %{createdBefore}" +msgstr "" + +msgid "ValueStreamAnalytics|Shows %{selectedSubjectFilterText} and %{labelsCount} for group '%{groupName}' from %{createdAfter} to %{createdBefore}" +msgstr "" + +msgid "ValueStreamAnalytics|Shows %{selectedSubjectFilterText} for group '%{groupName}' and %{projectsCount} from %{createdAfter} to %{createdBefore}" msgstr "" -msgid "ValueStreamAnalytics|Shows %{selectedFiltersDescription} for group '%{groupName}' from %{createdAfter} to %{createdBefore}" +msgid "ValueStreamAnalytics|Shows %{selectedSubjectFilterText} for group '%{groupName}' from %{createdAfter} to %{createdBefore}" msgstr "" msgid "ValueStreamAnalytics|Tasks by type" diff --git a/package.json b/package.json index 92f7e48d668..4ba8caee76e 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "@babel/preset-env": "^7.18.2", "@gitlab/at.js": "1.5.7", "@gitlab/favicon-overlay": "2.0.0", - "@gitlab/svgs": "2.30.0", - "@gitlab/ui": "42.24.0", + "@gitlab/svgs": "2.32.0", + "@gitlab/ui": "42.25.0", "@gitlab/visual-review-tools": "1.7.3", "@rails/actioncable": "6.1.4-7", "@rails/ujs": "6.1.4-7", diff --git a/qa/qa/service/praefect_manager.rb b/qa/qa/service/praefect_manager.rb index 8563c3656a8..eab41572cda 100644 --- a/qa/qa/service/praefect_manager.rb +++ b/qa/qa/service/praefect_manager.rb @@ -30,7 +30,7 @@ module QA wait_until_shell_command_matches(dataloss_command, /Outdated repositories/) end - def replicated?(project_id) + def replicated?(project_id, project_name_prefix = 'gitaly_cluster') Support::Retrier.retry_until(raise_on_failure: false) do replicas = wait_until_shell_command(%(docker exec #{@gitlab} bash -c 'gitlab-rake "gitlab:praefect:replicas[#{project_id}]"')) do |line| QA::Runtime::Logger.debug(line.chomp) @@ -40,7 +40,7 @@ module QA # ---------------------------------------------------------------------------------------------------------------------------------------------------------------- # gitaly_cluster-3aff1f2bd14e6c98 | 23c4422629234d62b62adacafd0a33a8364e8619 | 23c4422629234d62b62adacafd0a33a8364e8619 | 23c4422629234d62b62adacafd0a33a8364e8619 # - break line if line.start_with?('gitaly_cluster') + break line if line.start_with?(project_name_prefix) break nil if line.include?('Something went wrong when getting replicas') end next false unless replicas diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb index a68155ef0b2..fabcc3a862c 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb +++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb @@ -67,7 +67,7 @@ module QA project.initialize_with_readme = true end - expect(praefect_manager.replicated?(new_project.id)).to be true + expect(praefect_manager.replicated?(new_project.id, new_project.name)).to be true end end end diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb index 16b1de0393f..11e542916f9 100644 --- a/spec/features/merge_request/user_sees_pipelines_spec.rb +++ b/spec/features/merge_request/user_sees_pipelines_spec.rb @@ -78,9 +78,18 @@ RSpec.describe 'Merge request > User sees pipelines', :js do it 'user visits merge request page' do page.within('.merge-request-tabs') do - expect(page).to have_no_link('Pipelines') + expect(page).to have_link('Pipelines') end end + + it 'shows empty state with run pipeline button' do + page.within('.merge-request-tabs') do + click_link('Pipelines') + end + + expect(page).to have_content('There are currently no pipelines.') + expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') + end end end diff --git a/spec/frontend/commit/pipelines/pipelines_table_spec.js b/spec/frontend/commit/pipelines/pipelines_table_spec.js index 9b01af1e585..71ee12cf02d 100644 --- a/spec/frontend/commit/pipelines/pipelines_table_spec.js +++ b/spec/frontend/commit/pipelines/pipelines_table_spec.js @@ -1,4 +1,4 @@ -import { GlEmptyState, GlLoadingIcon, GlModal, GlTableLite } from '@gitlab/ui'; +import { GlLoadingIcon, GlModal, GlTableLite } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { nextTick } from 'vue'; @@ -8,7 +8,7 @@ import waitForPromises from 'helpers/wait_for_promises'; import Api from '~/api'; import PipelinesTable from '~/commit/pipelines/pipelines_table.vue'; import httpStatusCodes from '~/lib/utils/http_status'; -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; import { TOAST_MESSAGE } from '~/pipelines/constants'; import axios from '~/lib/utils/axios_utils'; @@ -26,10 +26,12 @@ describe('Pipelines table in Commits and Merge requests', () => { const findRunPipelineBtn = () => wrapper.findByTestId('run_pipeline_button'); const findRunPipelineBtnMobile = () => wrapper.findByTestId('run_pipeline_button_mobile'); const findLoadingState = () => wrapper.findComponent(GlLoadingIcon); - const findEmptyState = () => wrapper.findComponent(GlEmptyState); + const findErrorEmptyState = () => wrapper.findByTestId('pipeline-error-empty-state'); + const findEmptyState = () => wrapper.findByTestId('pipeline-empty-state'); const findTable = () => wrapper.findComponent(GlTableLite); const findTableRows = () => wrapper.findAllByTestId('pipeline-table-row'); const findModal = () => wrapper.findComponent(GlModal); + const findMrPipelinesDocsLink = () => wrapper.findByTestId('mr-pipelines-docs-link'); const createComponent = (props = {}) => { wrapper = extendedWrapper( @@ -73,7 +75,18 @@ describe('Pipelines table in Commits and Merge requests', () => { it('should render the empty state', () => { expect(findTableRows()).toHaveLength(0); expect(findLoadingState().exists()).toBe(false); - expect(findEmptyState().exists()).toBe(false); + expect(findErrorEmptyState().exists()).toBe(false); + expect(findEmptyState().exists()).toBe(true); + }); + + it('should render correct empty state content', () => { + expect(findRunPipelineBtn().exists()).toBe(true); + expect(findMrPipelinesDocsLink().attributes('href')).toBe( + '/help/ci/pipelines/merge_request_pipelines.md#prerequisites', + ); + expect(findEmptyState().text()).toContain( + 'To run a merge request pipeline, the jobs in the CI/CD configuration file must be configured to run in merge request pipelines.', + ); }); }); @@ -90,7 +103,7 @@ describe('Pipelines table in Commits and Merge requests', () => { expect(findTable().exists()).toBe(true); expect(findTableRows()).toHaveLength(1); expect(findLoadingState().exists()).toBe(false); - expect(findEmptyState().exists()).toBe(false); + expect(findErrorEmptyState().exists()).toBe(false); }); describe('with pagination', () => { @@ -226,12 +239,14 @@ describe('Pipelines table in Commits and Merge requests', () => { describe('failure', () => { const permissionsMsg = 'You do not have permission to run a pipeline on this branch.'; + const defaultMsg = + 'An error occurred while trying to run a new pipeline for this merge request.'; it.each` status | message - ${httpStatusCodes.BAD_REQUEST} | ${permissionsMsg} + ${httpStatusCodes.BAD_REQUEST} | ${defaultMsg} ${httpStatusCodes.UNAUTHORIZED} | ${permissionsMsg} - ${httpStatusCodes.INTERNAL_SERVER_ERROR} | ${'An error occurred while trying to run a new pipeline for this merge request.'} + ${httpStatusCodes.INTERNAL_SERVER_ERROR} | ${defaultMsg} `('displays permissions error message', async ({ status, message }) => { const response = { response: { status } }; @@ -243,7 +258,13 @@ describe('Pipelines table in Commits and Merge requests', () => { await waitForPromises(); - expect(createFlash).toHaveBeenCalledWith({ message }); + expect(createAlert).toHaveBeenCalledWith({ + message, + primaryButton: { + text: 'Learn more', + link: '/help/ci/pipelines/merge_request_pipelines.md', + }, + }); }); }); }); @@ -293,7 +314,7 @@ describe('Pipelines table in Commits and Merge requests', () => { }); it('should render error state', () => { - expect(findEmptyState().text()).toBe( + expect(findErrorEmptyState().text()).toBe( 'There was an error fetching the pipelines. Try again in a few moments or contact your support team.', ); }); diff --git a/spec/frontend/pipelines/performance_insights_modal_spec.js b/spec/frontend/pipelines/performance_insights_modal_spec.js index b745eb1d78e..8c802be7718 100644 --- a/spec/frontend/pipelines/performance_insights_modal_spec.js +++ b/spec/frontend/pipelines/performance_insights_modal_spec.js @@ -20,6 +20,7 @@ describe('Performance insights modal', () => { const findModal = () => wrapper.findComponent(GlModal); const findAlert = () => wrapper.findComponent(GlAlert); const findLink = () => wrapper.findComponent(GlLink); + const findLimitText = () => wrapper.findByTestId('limit-alert-text'); const findQueuedCardData = () => wrapper.findByTestId('insights-queued-card-data'); const findQueuedCardLink = () => wrapper.findByTestId('insights-queued-card-link'); const findExecutedCardData = () => wrapper.findByTestId('insights-executed-card-data'); @@ -62,8 +63,19 @@ describe('Performance insights modal', () => { expect(findModal().exists()).toBe(true); }); - it('does not dispaly alert', () => { - expect(findAlert().exists()).toBe(false); + it('displays alert', () => { + expect(findAlert().exists()).toBe(true); + }); + + it('displays feedback issue link', () => { + expect(findLink().text()).toBe('Feedback issue'); + expect(findLink().attributes('href')).toBe( + 'https://gitlab.com/gitlab-org/gitlab/-/issues/365902', + ); + }); + + it('does not display limit text', () => { + expect(findLimitText().exists()).toBe(false); }); describe('queued duration card', () => { @@ -107,16 +119,13 @@ describe('Performance insights modal', () => { }); }); - describe('limit alert', () => { - it('displays limit alert when there is a next page', async () => { + describe('with next page', () => { + it('displays limit text when there is a next page', async () => { createComponent([[getPerformanceInsights, getPerformanceInsightsNextPageHandler]]); await waitForPromises(); - expect(findAlert().exists()).toBe(true); - expect(findLink().attributes('href')).toBe( - 'https://gitlab.com/gitlab-org/gitlab/-/issues/365902', - ); + expect(findLimitText().exists()).toBe(true); }); }); }); diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb index 439678e7e16..a3efc60ff5b 100644 --- a/spec/graphql/types/base_field_spec.rb +++ b/spec/graphql/types/base_field_spec.rb @@ -299,7 +299,7 @@ RSpec.describe Types::BaseField do end it 'returns the correct availability in the description' do - expect(field.description). to eq expected_description + expect(field.description).to eq expected_description end end end diff --git a/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb index 03c784dcbe7..ef378f3fc5a 100644 --- a/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb +++ b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb @@ -2,13 +2,13 @@ require 'spec_helper' -RSpec.describe Types::Ci::RunnerUpgradeStatusTypeEnum do +RSpec.describe Types::Ci::RunnerUpgradeStatusEnum do let(:model_only_enum_values) { %w[not_processed] } let(:expected_graphql_source_values) do Ci::RunnerVersion.statuses.keys - model_only_enum_values end - specify { expect(described_class.graphql_name).to eq('CiRunnerUpgradeStatusType') } + specify { expect(described_class.graphql_name).to eq('CiRunnerUpgradeStatus') } it 'exposes all upgrade status values except not_processed' do expect(described_class.values.keys).to match_array( diff --git a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb index 0d78ce3440a..de43e759193 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb @@ -282,7 +282,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Command do subject { command.ambiguous_ref? } context 'when ref is not ambiguous' do - it { is_expected. to eq(false) } + it { is_expected.to eq(false) } end context 'when ref is ambiguous' do @@ -291,7 +291,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Command do project.repository.add_branch(project.creator, 'ref', 'master') end - it { is_expected. to eq(true) } + it { is_expected.to eq(true) } end end diff --git a/spec/lib/gitlab/database/shared_model_spec.rb b/spec/lib/gitlab/database/shared_model_spec.rb index c88edc17817..7e0ba3397d1 100644 --- a/spec/lib/gitlab/database/shared_model_spec.rb +++ b/spec/lib/gitlab/database/shared_model_spec.rb @@ -106,7 +106,7 @@ RSpec.describe Gitlab::Database::SharedModel do shared_model = shared_model_class.new - expect(shared_model.connection_db_config). to eq(described_class.connection_db_config) + expect(shared_model.connection_db_config).to eq(described_class.connection_db_config) end end end diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb index 624160d2f48..c378ecb8134 100644 --- a/spec/lib/gitlab/diff/highlight_spec.rb +++ b/spec/lib/gitlab/diff/highlight_spec.rb @@ -117,7 +117,7 @@ RSpec.describe Gitlab::Diff::Highlight do it 'reports to Sentry if configured' do expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).and_call_original - expect { subject }. to raise_exception(RangeError) + expect { subject }.to raise_exception(RangeError) end end diff --git a/spec/lib/gitlab/spamcheck/client_spec.rb b/spec/lib/gitlab/spamcheck/client_spec.rb index a6e7665569c..bb0b542b4f5 100644 --- a/spec/lib/gitlab/spamcheck/client_spec.rb +++ b/spec/lib/gitlab/spamcheck/client_spec.rb @@ -97,7 +97,7 @@ RSpec.describe Gitlab::Spamcheck::Client do context: cxt) expect(issue_pb.title).to eq issue.title expect(issue_pb.description).to eq issue.description - expect(issue_pb.user_in_project). to be false + expect(issue_pb.user_in_project).to be false expect(issue_pb.project.project_id).to eq issue.project_id expect(issue_pb.created_at).to eq timestamp_to_protobuf_timestamp(issue.created_at) expect(issue_pb.updated_at).to eq timestamp_to_protobuf_timestamp(issue.updated_at) diff --git a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb index 3478305bbad..a23f9995875 100644 --- a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb +++ b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb @@ -47,6 +47,6 @@ RSpec.describe RemoveDanglingRunningBuilds, :suppress_gitlab_schemas_validate_co migrate! expect(running_metadata.reload).to be_present - expect { failed_metadata.reload } .to raise_error(ActiveRecord::RecordNotFound) + expect { failed_metadata.reload }.to raise_error(ActiveRecord::RecordNotFound) end end diff --git a/spec/models/concerns/database_event_tracking_spec.rb b/spec/models/concerns/database_event_tracking_spec.rb new file mode 100644 index 00000000000..79be8654498 --- /dev/null +++ b/spec/models/concerns/database_event_tracking_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe DatabaseEventTracking, :snowplow do + let(:test_class) do + Class.new(ActiveRecord::Base) do + include DatabaseEventTracking + + self.table_name = 'application_setting_terms' + + self::SNOWPLOW_ATTRIBUTES = %w[id].freeze # rubocop:disable Rspec/LeakyConstantDeclaration + end + end + + subject(:create_test_class_record) { test_class.create!(id: 1, terms: "") } + + context 'if event emmiter failed' do + before do + allow(Gitlab::Tracking).to receive(:event).and_raise(StandardError) # rubocop:disable Rspec/ExpectGitlabTracking + end + + it 'tracks the exception' do + expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception) + + create_test_class_record + end + end + + context 'if product_intelligence_database_event_tracking FF is off' do + before do + stub_feature_flags(product_intelligence_database_event_tracking: false) + end + + it 'does not track the event' do + create_test_class_record + + expect_no_snowplow_event + end + end + + describe 'event tracking' do + let(:category) { test_class.to_s } + let(:event) { 'database_event' } + + it 'when created' do + create_test_class_record + + expect_snowplow_event(category: category, action: "#{event}_create", label: 'application_setting_terms', + property: 'create', namespace: nil, "id" => 1) + end + + it 'when updated' do + create_test_class_record + test_class.first.update!(id: 3) + + expect_snowplow_event(category: category, action: "#{event}_update", label: 'application_setting_terms', + property: 'update', namespace: nil, "id" => 3) + end + + it 'when destroyed' do + create_test_class_record + test_class.first.destroy! + + expect_snowplow_event(category: category, action: "#{event}_destroy", label: 'application_setting_terms', + property: 'destroy', namespace: nil, "id" => 1) + end + end +end diff --git a/spec/models/integrations/chat_message/issue_message_spec.rb b/spec/models/integrations/chat_message/issue_message_spec.rb index 7026a314b78..4a86322cdaf 100644 --- a/spec/models/integrations/chat_message/issue_message_spec.rb +++ b/spec/models/integrations/chat_message/issue_message_spec.rb @@ -65,7 +65,7 @@ RSpec.describe Integrations::ChatMessage::IssueMessage do end it 'returns a message regarding closing of issues' do - expect(subject.pretext). to eq( + expect(subject.pretext).to eq( '[<http://somewhere.com|project_name>] Issue <http://url.com|#100 Issue title> closed by Test User (test.user)') expect(subject.attachments).to be_empty end @@ -111,7 +111,7 @@ RSpec.describe Integrations::ChatMessage::IssueMessage do end it 'returns a message regarding closing of issues' do - expect(subject.pretext). to eq( + expect(subject.pretext).to eq( '[[project_name](http://somewhere.com)] Issue [#100 Issue title](http://url.com) closed by Test User (test.user)') expect(subject.attachments).to be_empty expect(subject.activity).to eq({ diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 72a57b6076a..af1383b68bf 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -257,7 +257,7 @@ RSpec.describe Milestone do let(:milestone) { create(:milestone, title: 'foo', description: 'bar') } it 'returns milestones with a matching title' do - expect(described_class.search_title(milestone.title)) .to eq([milestone]) + expect(described_class.search_title(milestone.title)).to eq([milestone]) end it 'returns milestones with a partially matching title' do @@ -272,7 +272,7 @@ RSpec.describe Milestone do it 'searches only on the title and ignores milestones with a matching description' do create(:milestone, title: 'bar', description: 'foo') - expect(described_class.search_title(milestone.title)) .to eq([milestone]) + expect(described_class.search_title(milestone.title)).to eq([milestone]) end end diff --git a/spec/presenters/alert_management/alert_presenter_spec.rb b/spec/presenters/alert_management/alert_presenter_spec.rb index 21c0cb3fead..fe228f174fe 100644 --- a/spec/presenters/alert_management/alert_presenter_spec.rb +++ b/spec/presenters/alert_management/alert_presenter_spec.rb @@ -115,7 +115,7 @@ RSpec.describe AlertManagement::AlertPresenter do it 'formats the start time of the alert' do alert.started_at = Time.utc(2019, 5, 5) - expect(presenter.start_time). to eq('05 May 2019, 12:00AM (UTC)') + expect(presenter.start_time).to eq('05 May 2019, 12:00AM (UTC)') end end diff --git a/spec/requests/api/graphql/custom_emoji_query_spec.rb b/spec/requests/api/graphql/custom_emoji_query_spec.rb index 874357d9eef..13b7a22e791 100644 --- a/spec/requests/api/graphql/custom_emoji_query_spec.rb +++ b/spec/requests/api/graphql/custom_emoji_query_spec.rb @@ -31,8 +31,8 @@ RSpec.describe 'getting custom emoji within namespace' do post_graphql(custom_emoji_query(group), current_user: current_user) expect(response).to have_gitlab_http_status(:ok) - expect(graphql_data['group']['customEmoji']['nodes'].count). to eq(1) - expect(graphql_data['group']['customEmoji']['nodes'].first['name']). to eq(custom_emoji.name) + expect(graphql_data['group']['customEmoji']['nodes'].count).to eq(1) + expect(graphql_data['group']['customEmoji']['nodes'].first['name']).to eq(custom_emoji.name) end it 'returns nil when unauthorised' do diff --git a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb index fc88d37660b..91e043ffb4b 100644 --- a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb +++ b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb @@ -2,16 +2,18 @@ # # Requires a context containing: # - subject -# - project # - feature_flag_name # - category # - action # - namespace +# Optionaly, the context can contain: +# - project +# - property # - user +# - label +# - **extra shared_examples 'Snowplow event tracking' do - let(:label) { nil } - it 'is not emitted if FF is disabled' do stub_feature_flags(feature_flag_name => false) @@ -21,13 +23,17 @@ shared_examples 'Snowplow event tracking' do end it 'is emitted' do + extra ||= {} + params = { category: category, action: action, namespace: namespace, - user: user, - project: project, - label: label + user: try(:user), + project: try(:project), + label: try(:label), + property: try(:property), + **extra }.compact subject diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb index 74bec406947..8f8178cde4d 100644 --- a/spec/tasks/gitlab/db_rake_spec.rb +++ b/spec/tasks/gitlab/db_rake_spec.rb @@ -370,7 +370,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do it 'outputs changed message for automation after operations happen' do allow(ActiveRecord::Base.connection.schema_migration).to receive(:table_exists?).and_return(schema_migration_table_exists) allow_any_instance_of(ActiveRecord::MigrationContext).to receive(:needs_migration?).and_return(needs_migrations) - expect { run_rake_task('gitlab:db:unattended') }. to output(/^#{rake_output}$/).to_stdout + expect { run_rake_task('gitlab:db:unattended') }.to output(/^#{rake_output}$/).to_stdout end end end diff --git a/spec/workers/concerns/limited_capacity/job_tracker_spec.rb b/spec/workers/concerns/limited_capacity/job_tracker_spec.rb index eeccdbd0e2d..0e3fa350fcd 100644 --- a/spec/workers/concerns/limited_capacity/job_tracker_spec.rb +++ b/spec/workers/concerns/limited_capacity/job_tracker_spec.rb @@ -11,7 +11,7 @@ RSpec.describe LimitedCapacity::JobTracker, :clean_gitlab_redis_shared_state do describe '#register' do it 'adds jid to the set' do - expect(job_tracker.register('a-job-id', max_jids)). to be true + expect(job_tracker.register('a-job-id', max_jids)).to be true expect(job_tracker.running_jids).to contain_exactly('a-job-id') end diff --git a/yarn.lock b/yarn.lock index 3f40c7805f4..ca755429f19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1059,19 +1059,19 @@ stylelint-declaration-strict-value "1.8.0" stylelint-scss "4.2.0" -"@gitlab/svgs@2.30.0": - version "2.30.0" - resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.30.0.tgz#bb73b2d16868b17e7e2dbb73653b7ab84f3cbd05" - integrity sha512-XtYXba8XMAMHJz66H/lVZpXy77Z+ATlvbuvsR9cvM479lUEbrIcdAVOPV6zjPJiIxCUA5Yx1lUfWhgAwLEvRgw== +"@gitlab/svgs@2.32.0": + version "2.32.0" + resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.32.0.tgz#eb66dc76cc6242d97d16e05acb0dbad4f56555a0" + integrity sha512-ElblTUE26pddJS6EzHHtMHPkZ7JPB7vt3C2RoY9W3JPPSrcsOudeeLN5oW7Pz3MoXR3G0U/Wg+Bhe4M1STD+tA== -"@gitlab/ui@42.24.0": - version "42.24.0" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-42.24.0.tgz#6263d3b59cc7791096723b63746add3a15cc116f" - integrity sha512-krQcaGjskWUw/jqRu6V5kCP2yLy+drGitx0T+fIWy78wwQNfR8qgfeaGfPBwTYZ3zpLF8WBULIj37VnAqx2HIw== +"@gitlab/ui@42.25.0": + version "42.25.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-42.25.0.tgz#d79873347be9868c4d3d3123295ce1f12967f330" + integrity sha512-yxSQeLbhrPD4KKQPCo+glarlhoa4cj46j7mgQtTRbJFw2ZWPcpJ4xuujCb8GoyGPlHpWaS8VJyv3l+hwBQs3qg== dependencies: "@popperjs/core" "^2.11.2" bootstrap-vue "2.20.1" - dompurify "^2.3.9" + dompurify "^2.3.10" echarts "^5.3.2" iframe-resizer "^4.3.2" lodash "^4.17.20" @@ -4862,7 +4862,7 @@ dompurify@2.3.6: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.6.tgz#2e019d7d7617aacac07cbbe3d88ae3ad354cf875" integrity sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg== -dompurify@^2.3.10, dompurify@^2.3.9: +dompurify@^2.3.10: version "2.3.10" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.10.tgz#901f7390ffe16a91a5a556b94043314cd4850385" integrity sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g== |