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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-24 12:07:53 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-24 12:07:53 +0300
commit52b219b6f40e49471c66765a95a550f6de256b6a (patch)
tree37102bf58bd19bb23ab99bf940763a0d5311965b
parent9933e246c88dfa3d62eb0bab258539711663b904 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.eslintrc.yml1
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml28
-rw-r--r--app/assets/javascripts/api.js7
-rw-r--r--app/assets/javascripts/content_editor/content_editor.stories.js21
-rw-r--r--app/assets/javascripts/lib/graphql.js5
-rw-r--r--app/views/devise/passwords/new.html.haml5
-rw-r--r--db/migrate/20230523101514_finalize_user_type_migration.rb15
-rw-r--r--db/schema_migrations/202305231015141
-rw-r--r--doc/development/fe_guide/storybook.md64
-rw-r--r--doc/update/index.md9
-rw-r--r--doc/user/workspace/index.md1
-rw-r--r--lib/gitlab/database/background_migration/batched_migration.rb7
-rw-r--r--lib/gitlab/database/background_migration/batched_migration_runner.rb2
-rw-r--r--lib/gitlab/database/background_migration/health_status.rb45
-rw-r--r--lib/gitlab/database/background_migration/health_status/indicators.rb12
-rw-r--r--lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table.rb41
-rw-r--r--lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex.rb90
-rw-r--r--lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb74
-rw-r--r--lib/gitlab/database/background_migration/health_status/signals.rb71
-rw-r--r--lib/gitlab/database/health_status.rb40
-rw-r--r--lib/gitlab/database/health_status/context.rb33
-rw-r--r--lib/gitlab/database/health_status/indicators.rb10
-rw-r--r--lib/gitlab/database/health_status/indicators/autovacuum_active_on_table.rb39
-rw-r--r--lib/gitlab/database/health_status/indicators/patroni_apdex.rb88
-rw-r--r--lib/gitlab/database/health_status/indicators/write_ahead_log.rb71
-rw-r--r--lib/gitlab/database/health_status/logger.rb15
-rw-r--r--lib/gitlab/database/health_status/signals.rb63
-rw-r--r--lib/tasks/frontend.rake18
-rw-r--r--locale/gitlab.pot3
-rwxr-xr-xscripts/frontend/start_storybook.sh8
-rw-r--r--scripts/utils.sh9
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb8
-rw-r--r--spec/lib/gitlab/database/health_status/indicators/autovacuum_active_on_table_spec.rb (renamed from spec/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table_spec.rb)17
-rw-r--r--spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb (renamed from spec/lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex_spec.rb)26
-rw-r--r--spec/lib/gitlab/database/health_status/indicators/write_ahead_log_spec.rb (renamed from spec/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log_spec.rb)19
-rw-r--r--spec/lib/gitlab/database/health_status/logger_spec.rb13
-rw-r--r--spec/lib/gitlab/database/health_status/signals_spec.rb40
-rw-r--r--spec/lib/gitlab/database/health_status_spec.rb (renamed from spec/lib/gitlab/database/background_migration/health_status_spec.rb)25
-rw-r--r--spec/migrations/20230523101514_finalize_user_type_migration_spec.rb12
-rw-r--r--spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb4
-rw-r--r--storybook/.env.template2
-rw-r--r--storybook/.eslintrc.yml8
-rw-r--r--storybook/.gitignore3
-rw-r--r--storybook/config/addons/gitlab_api_access/constants.js5
-rw-r--r--storybook/config/addons/gitlab_api_access/manager.js69
-rw-r--r--storybook/config/addons/gitlab_api_access/preview.js83
-rw-r--r--storybook/config/gon.js5
-rw-r--r--storybook/config/main.js2
-rw-r--r--storybook/config/manager.js1
-rw-r--r--storybook/config/preview.js12
-rw-r--r--storybook/package.json10
-rw-r--r--storybook/yarn.lock463
52 files changed, 1173 insertions, 550 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml
index ae0d4610927..1bb28aae21a 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -163,7 +163,6 @@ overrides:
- '*.config.js'
- '*.config.*.js'
- 'jest_resolver.js'
- - storybook/config/*.js
rules:
'@gitlab/require-i18n-strings': off
import/no-extraneous-dependencies: off
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index c3f14011c5b..fc98f771344 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -108,26 +108,30 @@ start-review-app-pipeline:
- artifact: review-app-pipeline.yml
job: e2e-test-pipeline-generate
-include:
- - project: gitlab-org/quality/pipeline-common
- ref: 5.2.2
- file:
- - /ci/danger-review.yml
-
danger-review:
extends:
- .default-retry
- .ruby-node-cache
- .review:rules:danger
- image: "${DEFAULT_CI_IMAGE}"
+ stage: test
+ needs: []
before_script:
- source scripts/utils.sh
- bundle_install_script "--with danger"
- yarn_install_script
+ script:
+ # ${DANGER_DANGERFILE} is used by Jihulab for customizing danger support: https://jihulab.com/gitlab-cn/gitlab/-/blob/main-jh/jh/.gitlab-ci.yml
+ - >
+ if [ -z "$DANGER_GITLAB_API_TOKEN" ]; then
+ run_timed_command danger_as_local
+ else
+ danger_id=$(echo -n ${DANGER_GITLAB_API_TOKEN} | md5sum | awk '{print $1}' | cut -c5-10)
+ run_timed_command "bundle exec danger --fail-on-errors=true --verbose --danger_id=\"${danger_id}\" --dangerfile=\"${DANGER_DANGERFILE:-Dangerfile}\""
+ fi
danger-review-local:
- extends: danger-review
- before_script:
- - !reference ["danger-review", "before_script"]
- # We unset DANGER_GITLAB_API_TOKEN so that Danger will run as local from `danger-review:script`
- - unset DANGER_GITLAB_API_TOKEN
+ extends:
+ - danger-review
+ - .review:rules:danger-local
+ script:
+ - run_timed_command danger_as_local
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 87c74438d00..95da3b3cf49 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -97,6 +97,7 @@ const Api = {
secureFilePath: '/api/:version/projects/:project_id/secure_files/:secure_file_id',
secureFilesPath: '/api/:version/projects/:project_id/secure_files',
dependencyProxyPath: '/api/:version/groups/:id/dependency_proxy/cache',
+ markdownPath: '/api/:version/markdown',
group(groupId, callback = () => {}) {
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);
@@ -1017,6 +1018,12 @@ const Api = {
return axios.delete(url, { params: { ...options } });
},
+
+ markdown(data = {}) {
+ const url = Api.buildUrl(this.markdownPath);
+
+ return axios.post(url, data);
+ },
};
export default Api;
diff --git a/app/assets/javascripts/content_editor/content_editor.stories.js b/app/assets/javascripts/content_editor/content_editor.stories.js
index 9e1a4bfe361..b98050b61ea 100644
--- a/app/assets/javascripts/content_editor/content_editor.stories.js
+++ b/app/assets/javascripts/content_editor/content_editor.stories.js
@@ -1,26 +1,31 @@
+import Api from '~/api';
import { ContentEditor } from './index';
export default {
component: ContentEditor,
- title: 'content_editor/content_editor',
+ title: 'ce/content_editor/content_editor',
};
const Template = (_, { argTypes }) => ({
components: { ContentEditor },
props: Object.keys(argTypes),
- template: '<content-editor v-bind="$props" @initialized="loadContent" />',
- methods: {
- loadContent(contentEditor) {
- contentEditor.setSerializedContent('Hello content editor');
- },
- },
+ template: `
+ <content-editor v-bind="$props" />
+ `,
});
export const Default = Template.bind({});
Default.args = {
- renderMarkdown: () => '<p>Hello content editor</p>',
+ project: 'gitlab-org/gitlab-shell',
+ renderMarkdown: async (text) => {
+ const response = await Api.markdown({ text, gfm: true, project: Default.args.project });
+
+ return response.data.html;
+ },
+ markdown: 'This is **bold text**',
uploadsPath: '/uploads/',
serializerConfig: {},
extensions: [],
+ enableAutocomplete: false,
};
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index a4c13f9e40e..6ab530576fc 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -120,6 +120,8 @@ function createApolloClient(resolvers = {}, config = {}) {
cacheConfig = { typePolicies: {}, possibleTypes: {} },
fetchPolicy = fetchPolicies.CACHE_FIRST,
typeDefs,
+ httpHeaders = {},
+ fetchCredentials = 'same-origin',
path = '/api/graphql',
useGet = false,
} = config;
@@ -138,11 +140,12 @@ function createApolloClient(resolvers = {}, config = {}) {
uri,
headers: {
[csrf.headerKey]: csrf.token,
+ ...httpHeaders,
},
// fetch won’t send cookies in older browsers, unless you set the credentials init option.
// We set to `same-origin` which is default value in modern browsers.
// See https://github.com/whatwg/fetch/pull/585 for more information.
- credentials: 'same-origin',
+ credentials: fetchCredentials,
batchMax,
};
diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml
index 1400ac9ca72..93ac252823a 100644
--- a/app/views/devise/passwords/new.html.haml
+++ b/app/views/devise/passwords/new.html.haml
@@ -7,7 +7,10 @@
= f.label :email, class: ("gl-mb-1" if Feature.enabled?(:restyle_login_page))
= f.email_field :email, class: "form-control gl-form-input", required: true, autocomplete: 'off', value: params[:user_email], autofocus: true, title: _('Please provide a valid email address.')
.form-text.text-muted
- = _('Requires your primary GitLab email address.')
+ - if Feature.enabled?(:password_reset_any_verified_email)
+ = _('Requires a verified GitLab email address.')
+ - else
+ = _('Requires your primary GitLab email address.')
- if recaptcha_enabled?
.gl-px-5
diff --git a/db/migrate/20230523101514_finalize_user_type_migration.rb b/db/migrate/20230523101514_finalize_user_type_migration.rb
new file mode 100644
index 00000000000..f8ae4c7bb2c
--- /dev/null
+++ b/db/migrate/20230523101514_finalize_user_type_migration.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class FinalizeUserTypeMigration < Gitlab::Database::Migration[2.1]
+ MIGRATION = 'MigrateHumanUserType'
+
+ disable_ddl_transaction!
+
+ def up
+ finalize_background_migration(MIGRATION)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/schema_migrations/20230523101514 b/db/schema_migrations/20230523101514
new file mode 100644
index 00000000000..76c331d425d
--- /dev/null
+++ b/db/schema_migrations/20230523101514
@@ -0,0 +1 @@
+d9efa5185994ecc7d2025d450a1072286674a0a2d94f7f2aa11a6b6b24d4f5da \ No newline at end of file
diff --git a/doc/development/fe_guide/storybook.md b/doc/development/fe_guide/storybook.md
index 8e0814ad96b..44169f110c7 100644
--- a/doc/development/fe_guide/storybook.md
+++ b/doc/development/fe_guide/storybook.md
@@ -53,8 +53,64 @@ To add a story:
If the component is located in the `ee/` directory, make sure to prefix the story's title with `ee/` as well.
This will ensure the Storybook navigation maps closely to our internal directory structure.
-## Mock backend APIs
+## Using GitLab REST and GraphQL APIs
-The GitLab Storybook uses [MirajeJS](https://miragejs.com/) to mock REST and GraphQL APIs. Storybook shares the MirajeJS server
-with the [frontend integration tests](../testing_guide/testing_levels.md#frontend-integration-tests). You can find the MirajeJS
-configuration files in `spec/frontend_integration/mock_server`.
+You can write stories for components that use either GitLab’s [REST](../../api/rest/index.md) or
+[GraphQL](../../api/graphql/index.md) APIs.
+
+### Set up API access token and GitLab instance URL
+
+To add a story with API access:
+
+1. Create a [personal access token](../../user/profile/personal_access_tokens.md) in your GitLab instance.
+
+ NOTE:
+ If you test against `gitlab.com`, make sure to use a token with `read_api` if possible and to make the token short-lived.
+
+1. Create an `.env` file in the `storybook` directory. Use the `storybook/.env.template` file as
+a starting point.
+
+1. Set the `API_ACCESS_TOKEN` variable to the access token that you created.
+
+1. Set the `GITLAB_URL` variable to the GitLab instance’s domain URL, for example: `http://gdk.test:3000`.
+
+1. Start or restart your storybook.
+
+You can also use the GitLab API Access panel in the Storybook UI to set the GitLab instance URL and access token.
+
+### Using REST API
+
+The Storybook sets up `~/lib/utils/axios_utils` in `storybook/config/preview.js`. Components that use the REST API
+should work out of the box as long as you provide a valid GitLab instance URL and access token.
+
+### Using GraphQL
+
+To write a story for a component that uses the GraphQL API, use the `createVueApollo` method provided in
+the Story context.
+
+```javascript
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import WorkspacesList from './list.vue';
+
+Vue.use(VueApollo);
+
+const Template = (_, { argTypes, createVueApollo }) => {
+ return {
+ components: { WorkspacesList },
+ apolloProvider: createVueApollo(),
+ props: Object.keys(argTypes),
+ template: '<workspaces-list />',
+ };
+};
+
+export default {
+ component: WorkspacesList,
+ title: 'ee/remote_development/workspaces_list',
+};
+
+export const Default = Template.bind({});
+
+Default.args = {};
+
+```
diff --git a/doc/update/index.md b/doc/update/index.md
index 00c55f1e4b4..07baec8d072 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -265,6 +265,15 @@ NOTE:
Specific information that follow related to Ruby and Git versions do not apply to [Omnibus installations](https://docs.gitlab.com/omnibus/)
and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with appropriate Ruby and Git versions and are not using system binaries for Ruby and Git. There is no need to install Ruby or Git when utilizing these two approaches.
+### 16.1.0
+
+- A `MigrateHumanUserType` background migration will be finalized with
+ the `FinalizeUserTypeMigration` migration.
+ GitLab 16.0 introduced a [batched background migration](background_migrations.md#batched-background-migrations) to
+ [migrate `user_type` values from `NULL` to `0`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115849). This
+ migration may take multiple days to complete on larger GitLab instances. Make sure the migration
+ has completed successfully before upgrading to 16.1.0.
+
### 16.0.0
- Sidekiq jobs are only routed to `default` and `mailers` queues by default, and as a result,
diff --git a/doc/user/workspace/index.md b/doc/user/workspace/index.md
index 647960459bf..45d9e262bed 100644
--- a/doc/user/workspace/index.md
+++ b/doc/user/workspace/index.md
@@ -37,6 +37,7 @@ Each workspace includes its own set of dependencies, libraries, and tools, which
dns_zone: "workspaces.example.dev"
```
+- You must have at least the Developer role in the root group.
- In each public project you want to use this feature for, create a [devfile](#devfile):
1. On the top bar, select **Main menu > Projects** and find your project.
1. In the root directory of your project, create a file named `.devfile.yaml`. You can use one of the [example configurations](#example-configurations).
diff --git a/lib/gitlab/database/background_migration/batched_migration.rb b/lib/gitlab/database/background_migration/batched_migration.rb
index 2c1a14c56f6..2118393beb0 100644
--- a/lib/gitlab/database/background_migration/batched_migration.rb
+++ b/lib/gitlab/database/background_migration/batched_migration.rb
@@ -216,7 +216,12 @@ module Gitlab
end
def health_context
- HealthStatus::Context.new(connection, [table_name], gitlab_schema.to_sym)
+ @health_context ||= Gitlab::Database::HealthStatus::Context.new(
+ self,
+ connection,
+ [table_name],
+ gitlab_schema.to_sym
+ )
end
def hold!(until_time: 10.minutes.from_now)
diff --git a/lib/gitlab/database/background_migration/batched_migration_runner.rb b/lib/gitlab/database/background_migration/batched_migration_runner.rb
index 7224ff2b517..e3e8754c758 100644
--- a/lib/gitlab/database/background_migration/batched_migration_runner.rb
+++ b/lib/gitlab/database/background_migration/batched_migration_runner.rb
@@ -144,7 +144,7 @@ module Gitlab
end
def adjust_migration(active_migration)
- signals = HealthStatus.evaluate(active_migration)
+ signals = Gitlab::Database::HealthStatus.evaluate(active_migration.health_context)
if signals.any?(&:stop?)
active_migration.hold!
diff --git a/lib/gitlab/database/background_migration/health_status.rb b/lib/gitlab/database/background_migration/health_status.rb
deleted file mode 100644
index 96905fd0bc5..00000000000
--- a/lib/gitlab/database/background_migration/health_status.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- module BackgroundMigration
- module HealthStatus
- DEFAULT_INIDICATORS = [
- Indicators::AutovacuumActiveOnTable,
- Indicators::WriteAheadLog,
- Indicators::PatroniApdex
- ].freeze
-
- # Rather than passing along the migration, we use a more explicitly defined context
- Context = Struct.new(:connection, :tables, :gitlab_schema)
-
- def self.evaluate(migration, indicators = DEFAULT_INIDICATORS)
- indicators.map do |indicator|
- signal = begin
- indicator.new(migration.health_context).evaluate
- rescue StandardError => e
- Gitlab::ErrorTracking.track_exception(e, migration_id: migration.id,
- job_class_name: migration.job_class_name)
-
- Signals::Unknown.new(indicator, reason: "unexpected error: #{e.message} (#{e.class})")
- end
-
- log_signal(signal, migration) if signal.log_info?
-
- signal
- end
- end
-
- def self.log_signal(signal, migration)
- Gitlab::BackgroundMigration::Logger.info(
- migration_id: migration.id,
- health_status_indicator: signal.indicator_class.to_s,
- indicator_signal: signal.short_name,
- signal_reason: signal.reason,
- message: "#{migration} signaled: #{signal}"
- )
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/background_migration/health_status/indicators.rb b/lib/gitlab/database/background_migration/health_status/indicators.rb
deleted file mode 100644
index 69503e5b61f..00000000000
--- a/lib/gitlab/database/background_migration/health_status/indicators.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- module BackgroundMigration
- module HealthStatus
- module Indicators
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table.rb b/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table.rb
deleted file mode 100644
index 48e12609a13..00000000000
--- a/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- module BackgroundMigration
- module HealthStatus
- module Indicators
- class AutovacuumActiveOnTable
- def initialize(context)
- @context = context
- end
-
- def evaluate
- return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
-
- autovacuum_active_on = active_autovacuums_for(context.tables)
-
- if autovacuum_active_on.empty?
- Signals::Normal.new(self.class, reason: 'no autovacuum running on any relevant tables')
- else
- Signals::Stop.new(self.class, reason: "autovacuum running on: #{autovacuum_active_on.join(', ')}")
- end
- end
-
- private
-
- attr_reader :context
-
- def enabled?
- Feature.enabled?(:batched_migrations_health_status_autovacuum, type: :ops)
- end
-
- def active_autovacuums_for(tables)
- Gitlab::Database::PostgresAutovacuumActivity.for_tables(tables)
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex.rb b/lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex.rb
deleted file mode 100644
index 0dd6dd5c2a4..00000000000
--- a/lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- module BackgroundMigration
- module HealthStatus
- module Indicators
- class PatroniApdex
- include Gitlab::Utils::StrongMemoize
-
- def initialize(context)
- @context = context
- end
-
- def evaluate
- return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
-
- connection_error_message = fetch_connection_error_message
- return unknown_signal(connection_error_message) if connection_error_message.present?
-
- apdex_sli = fetch_sli(apdex_sli_query)
- return unknown_signal('Patroni service apdex can not be calculated') unless apdex_sli.present?
-
- if apdex_sli.to_f > apdex_slo.to_f
- Signals::Normal.new(self.class, reason: 'Patroni service apdex is above SLO')
- else
- Signals::Stop.new(self.class, reason: 'Patroni service apdex is below SLO')
- end
- end
-
- private
-
- attr_reader :context
-
- def enabled?
- Feature.enabled?(:batched_migrations_health_status_patroni_apdex, type: :ops)
- end
-
- def unknown_signal(reason)
- Signals::Unknown.new(self.class, reason: reason)
- end
-
- def fetch_connection_error_message
- return 'Patroni Apdex Settings not configured' unless database_apdex_settings.present?
- return 'Prometheus client is not ready' unless client.ready?
- return 'Apdex SLI query is not configured' unless apdex_sli_query
- return 'Apdex SLO is not configured' unless apdex_slo
- end
-
- def client
- @client ||= Gitlab::PrometheusClient.new(
- database_apdex_settings[:prometheus_api_url],
- allow_local_requests: true,
- verify: true
- )
- end
-
- def database_apdex_settings
- @database_apdex_settings ||= Gitlab::CurrentSettings.database_apdex_settings&.with_indifferent_access
- end
-
- def apdex_sli_query
- {
- gitlab_main: database_apdex_settings[:apdex_sli_query][:main],
- gitlab_ci: database_apdex_settings[:apdex_sli_query][:ci]
- }.fetch(context.gitlab_schema.to_sym)
- end
- strong_memoize_attr :apdex_sli_query
-
- def apdex_slo
- {
- gitlab_main: database_apdex_settings[:apdex_slo][:main],
- gitlab_ci: database_apdex_settings[:apdex_slo][:ci]
- }.fetch(context.gitlab_schema.to_sym)
- end
- strong_memoize_attr :apdex_slo
-
- def fetch_sli(query)
- response = client.query(query)
- metric = response&.first || {}
- value = metric.fetch('value', [])
-
- Array.wrap(value).second
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb b/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb
deleted file mode 100644
index d2fb0a8b751..00000000000
--- a/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- module BackgroundMigration
- module HealthStatus
- module Indicators
- class WriteAheadLog
- include Gitlab::Utils::StrongMemoize
-
- LIMIT = 42
- PENDING_WAL_COUNT_SQL = <<~SQL
- WITH
- current_wal_file AS (
- SELECT pg_walfile_name(pg_current_wal_insert_lsn()) AS pg_walfile_name
- ),
- current_wal AS (
- SELECT
- ('x' || substring(pg_walfile_name, 9, 8))::bit(32)::int AS log,
- ('x' || substring(pg_walfile_name, 17, 8))::bit(32)::int AS seg,
- pg_walfile_name
- FROM current_wal_file
- ),
- archive_wal AS (
- SELECT
- ('x' || substring(last_archived_wal, 9, 8))::bit(32)::int AS log,
- ('x' || substring(last_archived_wal, 17, 8))::bit(32)::int AS seg,
- last_archived_wal
- FROM pg_stat_archiver
- )
- SELECT ((current_wal.log - archive_wal.log) * 256) + (current_wal.seg - archive_wal.seg) AS pending_wal_count
- FROM current_wal, archive_wal
- SQL
-
- def initialize(context)
- @connection = context.connection
- end
-
- def evaluate
- return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
-
- unless pending_wal_count
- return Signals::NotAvailable.new(self.class, reason: 'WAL archive queue can not be calculated')
- end
-
- if pending_wal_count > LIMIT
- Signals::Stop.new(self.class, reason: "WAL archive queue is too big")
- else
- Signals::Normal.new(self.class, reason: 'WAL archive queue is within limit')
- end
- end
-
- private
-
- attr_reader :connection
-
- def enabled?
- Feature.enabled?(:batched_migrations_health_status_wal, type: :ops)
- end
-
- # Returns number of WAL segments pending archival
- def pending_wal_count
- strong_memoize(:pending_wal_count) do
- Gitlab::Database::LoadBalancing::Session.current.use_primary do
- connection.execute(PENDING_WAL_COUNT_SQL).to_a.first&.fetch('pending_wal_count')
- end
- end
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/background_migration/health_status/signals.rb b/lib/gitlab/database/background_migration/health_status/signals.rb
deleted file mode 100644
index 534c4330cf2..00000000000
--- a/lib/gitlab/database/background_migration/health_status/signals.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Database
- module BackgroundMigration
- module HealthStatus
- module Signals
- # Base class for a signal
- class Base
- attr_reader :indicator_class, :reason
-
- def initialize(indicator_class, reason:)
- @indicator_class = indicator_class
- @reason = reason
- end
-
- def to_s
- "#{short_name} (indicator: #{indicator_class}; reason: #{reason})"
- end
-
- # :nocov:
- def log_info?
- false
- end
-
- def stop?
- false
- end
- # :nocov:
-
- def short_name
- self.class.name.demodulize
- end
- end
-
- # A Signals::Stop is an indication to put a migration on hold or stop it entirely:
- # In general, we want to slow down or pause the migration.
- class Stop < Base
- # :nocov:
- def log_info?
- true
- end
-
- def stop?
- true
- end
- # :nocov:
- end
-
- # A Signals::Normal indicates normal system state: We carry on with the migration
- # and may even attempt to optimize its throughput etc.
- class Normal < Base; end
-
- # When given an Signals::Unknown, something unexpected happened while
- # we evaluated system indicators.
- class Unknown < Base
- # :nocov:
- def log_info?
- true
- end
- # :nocov:
- end
-
- # No signal could be determined, e.g. because the indicator
- # was disabled.
- class NotAvailable < Base; end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/database/health_status.rb b/lib/gitlab/database/health_status.rb
new file mode 100644
index 00000000000..69bb8a70afd
--- /dev/null
+++ b/lib/gitlab/database/health_status.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ DEFAULT_INIDICATORS = [
+ Indicators::AutovacuumActiveOnTable,
+ Indicators::WriteAheadLog,
+ Indicators::PatroniApdex
+ ].freeze
+
+ class << self
+ def evaluate(context, indicators = DEFAULT_INIDICATORS)
+ indicators.map do |indicator|
+ signal = begin
+ indicator.new(context).evaluate
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(e, **context.status_checker_info)
+
+ Signals::Unknown.new(indicator, reason: "unexpected error: #{e.message} (#{e.class})")
+ end
+
+ log_signal(signal, context) if signal.log_info?
+
+ signal
+ end
+ end
+
+ def log_signal(signal, context)
+ Gitlab::Database::HealthStatus::Logger.info(**context.status_checker_info.merge(
+ health_status_indicator: signal.indicator_class.to_s,
+ indicator_signal: signal.short_name,
+ signal_reason: signal.reason,
+ message: "#{context.status_checker} signaled: #{signal}"
+ ))
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/context.rb b/lib/gitlab/database/health_status/context.rb
new file mode 100644
index 00000000000..a1d9efead1f
--- /dev/null
+++ b/lib/gitlab/database/health_status/context.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ class Context
+ attr_reader :status_checker, :connection, :tables, :gitlab_schema
+
+ # status_checker: the caller object which checks for database health status
+ # eg: batched_migration
+ def initialize(status_checker, connection, tables, gitlab_schema)
+ @status_checker = status_checker
+ @connection = connection
+ @tables = tables
+ @gitlab_schema = gitlab_schema
+ end
+
+ def status_checker_info
+ data = {
+ status_checker_id: status_checker.id,
+ status_checker_type: status_checker.class.name
+ }
+
+ if status_checker.is_a?(Gitlab::Database::BackgroundMigration::BatchedMigration)
+ data[:job_class_name] = status_checker.job_class_name
+ end
+
+ data
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/indicators.rb b/lib/gitlab/database/health_status/indicators.rb
new file mode 100644
index 00000000000..a149c36aae4
--- /dev/null
+++ b/lib/gitlab/database/health_status/indicators.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ module Indicators
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/indicators/autovacuum_active_on_table.rb b/lib/gitlab/database/health_status/indicators/autovacuum_active_on_table.rb
new file mode 100644
index 00000000000..6bf2bbf0c70
--- /dev/null
+++ b/lib/gitlab/database/health_status/indicators/autovacuum_active_on_table.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ module Indicators
+ class AutovacuumActiveOnTable
+ def initialize(context)
+ @tables = context.tables
+ end
+
+ def evaluate
+ return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
+
+ autovacuum_active_on = active_autovacuums_for(tables)
+
+ if autovacuum_active_on.empty?
+ Signals::Normal.new(self.class, reason: 'no autovacuum running on any relevant tables')
+ else
+ Signals::Stop.new(self.class, reason: "autovacuum running on: #{autovacuum_active_on.join(', ')}")
+ end
+ end
+
+ private
+
+ attr_reader :tables
+
+ def enabled?
+ Feature.enabled?(:batched_migrations_health_status_autovacuum, type: :ops)
+ end
+
+ def active_autovacuums_for(tables)
+ Gitlab::Database::PostgresAutovacuumActivity.for_tables(tables)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/indicators/patroni_apdex.rb b/lib/gitlab/database/health_status/indicators/patroni_apdex.rb
new file mode 100644
index 00000000000..680c86cf7b2
--- /dev/null
+++ b/lib/gitlab/database/health_status/indicators/patroni_apdex.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ module Indicators
+ class PatroniApdex
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(context)
+ @gitlab_schema = context.gitlab_schema.to_sym
+ end
+
+ def evaluate
+ return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
+
+ connection_error_message = fetch_connection_error_message
+ return unknown_signal(connection_error_message) if connection_error_message.present?
+
+ apdex_sli = fetch_sli(apdex_sli_query)
+ return unknown_signal('Patroni service apdex can not be calculated') unless apdex_sli.present?
+
+ if apdex_sli.to_f > apdex_slo.to_f
+ Signals::Normal.new(self.class, reason: 'Patroni service apdex is above SLO')
+ else
+ Signals::Stop.new(self.class, reason: 'Patroni service apdex is below SLO')
+ end
+ end
+
+ private
+
+ attr_reader :gitlab_schema
+
+ def enabled?
+ Feature.enabled?(:batched_migrations_health_status_patroni_apdex, type: :ops)
+ end
+
+ def unknown_signal(reason)
+ Signals::Unknown.new(self.class, reason: reason)
+ end
+
+ def fetch_connection_error_message
+ return 'Patroni Apdex Settings not configured' unless database_apdex_settings.present?
+ return 'Prometheus client is not ready' unless client.ready?
+ return 'Apdex SLI query is not configured' unless apdex_sli_query
+ return 'Apdex SLO is not configured' unless apdex_slo
+ end
+
+ def client
+ @client ||= Gitlab::PrometheusClient.new(
+ database_apdex_settings[:prometheus_api_url],
+ allow_local_requests: true,
+ verify: true
+ )
+ end
+
+ def database_apdex_settings
+ @database_apdex_settings ||= Gitlab::CurrentSettings.database_apdex_settings&.with_indifferent_access
+ end
+
+ def apdex_sli_query
+ {
+ gitlab_main: database_apdex_settings[:apdex_sli_query][:main],
+ gitlab_ci: database_apdex_settings[:apdex_sli_query][:ci]
+ }.fetch(gitlab_schema)
+ end
+ strong_memoize_attr :apdex_sli_query
+
+ def apdex_slo
+ {
+ gitlab_main: database_apdex_settings[:apdex_slo][:main],
+ gitlab_ci: database_apdex_settings[:apdex_slo][:ci]
+ }.fetch(gitlab_schema)
+ end
+ strong_memoize_attr :apdex_slo
+
+ def fetch_sli(query)
+ response = client.query(query)
+ metric = response&.first || {}
+ value = metric.fetch('value', [])
+
+ Array.wrap(value).second
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/indicators/write_ahead_log.rb b/lib/gitlab/database/health_status/indicators/write_ahead_log.rb
new file mode 100644
index 00000000000..1614b17df48
--- /dev/null
+++ b/lib/gitlab/database/health_status/indicators/write_ahead_log.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ module Indicators
+ class WriteAheadLog
+ include Gitlab::Utils::StrongMemoize
+
+ LIMIT = 42
+ PENDING_WAL_COUNT_SQL = <<~SQL
+ WITH
+ current_wal_file AS (
+ SELECT pg_walfile_name(pg_current_wal_insert_lsn()) AS pg_walfile_name
+ ),
+ current_wal AS (
+ SELECT
+ ('x' || substring(pg_walfile_name, 9, 8))::bit(32)::int AS log,
+ ('x' || substring(pg_walfile_name, 17, 8))::bit(32)::int AS seg,
+ pg_walfile_name
+ FROM current_wal_file
+ ),
+ archive_wal AS (
+ SELECT
+ ('x' || substring(last_archived_wal, 9, 8))::bit(32)::int AS log,
+ ('x' || substring(last_archived_wal, 17, 8))::bit(32)::int AS seg,
+ last_archived_wal
+ FROM pg_stat_archiver
+ )
+ SELECT ((current_wal.log - archive_wal.log) * 256) + (current_wal.seg - archive_wal.seg) AS pending_wal_count
+ FROM current_wal, archive_wal
+ SQL
+
+ def initialize(context)
+ @connection = context.connection
+ end
+
+ def evaluate
+ return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
+
+ unless pending_wal_count
+ return Signals::NotAvailable.new(self.class, reason: 'WAL archive queue can not be calculated')
+ end
+
+ if pending_wal_count > LIMIT
+ Signals::Stop.new(self.class, reason: "WAL archive queue is too big")
+ else
+ Signals::Normal.new(self.class, reason: 'WAL archive queue is within limit')
+ end
+ end
+
+ private
+
+ attr_reader :connection
+
+ def enabled?
+ Feature.enabled?(:batched_migrations_health_status_wal, type: :ops)
+ end
+
+ # Returns number of WAL segments pending archival
+ def pending_wal_count
+ Gitlab::Database::LoadBalancing::Session.current.use_primary do
+ connection.execute(PENDING_WAL_COUNT_SQL).to_a.first&.fetch('pending_wal_count')
+ end
+ end
+ strong_memoize_attr :pending_wal_count
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/logger.rb b/lib/gitlab/database/health_status/logger.rb
new file mode 100644
index 00000000000..820c1aeb695
--- /dev/null
+++ b/lib/gitlab/database/health_status/logger.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ class Logger < ::Gitlab::JsonLogger
+ exclude_context!
+
+ def self.file_name_noext
+ 'database_health_status'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/health_status/signals.rb b/lib/gitlab/database/health_status/signals.rb
new file mode 100644
index 00000000000..e1bcdcae9c7
--- /dev/null
+++ b/lib/gitlab/database/health_status/signals.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module HealthStatus
+ module Signals
+ # Base class for a signal
+ class Base
+ attr_reader :indicator_class, :reason
+
+ def initialize(indicator_class, reason:)
+ @indicator_class = indicator_class
+ @reason = reason
+ end
+
+ def to_s
+ "#{short_name} (indicator: #{indicator_class}; reason: #{reason})"
+ end
+
+ def log_info?
+ false
+ end
+
+ def stop?
+ false
+ end
+
+ def short_name
+ self.class.name.demodulize
+ end
+ end
+
+ # A Signals::Stop is an indication to put a migration on hold or stop it entirely:
+ # In general, we want to slow down or pause the migration.
+ class Stop < Base
+ def log_info?
+ true
+ end
+
+ def stop?
+ true
+ end
+ end
+
+ # A Signals::Normal indicates normal system state: We carry on with the migration
+ # and may even attempt to optimize its throughput etc.
+ class Normal < Base; end
+
+ # When given an Signals::Unknown, something unexpected happened while
+ # we evaluated system indicators.
+ class Unknown < Base
+ def log_info?
+ true
+ end
+ end
+
+ # No signal could be determined, e.g. because the indicator
+ # was disabled.
+ class NotAvailable < Base; end
+ end
+ end
+ end
+end
diff --git a/lib/tasks/frontend.rake b/lib/tasks/frontend.rake
index e768c42736d..a6754f13089 100644
--- a/lib/tasks/frontend.rake
+++ b/lib/tasks/frontend.rake
@@ -18,30 +18,12 @@ unless Rails.env.production?
t.rspec_opts = '--format documentation'
end
- desc 'GitLab | Frontend | Generate fixtures for JavaScript integration tests'
- RSpec::Core::RakeTask.new(:mock_server_rspec_fixtures) do |t, args|
- require 'yaml'
-
- base_path = Pathname.new('spec/frontend_integration/fixture_generators.yml')
- ee_path = Pathname.new('ee') + base_path
-
- fixtures = YAML.safe_load(base_path.read)
- fixtures.concat(Array(YAML.safe_load(ee_path.read))) if Gitlab.ee? && ee_path.exist?
-
- t.pattern = fixtures.join(',')
- ENV['NO_KNAPSACK'] = 'true'
- t.rspec_opts = '--format documentation'
- end
-
desc 'GitLab | Frontend | Run JavaScript tests'
task tests: ['yarn:check'] do
sh "yarn test" do |ok, res|
abort('rake frontend:tests failed') unless ok
end
end
-
- desc 'GitLab | Frontend | Shortcut for generating all fixtures used by MirajeJS mock server'
- task mock_server_fixtures: ['frontend:mock_server_rspec_fixtures', 'gitlab:graphql:schema:dump']
end
desc 'GitLab | Frontend | Shortcut for frontend:fixtures and frontend:tests'
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 487cc4e1a4d..8df4d6eeffb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -38419,6 +38419,9 @@ msgid_plural "Requires %{count} approvals from %{names}."
msgstr[0] ""
msgstr[1] ""
+msgid "Requires a verified GitLab email address."
+msgstr ""
+
msgid "Requires values to meet regular expression requirements."
msgstr ""
diff --git a/scripts/frontend/start_storybook.sh b/scripts/frontend/start_storybook.sh
index 7ae0a21b15b..622e35f5483 100755
--- a/scripts/frontend/start_storybook.sh
+++ b/scripts/frontend/start_storybook.sh
@@ -3,14 +3,6 @@
bold=$(tput bold)
normal=$(tput sgr0)
-echo -e "Storybook provides a mock server that allows creating stories for components that make HTTP requests."
-echo -e "${bold}Storybook will fail to start if it can’t find the fixtures used by the mock server.${normal}\n"
-read -rp "Would you like to generate/update the frontend fixtures used by the mock server (y/N)? " answer
-
-if [[ "$answer" =~ ^(Y|y)$ ]] ; then
- bundle exec rake frontend:mock_server_fixtures
-fi
-
if ! [[ -d storybook/node_modules ]] ; then
yarn storybook:install
fi
diff --git a/scripts/utils.sh b/scripts/utils.sh
index 66512798a11..40cf6716528 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -114,6 +114,8 @@ function yarn_install_script() {
retry yarn install --frozen-lockfile
+ retry yarn storybook:install --frozen-lockfile
+
section_end "yarn-install"
}
@@ -290,6 +292,13 @@ function fail_pipeline_early() {
fi
}
+function danger_as_local() {
+ # Force danger to skip CI source GitLab and fallback to "local only git repo".
+ unset GITLAB_CI
+ # We need to base SHA to help danger determine the base commit for this shallow clone.
+ bundle exec danger dry_run --fail-on-errors=true --verbose --base="${CI_MERGE_REQUEST_DIFF_BASE_SHA}" --head="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA:-$CI_COMMIT_SHA}" --dangerfile="${DANGER_DANGERFILE:-Dangerfile}"
+}
+
# We're inlining this function in `.gitlab/ci/package-and-test/main.gitlab-ci.yml` so make sure to reflect any changes there
function assets_image_tag() {
local cache_assets_hash_file="cached-assets-hash.txt"
diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
index 4ef2e7f936b..0faa468233d 100644
--- a/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do
+RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner, feature_category: :database do
let(:connection) { Gitlab::Database.database_base_models[:main].connection }
let(:migration_wrapper) { double('test wrapper') }
@@ -15,8 +15,8 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do
end
before do
- normal_signal = instance_double(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Normal, stop?: false)
- allow(Gitlab::Database::BackgroundMigration::HealthStatus).to receive(:evaluate).and_return([normal_signal])
+ normal_signal = instance_double(Gitlab::Database::HealthStatus::Signals::Normal, stop?: false)
+ allow(Gitlab::Database::HealthStatus).to receive(:evaluate).and_return([normal_signal])
end
describe '#run_migration_job' do
@@ -65,7 +65,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do
end
context 'migration health' do
- let(:health_status) { Gitlab::Database::BackgroundMigration::HealthStatus }
+ let(:health_status) { Gitlab::Database::HealthStatus }
let(:stop_signal) { health_status::Signals::Stop.new(:indicator, reason: 'Take a break') }
let(:normal_signal) { health_status::Signals::Normal.new(:indicator, reason: 'All good') }
let(:not_available_signal) { health_status::Signals::NotAvailable.new(:indicator, reason: 'Indicator is disabled') }
diff --git a/spec/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table_spec.rb b/spec/lib/gitlab/database/health_status/indicators/autovacuum_active_on_table_spec.rb
index 1c0f5a0c420..cd145bd5c0f 100644
--- a/spec/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table_spec.rb
+++ b/spec/lib/gitlab/database/health_status/indicators/autovacuum_active_on_table_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::AutovacuumActiveOnTable,
+RSpec.describe Gitlab::Database::HealthStatus::Indicators::AutovacuumActiveOnTable,
feature_category: :database do
include Database::DatabaseHelpers
@@ -23,11 +23,18 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
let(:tables) { [table] }
let(:table) { 'users' }
- let(:context) { Gitlab::Database::BackgroundMigration::HealthStatus::Context.new(connection, tables) }
+ let(:context) do
+ Gitlab::Database::HealthStatus::Context.new(
+ described_class,
+ connection,
+ tables,
+ :gitlab_main
+ )
+ end
context 'without autovacuum activity' do
it 'returns Normal signal' do
- expect(subject).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Normal)
+ expect(subject).to be_a(Gitlab::Database::HealthStatus::Signals::Normal)
end
it 'remembers the indicator class' do
@@ -41,7 +48,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
end
it 'returns Stop signal' do
- expect(subject).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Stop)
+ expect(subject).to be_a(Gitlab::Database::HealthStatus::Signals::Stop)
end
it 'explains why' do
@@ -55,7 +62,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
it 'returns NoSignal signal in case the feature flag is disabled' do
stub_feature_flags(batched_migrations_health_status_autovacuum: false)
- expect(subject).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::NotAvailable)
+ expect(subject).to be_a(Gitlab::Database::HealthStatus::Signals::NotAvailable)
end
end
end
diff --git a/spec/lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex_spec.rb b/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb
index d3102a105ea..e0e3a0a7c23 100644
--- a/spec/lib/gitlab/database/background_migration/health_status/indicators/patroni_apdex_spec.rb
+++ b/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::PatroniApdex, :aggregate_failures, feature_category: :database do # rubocop:disable Layout/LineLength
+RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggregate_failures, feature_category: :database do # rubocop:disable Layout/LineLength
let(:schema) { :main }
let(:connection) { Gitlab::Database.database_base_models[schema].connection }
@@ -19,8 +19,12 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
let(:prometheus_client) { instance_double(Gitlab::PrometheusClient) }
let(:context) do
- Gitlab::Database::BackgroundMigration::HealthStatus::Context
- .new(connection, ['users'], gitlab_schema)
+ Gitlab::Database::HealthStatus::Context.new(
+ described_class,
+ connection,
+ ['users'],
+ gitlab_schema
+ )
end
let(:gitlab_schema) { "gitlab_#{schema}" }
@@ -61,7 +65,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
it 'returns NoSignal signal in case the feature flag is disabled' do
stub_feature_flags(batched_migrations_health_status_patroni_apdex: false)
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::NotAvailable)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::NotAvailable)
expect(evaluate.reason).to include('indicator disabled')
end
@@ -69,7 +73,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
let(:database_apdex_settings) { nil }
it 'returns Unknown signal' do
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown)
expect(evaluate.reason).to include('Patroni Apdex Settings not configured')
end
end
@@ -78,7 +82,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
let(:client_ready) { false }
it 'returns Unknown signal' do
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown)
expect(evaluate.reason).to include('Prometheus client is not ready')
end
end
@@ -87,7 +91,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
let(:"database_apdex_sli_query_#{schema}") { nil }
it 'returns Unknown signal' do
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown)
expect(evaluate.reason).to include('Apdex SLI query is not configured')
end
end
@@ -96,7 +100,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
let(:"database_apdex_slo_#{schema}") { nil }
it 'returns Unknown signal' do
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown)
expect(evaluate.reason).to include('Apdex SLO is not configured')
end
end
@@ -105,7 +109,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
expect(prometheus_client).to receive(:query)
.with(send("database_apdex_sli_query_#{schema}"))
.and_return([{ "value" => [1662423310.878, apdex_slo_above_sli[schema]] }])
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Normal)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Normal)
expect(evaluate.reason).to include('Patroni service apdex is above SLO')
end
@@ -113,7 +117,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
expect(prometheus_client).to receive(:query)
.with(send("database_apdex_sli_query_#{schema}"))
.and_return([{ "value" => [1662423310.878, apdex_slo_below_sli[schema]] }])
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Stop)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Stop)
expect(evaluate.reason).to include('Patroni service apdex is below SLO')
end
@@ -131,7 +135,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
with_them do
it 'returns Unknown signal' do
expect(prometheus_client).to receive(:query).and_return(result)
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown)
expect(evaluate.reason).to include('Patroni service apdex can not be calculated')
end
end
diff --git a/spec/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log_spec.rb b/spec/lib/gitlab/database/health_status/indicators/write_ahead_log_spec.rb
index 650f11e3cd5..aa2aee4f94a 100644
--- a/spec/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log_spec.rb
+++ b/spec/lib/gitlab/database/health_status/indicators/write_ahead_log_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::WriteAheadLog do
+RSpec.describe Gitlab::Database::HealthStatus::Indicators::WriteAheadLog, feature_category: :database do
let(:connection) { Gitlab::Database.database_base_models[:main].connection }
around do |example|
@@ -14,7 +14,14 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
describe '#evaluate' do
let(:tables) { [table] }
let(:table) { 'users' }
- let(:context) { Gitlab::Database::BackgroundMigration::HealthStatus::Context.new(connection, tables) }
+ let(:context) do
+ Gitlab::Database::HealthStatus::Context.new(
+ described_class,
+ connection,
+ tables,
+ :gitlab_main
+ )
+ end
subject(:evaluate) { described_class.new(context).evaluate }
@@ -25,14 +32,14 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
it 'returns NoSignal signal in case the feature flag is disabled' do
stub_feature_flags(batched_migrations_health_status_wal: false)
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::NotAvailable)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::NotAvailable)
expect(evaluate.reason).to include('indicator disabled')
end
it 'returns NoSignal signal when WAL archive queue can not be calculated' do
expect(connection).to receive(:execute).and_return([{ 'pending_wal_count' => nil }])
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::NotAvailable)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::NotAvailable)
expect(evaluate.reason).to include('WAL archive queue can not be calculated')
end
@@ -45,7 +52,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
context 'when WAL archive queue size is below the limit' do
it 'returns Normal signal' do
expect(connection).to receive(:execute).and_return([{ 'pending_wal_count' => 1 }])
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Normal)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Normal)
expect(evaluate.reason).to include('WAL archive queue is within limit')
end
end
@@ -53,7 +60,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::
context 'when WAL archive queue size is above the limit' do
it 'returns Stop signal' do
expect(connection).to receive(:execute).and_return([{ 'pending_wal_count' => 420 }])
- expect(evaluate).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Stop)
+ expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Stop)
expect(evaluate.reason).to include('WAL archive queue is too big')
end
end
diff --git a/spec/lib/gitlab/database/health_status/logger_spec.rb b/spec/lib/gitlab/database/health_status/logger_spec.rb
new file mode 100644
index 00000000000..5ae6b40cb3a
--- /dev/null
+++ b/spec/lib/gitlab/database/health_status/logger_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::HealthStatus::Logger, feature_category: :database do
+ subject { described_class.new('/dev/null') }
+
+ it_behaves_like 'a json logger', {}
+
+ it 'excludes context' do
+ expect(described_class.exclude_context?).to be(true)
+ end
+end
diff --git a/spec/lib/gitlab/database/health_status/signals_spec.rb b/spec/lib/gitlab/database/health_status/signals_spec.rb
new file mode 100644
index 00000000000..5bfd8ffb91e
--- /dev/null
+++ b/spec/lib/gitlab/database/health_status/signals_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::HealthStatus::Signals, feature_category: :database do
+ shared_examples 'health status signal' do |subclass, stop_signal, log_signal|
+ let(:indicator) { instance_double('Gitlab::Database::HealthStatus::Indicators::PatroniApdex') }
+ let(:reason) { 'Test reason' }
+
+ subject { subclass.new(indicator, reason: reason) }
+
+ describe '#log_info?' do
+ it 'returns the log signal' do
+ expect(subject.log_info?).to eq(log_signal)
+ end
+ end
+
+ describe '#stop?' do
+ it 'returns the stop signal' do
+ expect(subject.stop?).to eq(stop_signal)
+ end
+ end
+ end
+
+ context 'with Stop signal it should stop and log' do
+ it_behaves_like 'health status signal', described_class::Stop, true, true
+ end
+
+ context 'with Normal signal it should not stop and log' do
+ it_behaves_like 'health status signal', described_class::Normal, false, false
+ end
+
+ context 'with NotAvailable signal it should not stop and log' do
+ it_behaves_like 'health status signal', described_class::NotAvailable, false, false
+ end
+
+ context 'with Unknown signal it should only log and not stop' do
+ it_behaves_like 'health status signal', described_class::Unknown, false, true
+ end
+end
diff --git a/spec/lib/gitlab/database/background_migration/health_status_spec.rb b/spec/lib/gitlab/database/health_status_spec.rb
index 4d6c729f080..8d7717beaff 100644
--- a/spec/lib/gitlab/database/background_migration/health_status_spec.rb
+++ b/spec/lib/gitlab/database/health_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus, feature_category: :database do
+RSpec.describe Gitlab::Database::HealthStatus, feature_category: :database do
let(:connection) { Gitlab::Database.database_base_models[:main].connection }
around do |example|
@@ -12,11 +12,11 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus, feature_cate
end
describe '.evaluate' do
- subject(:evaluate) { described_class.evaluate(migration, [autovacuum_indicator_class]) }
+ subject(:evaluate) { described_class.evaluate(migration.health_context, [autovacuum_indicator_class]) }
let(:migration) { build(:batched_background_migration, :active) }
- let(:health_status) { Gitlab::Database::BackgroundMigration::HealthStatus }
+ let(:health_status) { described_class }
let(:autovacuum_indicator_class) { health_status::Indicators::AutovacuumActiveOnTable }
let(:wal_indicator_class) { health_status::Indicators::WriteAheadLog }
let(:patroni_apdex_indicator_class) { health_status::Indicators::PatroniApdex }
@@ -29,7 +29,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus, feature_cate
end
context 'with default indicators' do
- subject(:evaluate) { described_class.evaluate(migration) }
+ subject(:evaluate) { described_class.evaluate(migration.health_context) }
it 'returns a collection of signals' do
normal_signal = instance_double("#{health_status}::Signals::Normal", log_info?: false)
@@ -65,8 +65,10 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus, feature_cate
expect(autovacuum_indicator).to receive(:evaluate).and_return(signal)
- expect(Gitlab::BackgroundMigration::Logger).to receive(:info).with(
- migration_id: migration.id,
+ expect(Gitlab::Database::HealthStatus::Logger).to receive(:info).with(
+ status_checker_id: migration.id,
+ status_checker_type: 'Gitlab::Database::BackgroundMigration::BatchedMigration',
+ job_class_name: migration.job_class_name,
health_status_indicator: autovacuum_indicator_class.to_s,
indicator_signal: 'Stop',
signal_reason: 'Test Exception',
@@ -89,7 +91,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus, feature_cate
let(:error) { RuntimeError.new('everything broken') }
before do
- expect(autovacuum_indicator).to receive(:evaluate).and_raise(error)
+ allow(autovacuum_indicator).to receive(:evaluate).and_raise(error)
end
it 'does not fail' do
@@ -99,13 +101,18 @@ RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus, feature_cate
it 'returns Unknown signal' do
signal = evaluate.first
- expect(signal).to be_an_instance_of(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown)
+ expect(signal).to be_an_instance_of(Gitlab::Database::HealthStatus::Signals::Unknown)
expect(signal.reason).to eq("unexpected error: everything broken (RuntimeError)")
end
it 'reports the exception to error tracking' do
expect(Gitlab::ErrorTracking).to receive(:track_exception)
- .with(error, migration_id: migration.id, job_class_name: migration.job_class_name)
+ .with(
+ error,
+ status_checker_id: migration.id,
+ status_checker_type: 'Gitlab::Database::BackgroundMigration::BatchedMigration',
+ job_class_name: migration.job_class_name
+ )
evaluate
end
diff --git a/spec/migrations/20230523101514_finalize_user_type_migration_spec.rb b/spec/migrations/20230523101514_finalize_user_type_migration_spec.rb
new file mode 100644
index 00000000000..abf3a506748
--- /dev/null
+++ b/spec/migrations/20230523101514_finalize_user_type_migration_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FinalizeUserTypeMigration, feature_category: :devops_reports do
+ it 'finalizes MigrateHumanUserType migration' do
+ expect(described_class).to be_finalize_background_migration_of('MigrateHumanUserType')
+
+ migrate!
+ end
+end
diff --git a/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb b/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb
index 975c7a7447c..e7385f9abb6 100644
--- a/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb
+++ b/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb
@@ -331,8 +331,8 @@ RSpec.shared_examples 'it runs batched background migration jobs' do |tracking_d
end
it 'puts migration on hold when the pending WAL count is above the limit' do
- sql = Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::WriteAheadLog::PENDING_WAL_COUNT_SQL
- limit = Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::WriteAheadLog::LIMIT
+ sql = Gitlab::Database::HealthStatus::Indicators::WriteAheadLog::PENDING_WAL_COUNT_SQL
+ limit = Gitlab::Database::HealthStatus::Indicators::WriteAheadLog::LIMIT
expect(connection).to receive(:execute).with(sql).and_return([{ 'pending_wal_count' => limit + 1 }])
diff --git a/storybook/.env.template b/storybook/.env.template
new file mode 100644
index 00000000000..ed4d39132e3
--- /dev/null
+++ b/storybook/.env.template
@@ -0,0 +1,2 @@
+API_ACCESS_TOKEN="api-token"
+GITLAB_URL="http://gdk.test:3000"
diff --git a/storybook/.eslintrc.yml b/storybook/.eslintrc.yml
new file mode 100644
index 00000000000..f3bbec8f26d
--- /dev/null
+++ b/storybook/.eslintrc.yml
@@ -0,0 +1,8 @@
+rules:
+ '@gitlab/require-i18n-strings': off
+ import/no-extraneous-dependencies: off
+ import/no-commonjs: off
+ import/no-nodejs-modules: off
+ filenames/match-regex: off
+ no-console: off
+ import/no-unresolved: off
diff --git a/storybook/.gitignore b/storybook/.gitignore
index 18d5e871aaa..d636a68c7a4 100644
--- a/storybook/.gitignore
+++ b/storybook/.gitignore
@@ -1,2 +1,3 @@
node_modules/
-public/ \ No newline at end of file
+public/
+.env
diff --git a/storybook/config/addons/gitlab_api_access/constants.js b/storybook/config/addons/gitlab_api_access/constants.js
new file mode 100644
index 00000000000..a925557bf62
--- /dev/null
+++ b/storybook/config/addons/gitlab_api_access/constants.js
@@ -0,0 +1,5 @@
+export const ADDON_ID = 'gitlab-api-access';
+export const STATE_ID = `${ADDON_ID}/state`;
+export const PANEL_ID = `${ADDON_ID}/panel`;
+
+export const GITLAB_API_ACCESS_UPDATE_EVENT = 'gitlab-api-access.update';
diff --git a/storybook/config/addons/gitlab_api_access/manager.js b/storybook/config/addons/gitlab_api_access/manager.js
new file mode 100644
index 00000000000..77d97c76ee2
--- /dev/null
+++ b/storybook/config/addons/gitlab_api_access/manager.js
@@ -0,0 +1,69 @@
+import React from 'react';
+import { addons, types } from '@storybook/addons';
+import { useAddonState } from '@storybook/api';
+import { AddonPanel, Form } from '@storybook/components';
+import { ADDON_ID, STATE_ID, PANEL_ID, GITLAB_API_ACCESS_UPDATE_EVENT } from './constants';
+
+/**
+ * GitLab API Access is a Storybook extension that allows testing
+ * UI components that depend on GitLab's REST or GraphQL APIs.
+ *
+ * Read https://docs.gitlab.com/ee/development/fe_guide/storybook
+ * for more information.
+ */
+const h = React.createElement.bind(React);
+
+// give a unique name for the panel
+const GitLabAPIParametersPanel = () => {
+ const channel = addons.getChannel();
+ const [state, setState] = useAddonState(STATE_ID, {
+ gitlabURL: process.env.GITLAB_URL,
+ accessToken: process.env.API_ACCESS_TOKEN,
+ });
+ const updateState = (params) => {
+ const newState = {
+ ...state,
+ ...params,
+ };
+
+ setState(newState);
+
+ channel.emit(GITLAB_API_ACCESS_UPDATE_EVENT, newState);
+ };
+
+ const updateGitLabURL = (e) => {
+ updateState({ gitlabURL: e.target.value });
+ };
+
+ const updateAccessToken = (e) => {
+ updateState({ accessToken: e.target.value });
+ };
+
+ channel.emit(GITLAB_API_ACCESS_UPDATE_EVENT, state);
+
+ return h('div', {}, [
+ h(Form.Field, { label: 'GitLab URL' }, [
+ h(Form.Input, {
+ type: 'text',
+ value: state.gitlabURL,
+ placeholder: 'https://gitlab.com',
+ onChange: (e) => updateGitLabURL(e),
+ }),
+ ]),
+ h(Form.Field, { label: 'GitLab access token' }, [
+ h(Form.Input, {
+ type: 'password',
+ value: state.accessToken,
+ onChange: (e) => updateAccessToken(e),
+ }),
+ ]),
+ ]);
+};
+
+addons.register(ADDON_ID, () => {
+ addons.add(PANEL_ID, {
+ type: types.PANEL,
+ title: 'GitLab API Access',
+ render: ({ active, key }) => h(AddonPanel, { active, key }, [h(GitLabAPIParametersPanel)]),
+ });
+});
diff --git a/storybook/config/addons/gitlab_api_access/preview.js b/storybook/config/addons/gitlab_api_access/preview.js
new file mode 100644
index 00000000000..6daeedd0179
--- /dev/null
+++ b/storybook/config/addons/gitlab_api_access/preview.js
@@ -0,0 +1,83 @@
+import { addons } from '@storybook/addons';
+import { FORCE_REMOUNT } from '@storybook/core-events';
+import axios from '~/lib/utils/axios_utils';
+import createDefaultClient from '~/lib/graphql';
+import VueApollo from 'vue-apollo';
+import { GITLAB_API_ACCESS_UPDATE_EVENT } from './constants';
+
+/**
+ * GitLab API Access is a Storybook extension that allows testing
+ * UI components that depend on GitLab's REST or GraphQL APIs.
+ *
+ * Read https://docs.gitlab.com/ee/development/fe_guide/storybook
+ * for more information.
+ */
+const channel = addons.getChannel();
+let gitlabApiAccessParams;
+let refreshApolloClient = false;
+let apolloClient = null;
+
+const setGitLabAPIAccessParams = ({ gitlabURL, accessToken }) => {
+ window.gon.relative_url_root = gitlabURL;
+
+ axios.defaults.headers.common['PRIVATE-TOKEN'] = accessToken;
+ gitlabApiAccessParams = { gitlabURL, accessToken };
+ refreshApolloClient = true;
+};
+
+const createVueApollo = (resolvers = {}, config = {}) => {
+ // Avoids creating a new Apollo client every time that the story rerenders
+ if (!apolloClient || refreshApolloClient) {
+ refreshApolloClient = false;
+ apolloClient = new VueApollo({
+ defaultClient: createDefaultClient(
+ {
+ ...resolvers,
+ },
+ {
+ ...config,
+ httpHeaders: {
+ Authorization: `Bearer ${gitlabApiAccessParams.accessToken}`,
+ },
+ },
+ ),
+ });
+ }
+
+ return apolloClient;
+};
+
+channel.addListener(GITLAB_API_ACCESS_UPDATE_EVENT, (params) => {
+ setGitLabAPIAccessParams(params);
+
+ const storyId = new URLSearchParams(window.location.search).get('id');
+
+ // If we don’t force remount, Vue Apollo is not updated with the new parameters
+ addons.channel.emit(FORCE_REMOUNT, { storyId });
+});
+
+/*
+ * Story decorator used to inject a VueApollo client factory
+ * that contains the GitLab API access parameters.
+ */
+export const withGitLabAPIAccess = (story, context) => {
+ Object.assign(context, { createVueApollo });
+
+ return {
+ components: {
+ story,
+ },
+ template: '<story />',
+ };
+};
+
+/*
+ * Initializes the GitLab API access parameters
+ * with values coming from the environment.
+ */
+export const initializeGitLabAPIAccess = () => {
+ setGitLabAPIAccessParams({
+ gitlabURL: process.env.GITLAB_URL,
+ accessToken: process.env.API_ACCESS_TOKEN,
+ });
+};
diff --git a/storybook/config/gon.js b/storybook/config/gon.js
new file mode 100644
index 00000000000..d85ae3d611b
--- /dev/null
+++ b/storybook/config/gon.js
@@ -0,0 +1,5 @@
+window.gon = {
+ user_color_scheme: 'white',
+ api_version: 'v4',
+ relative_url_root: '',
+};
diff --git a/storybook/config/main.js b/storybook/config/main.js
index 59aa9deb3b5..794a5e20344 100644
--- a/storybook/config/main.js
+++ b/storybook/config/main.js
@@ -5,5 +5,5 @@ module.exports = {
'../../app/assets/javascripts/**/*.stories.js',
IS_EE && '../../ee/app/assets/javascripts/**/*.stories.js',
].filter(Boolean),
- addons: ['@storybook/addon-essentials', '@storybook/addon-a11y', 'storybook-mirage'],
+ addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],
};
diff --git a/storybook/config/manager.js b/storybook/config/manager.js
new file mode 100644
index 00000000000..010f0caf61d
--- /dev/null
+++ b/storybook/config/manager.js
@@ -0,0 +1 @@
+import './addons/gitlab_api_access/manager';
diff --git a/storybook/config/preview.js b/storybook/config/preview.js
index 6f3b8190742..70c8041bb3c 100644
--- a/storybook/config/preview.js
+++ b/storybook/config/preview.js
@@ -1,7 +1,8 @@
-import { withServer } from 'storybook-mirage'; // eslint-disable-line import/no-unresolved
+// Some modules read window.gon on initialization thus we need to define this object before anything else
+import './gon';
import Vue from 'vue';
-import { createMockServer } from 'test_helpers/mock_server';
import translateMixin from '~/vue_shared/translate';
+import { withGitLabAPIAccess, initializeGitLabAPIAccess } from './addons/gitlab_api_access/preview';
const stylesheetsRequireCtx = require.context(
'../../app/assets/stylesheets',
@@ -9,13 +10,12 @@ const stylesheetsRequireCtx = require.context(
/(application|application_utilities|highlight\/themes\/white)\.scss$/,
);
-window.gon = {
- user_color_scheme: 'white',
-};
+initializeGitLabAPIAccess();
+
translateMixin(Vue);
stylesheetsRequireCtx('./application.scss');
stylesheetsRequireCtx('./application_utilities.scss');
stylesheetsRequireCtx('./highlight/themes/white.scss');
-export const decorators = [withServer(createMockServer)];
+export const decorators = [withGitLabAPIAccess];
diff --git a/storybook/package.json b/storybook/package.json
index c6e47bf6b5f..ec3590dea13 100644
--- a/storybook/package.json
+++ b/storybook/package.json
@@ -9,16 +9,20 @@
"vue": "https://gitlab.com/gitlab-org/gitlab/-/issues/340511"
},
"devDependencies": {
+ "react": "16.14.0",
+ "@storybook/addons": "^6.5.10",
+ "@storybook/api": "^6.5.10",
+ "@storybook/components": "^6.5.10",
+ "@storybook/core-events": "^6.5.10",
"@storybook/addon-a11y": "^6.5.10",
"@storybook/addon-actions": "^6.5.10",
"@storybook/addon-controls": "^6.5.10",
"@storybook/addon-essentials": "^6.5.10",
- "@storybook/vue": "6.5.10",
+ "@storybook/vue": "^6.5.10",
"graphql-tag": "^2.12.5",
"postcss-loader": "3.0.0",
"sass": "^1.49.9",
- "sass-loader": "^7.1.0",
- "storybook-mirage": "^0.0.4"
+ "sass-loader": "^7.1.0"
},
"resolutions": {
"chokidar": "^3.5.2"
diff --git a/storybook/yarn.lock b/storybook/yarn.lock
index f960b7e1de9..0e51671b2f9 100644
--- a/storybook/yarn.lock
+++ b/storybook/yarn.lock
@@ -1473,6 +1473,23 @@
global "^4.4.0"
regenerator-runtime "^0.13.7"
+"@storybook/addons@6.5.16", "@storybook/addons@^6.5.10":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.5.16.tgz#07e8f2205f86fa4c9dada719e3e096cb468e3cdd"
+ integrity sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ==
+ dependencies:
+ "@storybook/api" "6.5.16"
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/csf" "0.0.2--canary.4566f4d.1"
+ "@storybook/router" "6.5.16"
+ "@storybook/theming" "6.5.16"
+ "@types/webpack-env" "^1.16.0"
+ core-js "^3.8.2"
+ global "^4.4.0"
+ regenerator-runtime "^0.13.7"
+
"@storybook/api@6.5.10":
version "6.5.10"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.10.tgz#215623844648f0da2ac646fdcdd1345c2e1a8490"
@@ -1496,28 +1513,51 @@
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
-"@storybook/builder-webpack4@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.10.tgz#79e95323577a37349ab3c81193fa249ac5c50173"
- integrity sha512-AoKjsCNoQQoZXYwBDxO8s+yVEd5FjBJAaysEuUTHq2fb81jwLrGcEOo6hjw4jqfugZQIzYUEjPazlvubS78zpw==
+"@storybook/api@6.5.16", "@storybook/api@^6.5.10":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.16.tgz#897915b76de05587fd702951d5d836f708043662"
+ integrity sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA==
+ dependencies:
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/csf" "0.0.2--canary.4566f4d.1"
+ "@storybook/router" "6.5.16"
+ "@storybook/semver" "^7.3.2"
+ "@storybook/theming" "6.5.16"
+ core-js "^3.8.2"
+ fast-deep-equal "^3.1.3"
+ global "^4.4.0"
+ lodash "^4.17.21"
+ memoizerific "^1.11.3"
+ regenerator-runtime "^0.13.7"
+ store2 "^2.12.0"
+ telejson "^6.0.8"
+ ts-dedent "^2.0.0"
+ util-deprecate "^1.0.2"
+
+"@storybook/builder-webpack4@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.16.tgz#ac468d244835a7f3bd01936398fee47244da35c1"
+ integrity sha512-YqDIrVNsUo8r9xc6AxsYDLxVYtMgl5Bxk+8/h1adsOko+jAFhdg6hOcAVxEmoSI0TMASOOVMFlT2hr23ppN2rQ==
dependencies:
"@babel/core" "^7.12.10"
- "@storybook/addons" "6.5.10"
- "@storybook/api" "6.5.10"
- "@storybook/channel-postmessage" "6.5.10"
- "@storybook/channels" "6.5.10"
- "@storybook/client-api" "6.5.10"
- "@storybook/client-logger" "6.5.10"
- "@storybook/components" "6.5.10"
- "@storybook/core-common" "6.5.10"
- "@storybook/core-events" "6.5.10"
- "@storybook/node-logger" "6.5.10"
- "@storybook/preview-web" "6.5.10"
- "@storybook/router" "6.5.10"
+ "@storybook/addons" "6.5.16"
+ "@storybook/api" "6.5.16"
+ "@storybook/channel-postmessage" "6.5.16"
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-api" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/components" "6.5.16"
+ "@storybook/core-common" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/node-logger" "6.5.16"
+ "@storybook/preview-web" "6.5.16"
+ "@storybook/router" "6.5.16"
"@storybook/semver" "^7.3.2"
- "@storybook/store" "6.5.10"
- "@storybook/theming" "6.5.10"
- "@storybook/ui" "6.5.10"
+ "@storybook/store" "6.5.16"
+ "@storybook/theming" "6.5.16"
+ "@storybook/ui" "6.5.16"
"@types/node" "^14.0.10 || ^16.0.0"
"@types/webpack" "^4.41.26"
autoprefixer "^9.8.6"
@@ -1562,13 +1602,26 @@
qs "^6.10.0"
telejson "^6.0.8"
-"@storybook/channel-websocket@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.10.tgz#bd1316a9b555229b215e5054a76b57c503dd8adc"
- integrity sha512-RTXMZbMWCS3xU+4GVIdfnUXsKcwg/WTozy88/5OxaKjGw6KgRedqLAQJKJ6Y5XlnwIcWelirkHj/COwTTXhbPg==
+"@storybook/channel-postmessage@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.5.16.tgz#06167c0a66c06b2b5f8ff01d1dd436fff8119a15"
+ integrity sha512-fZZSN29dsUArWOx7e7lTdMA9+7zijVwCwbvi2Fo4fqhRLh1DsTb/VXfz1FKMCWAjNlcX7QQvV25tnxbqsD6lyw==
dependencies:
- "@storybook/channels" "6.5.10"
- "@storybook/client-logger" "6.5.10"
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ core-js "^3.8.2"
+ global "^4.4.0"
+ qs "^6.10.0"
+ telejson "^6.0.8"
+
+"@storybook/channel-websocket@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.16.tgz#41f69ca9444a4dfbf72580b4696900c5b1d2b817"
+ integrity sha512-wJg2lpBjmRC2GJFzmhB9kxlh109VE58r/0WhFtLbwKvPqsvGf82xkBEl6BtBCvIQ4stzYnj/XijjA8qSi2zpOg==
+ dependencies:
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
core-js "^3.8.2"
global "^4.4.0"
telejson "^6.0.8"
@@ -1582,18 +1635,27 @@
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
-"@storybook/client-api@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.10.tgz#0bc3f68ce014ce1ffd560472a893ba04be370f09"
- integrity sha512-3wBWZl3NvMFgMovgEh+euiARAT2FXzpvTF4Q1gerGMNNDlrGxHnFvSuy4FHg/irtOGLa4yLz43ULFbYtpKw0Lg==
+"@storybook/channels@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.5.16.tgz#3fb9a3b5666ecb951a2d0cf8b0699b084ef2d3c6"
+ integrity sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==
dependencies:
- "@storybook/addons" "6.5.10"
- "@storybook/channel-postmessage" "6.5.10"
- "@storybook/channels" "6.5.10"
- "@storybook/client-logger" "6.5.10"
- "@storybook/core-events" "6.5.10"
+ core-js "^3.8.2"
+ ts-dedent "^2.0.0"
+ util-deprecate "^1.0.2"
+
+"@storybook/client-api@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.16.tgz#13e5a7c3d1f0f951ec4ef51cfcf2c5aafb560e12"
+ integrity sha512-i3UwkzzUFw8I+E6fOcgB5sc4oU2fhvaKnqC1mpd9IYGJ9JN9MnGIaVl3Ko28DtFItu/QabC9JsLIJVripFLktQ==
+ dependencies:
+ "@storybook/addons" "6.5.16"
+ "@storybook/channel-postmessage" "6.5.16"
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
"@storybook/csf" "0.0.2--canary.4566f4d.1"
- "@storybook/store" "6.5.10"
+ "@storybook/store" "6.5.16"
"@types/qs" "^6.9.5"
"@types/webpack-env" "^1.16.0"
core-js "^3.8.2"
@@ -1616,6 +1678,14 @@
core-js "^3.8.2"
global "^4.4.0"
+"@storybook/client-logger@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.5.16.tgz#955cc46b389e7151c9eb1585a75e6a0605af61a1"
+ integrity sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q==
+ dependencies:
+ core-js "^3.8.2"
+ global "^4.4.0"
+
"@storybook/components@6.5.10":
version "6.5.10"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.10.tgz#268e1269bc3d262f7dcec13f96c3b844919687b8"
@@ -1630,21 +1700,35 @@
regenerator-runtime "^0.13.7"
util-deprecate "^1.0.2"
-"@storybook/core-client@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.10.tgz#90c86923236c8efff33d454a0dc552f6df4346b1"
- integrity sha512-THsIjNrOrampTl0Lgfjvfjk1JnktKb4CQLOM80KpQb4cjDqorBjJmErzUkUQ2y3fXvrDmQ/kUREkShET4XEdtA==
+"@storybook/components@6.5.16", "@storybook/components@^6.5.10":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.16.tgz#f8dc51213bc08fe32154be964e1e8b0e2f670ed6"
+ integrity sha512-LzBOFJKITLtDcbW9jXl0/PaG+4xAz25PK8JxPZpIALbmOpYWOAPcO6V9C2heX6e6NgWFMUxjplkULEk9RCQMNA==
dependencies:
- "@storybook/addons" "6.5.10"
- "@storybook/channel-postmessage" "6.5.10"
- "@storybook/channel-websocket" "6.5.10"
- "@storybook/client-api" "6.5.10"
- "@storybook/client-logger" "6.5.10"
- "@storybook/core-events" "6.5.10"
+ "@storybook/client-logger" "6.5.16"
"@storybook/csf" "0.0.2--canary.4566f4d.1"
- "@storybook/preview-web" "6.5.10"
- "@storybook/store" "6.5.10"
- "@storybook/ui" "6.5.10"
+ "@storybook/theming" "6.5.16"
+ core-js "^3.8.2"
+ memoizerific "^1.11.3"
+ qs "^6.10.0"
+ regenerator-runtime "^0.13.7"
+ util-deprecate "^1.0.2"
+
+"@storybook/core-client@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.16.tgz#ed2328fd38c6111fe887f6a91b28d9dc2b17092a"
+ integrity sha512-14IRaDrVtKrQ+gNWC0wPwkCNfkZOKghYV/swCUnQX3rP99defsZK8Hc7xHIYoAiOP5+sc3sweRAxgmFiJeQ1Ig==
+ dependencies:
+ "@storybook/addons" "6.5.16"
+ "@storybook/channel-postmessage" "6.5.16"
+ "@storybook/channel-websocket" "6.5.16"
+ "@storybook/client-api" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/csf" "0.0.2--canary.4566f4d.1"
+ "@storybook/preview-web" "6.5.16"
+ "@storybook/store" "6.5.16"
+ "@storybook/ui" "6.5.16"
airbnb-js-shims "^2.2.1"
ansi-to-html "^0.6.11"
core-js "^3.8.2"
@@ -1712,6 +1796,62 @@
util-deprecate "^1.0.2"
webpack "4"
+"@storybook/core-common@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.5.16.tgz#db80aa6f220a576a83db821f720e103190a914ae"
+ integrity sha512-2qtnKP3TTOzt2cp6LXKRTh7XrI9z5VanMnMTgeoFcA5ebnndD4V6BExQUdYPClE/QooLx6blUWNgS9dFEpjSqQ==
+ dependencies:
+ "@babel/core" "^7.12.10"
+ "@babel/plugin-proposal-class-properties" "^7.12.1"
+ "@babel/plugin-proposal-decorators" "^7.12.12"
+ "@babel/plugin-proposal-export-default-from" "^7.12.1"
+ "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1"
+ "@babel/plugin-proposal-object-rest-spread" "^7.12.1"
+ "@babel/plugin-proposal-optional-chaining" "^7.12.7"
+ "@babel/plugin-proposal-private-methods" "^7.12.1"
+ "@babel/plugin-proposal-private-property-in-object" "^7.12.1"
+ "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+ "@babel/plugin-transform-arrow-functions" "^7.12.1"
+ "@babel/plugin-transform-block-scoping" "^7.12.12"
+ "@babel/plugin-transform-classes" "^7.12.1"
+ "@babel/plugin-transform-destructuring" "^7.12.1"
+ "@babel/plugin-transform-for-of" "^7.12.1"
+ "@babel/plugin-transform-parameters" "^7.12.1"
+ "@babel/plugin-transform-shorthand-properties" "^7.12.1"
+ "@babel/plugin-transform-spread" "^7.12.1"
+ "@babel/preset-env" "^7.12.11"
+ "@babel/preset-react" "^7.12.10"
+ "@babel/preset-typescript" "^7.12.7"
+ "@babel/register" "^7.12.1"
+ "@storybook/node-logger" "6.5.16"
+ "@storybook/semver" "^7.3.2"
+ "@types/node" "^14.0.10 || ^16.0.0"
+ "@types/pretty-hrtime" "^1.0.0"
+ babel-loader "^8.0.0"
+ babel-plugin-macros "^3.0.1"
+ babel-plugin-polyfill-corejs3 "^0.1.0"
+ chalk "^4.1.0"
+ core-js "^3.8.2"
+ express "^4.17.1"
+ file-system-cache "^1.0.5"
+ find-up "^5.0.0"
+ fork-ts-checker-webpack-plugin "^6.0.4"
+ fs-extra "^9.0.1"
+ glob "^7.1.6"
+ handlebars "^4.7.7"
+ interpret "^2.2.0"
+ json5 "^2.2.3"
+ lazy-universal-dotenv "^3.0.1"
+ picomatch "^2.3.0"
+ pkg-dir "^5.0.0"
+ pretty-hrtime "^1.0.3"
+ resolve-from "^5.0.0"
+ slash "^3.0.0"
+ telejson "^6.0.8"
+ ts-dedent "^2.0.0"
+ util-deprecate "^1.0.2"
+ webpack "4"
+
"@storybook/core-events@6.5.10":
version "6.5.10"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.10.tgz#66d87c8ea18db8e448018a16a3d0198ddbcbc683"
@@ -1719,23 +1859,30 @@
dependencies:
core-js "^3.8.2"
-"@storybook/core-server@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.10.tgz#ada3d647833c02cb8c742281c1f314ff866f96f8"
- integrity sha512-jqwpA0ccA8X5ck4esWBid04+cEIVqirdAcqJeNb9IZAD+bRreO4Im8ilzr7jc5AmQ9fkqHs2NByFKh9TITp8NQ==
+"@storybook/core-events@6.5.16", "@storybook/core-events@^6.5.10":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.16.tgz#b1c265dac755007dae172d9d4b72656c9e5d7bb3"
+ integrity sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==
+ dependencies:
+ core-js "^3.8.2"
+
+"@storybook/core-server@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.16.tgz#f40de3413de49388129d29c74e5e48321af03f12"
+ integrity sha512-/3NPfmNyply395Dm0zaVZ8P9aruwO+tPx4D6/jpw8aqrRSwvAMndPMpoMCm0NXcpSm5rdX+Je4S3JW6JcggFkA==
dependencies:
"@discoveryjs/json-ext" "^0.5.3"
- "@storybook/builder-webpack4" "6.5.10"
- "@storybook/core-client" "6.5.10"
- "@storybook/core-common" "6.5.10"
- "@storybook/core-events" "6.5.10"
+ "@storybook/builder-webpack4" "6.5.16"
+ "@storybook/core-client" "6.5.16"
+ "@storybook/core-common" "6.5.16"
+ "@storybook/core-events" "6.5.16"
"@storybook/csf" "0.0.2--canary.4566f4d.1"
- "@storybook/csf-tools" "6.5.10"
- "@storybook/manager-webpack4" "6.5.10"
- "@storybook/node-logger" "6.5.10"
+ "@storybook/csf-tools" "6.5.16"
+ "@storybook/manager-webpack4" "6.5.16"
+ "@storybook/node-logger" "6.5.16"
"@storybook/semver" "^7.3.2"
- "@storybook/store" "6.5.10"
- "@storybook/telemetry" "6.5.10"
+ "@storybook/store" "6.5.16"
+ "@storybook/telemetry" "6.5.16"
"@types/node" "^14.0.10 || ^16.0.0"
"@types/node-fetch" "^2.5.7"
"@types/pretty-hrtime" "^1.0.0"
@@ -1770,18 +1917,18 @@
ws "^8.2.3"
x-default-browser "^0.4.0"
-"@storybook/core@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.10.tgz#15ec8be85943251e25c2c24e80e20dcacc4fed65"
- integrity sha512-K86yYa0tYlMxADlwQTculYvPROokQau09SCVqpsLg3wJCTvYFL4+SIqcYoyBSbFmHOdnYbJgPydjN33MYLiOZQ==
+"@storybook/core@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.16.tgz#ae994f01327fe81b6e652963c35bac7a74f0da06"
+ integrity sha512-CEF3QFTsm/VMnMKtRNr4rRdLeIkIG0g1t26WcmxTdSThNPBd8CsWzQJ7Jqu7CKiut+MU4A1LMOwbwCE5F2gmyA==
dependencies:
- "@storybook/core-client" "6.5.10"
- "@storybook/core-server" "6.5.10"
+ "@storybook/core-client" "6.5.16"
+ "@storybook/core-server" "6.5.16"
-"@storybook/csf-tools@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.10.tgz#ae6f1ebd4951e8978c8fe3e08ddd2bd269bf922b"
- integrity sha512-H77kZQEisu7+skzeIbNZwmE09OqLjwJTeFhLN1pcjxKVa30LEI3pBHcNBxVKqgxl+Yg3KkB7W/ArLO2N+i2ohw==
+"@storybook/csf-tools@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.16.tgz#367889a3ddb33c93261129104ec2958215ec5459"
+ integrity sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A==
dependencies:
"@babel/core" "^7.12.10"
"@babel/generator" "^7.12.11"
@@ -1818,20 +1965,33 @@
lodash "^4.17.21"
regenerator-runtime "^0.13.7"
-"@storybook/manager-webpack4@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.10.tgz#41bae252b863484f293954ef2d2dc80bf3e028f1"
- integrity sha512-N/TlNDhuhARuFipR/ZJ/xEVESz23iIbCsZ4VNehLHm8PpiGlQUehk+jMjWmz5XV0bJItwjRclY+CU3GjZKblfQ==
+"@storybook/docs-tools@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-6.5.16.tgz#1ec5433eeab63a214d37ffc4660cdaec9704ac39"
+ integrity sha512-o+rAWPRGifjBF5xZzTKOqnHN3XQWkl0QFJYVDIiJYJrVll7ExCkpEq/PahOGzIBBV+tpMstJgmKM3lr/lu/jmg==
+ dependencies:
+ "@babel/core" "^7.12.10"
+ "@storybook/csf" "0.0.2--canary.4566f4d.1"
+ "@storybook/store" "6.5.16"
+ core-js "^3.8.2"
+ doctrine "^3.0.0"
+ lodash "^4.17.21"
+ regenerator-runtime "^0.13.7"
+
+"@storybook/manager-webpack4@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.16.tgz#7033228d38f048ceff3d403ba918d7f206b926a5"
+ integrity sha512-5VJZwmQU6AgdsBPsYdu886UKBHQ9SJEnFMaeUxKEclXk+iRsmbzlL4GHKyVd6oGX/ZaecZtcHPR6xrzmA4Ziew==
dependencies:
"@babel/core" "^7.12.10"
"@babel/plugin-transform-template-literals" "^7.12.1"
"@babel/preset-react" "^7.12.10"
- "@storybook/addons" "6.5.10"
- "@storybook/core-client" "6.5.10"
- "@storybook/core-common" "6.5.10"
- "@storybook/node-logger" "6.5.10"
- "@storybook/theming" "6.5.10"
- "@storybook/ui" "6.5.10"
+ "@storybook/addons" "6.5.16"
+ "@storybook/core-client" "6.5.16"
+ "@storybook/core-common" "6.5.16"
+ "@storybook/node-logger" "6.5.16"
+ "@storybook/theming" "6.5.16"
+ "@storybook/ui" "6.5.16"
"@types/node" "^14.0.10 || ^16.0.0"
"@types/webpack" "^4.41.26"
babel-loader "^8.0.0"
@@ -1887,6 +2047,17 @@
npmlog "^5.0.1"
pretty-hrtime "^1.0.3"
+"@storybook/node-logger@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.5.16.tgz#d57fd6204c2abfbc297551d98ad5475dd73207cc"
+ integrity sha512-YjhBKrclQtjhqFNSO+BZK+RXOx6EQypAELJKoLFaawg331e8VUfvUuRCNB3fcEWp8G9oH13PQQte0OTjLyyOYg==
+ dependencies:
+ "@types/npmlog" "^4.1.2"
+ chalk "^4.1.0"
+ core-js "^3.8.2"
+ npmlog "^5.0.1"
+ pretty-hrtime "^1.0.3"
+
"@storybook/postinstall@6.5.10":
version "6.5.10"
resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.5.10.tgz#b25378da036bce7b318c6732733aa5ad43449f37"
@@ -1916,6 +2087,28 @@
unfetch "^4.2.0"
util-deprecate "^1.0.2"
+"@storybook/preview-web@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-6.5.16.tgz#1d32a72be25776f9597e33ffc1914f3430fae689"
+ integrity sha512-IJnvfe2sKCfk7apN9Fu9U8qibbarrPX5JB55ZzK1amSHVmSDuYk5MIMc/U3NnSQNnvd1DO5v/zMcGgj563hrtg==
+ dependencies:
+ "@storybook/addons" "6.5.16"
+ "@storybook/channel-postmessage" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/csf" "0.0.2--canary.4566f4d.1"
+ "@storybook/store" "6.5.16"
+ ansi-to-html "^0.6.11"
+ core-js "^3.8.2"
+ global "^4.4.0"
+ lodash "^4.17.21"
+ qs "^6.10.0"
+ regenerator-runtime "^0.13.7"
+ synchronous-promise "^2.0.15"
+ ts-dedent "^2.0.0"
+ unfetch "^4.2.0"
+ util-deprecate "^1.0.2"
+
"@storybook/router@6.5.10":
version "6.5.10"
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.10.tgz#b0c342e080c1d2b5344603bc43a6c75734a4a879"
@@ -1927,6 +2120,17 @@
qs "^6.10.0"
regenerator-runtime "^0.13.7"
+"@storybook/router@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.16.tgz#28fb4d34e8219351a40bee1fc94dcacda6e1bd8b"
+ integrity sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==
+ dependencies:
+ "@storybook/client-logger" "6.5.16"
+ core-js "^3.8.2"
+ memoizerific "^1.11.3"
+ qs "^6.10.0"
+ regenerator-runtime "^0.13.7"
+
"@storybook/semver@^7.3.2":
version "7.3.2"
resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0"
@@ -1972,13 +2176,34 @@
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
-"@storybook/telemetry@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.10.tgz#742b05a55dfe8470ce4cb371f3f3f2c02f96e816"
- integrity sha512-+M5HILDFS8nDumLxeSeAwi1MTzIuV6UWzV4yB2wcsEXOBTdplcl9oYqFKtlst78oOIdGtpPYxYfivDlqxC2K4g==
+"@storybook/store@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/store/-/store-6.5.16.tgz#b308701293a3a11bfcc766770584495874fd17da"
+ integrity sha512-g+bVL5hmMq/9cM51K04e37OviUPHT0rHHrRm5wj/hrf18Kd9120b3sxdQ5Dc+HZ292yuME0n+cyrQPTYx9Epmw==
dependencies:
- "@storybook/client-logger" "6.5.10"
- "@storybook/core-common" "6.5.10"
+ "@storybook/addons" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/csf" "0.0.2--canary.4566f4d.1"
+ core-js "^3.8.2"
+ fast-deep-equal "^3.1.3"
+ global "^4.4.0"
+ lodash "^4.17.21"
+ memoizerific "^1.11.3"
+ regenerator-runtime "^0.13.7"
+ slash "^3.0.0"
+ stable "^0.1.8"
+ synchronous-promise "^2.0.15"
+ ts-dedent "^2.0.0"
+ util-deprecate "^1.0.2"
+
+"@storybook/telemetry@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.16.tgz#b13c8133e02c28e37b7716c987e7414b1ddc5363"
+ integrity sha512-CWr5Uko1l9jJW88yTXsZTj/3GTabPvw0o7pDPOXPp8JRZiJTxv1JFaFCafhK9UzYbgcRuGfCC8kEWPZims7iKA==
+ dependencies:
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core-common" "6.5.16"
chalk "^4.1.0"
core-js "^3.8.2"
detect-package-manager "^2.0.1"
@@ -2000,38 +2225,48 @@
memoizerific "^1.11.3"
regenerator-runtime "^0.13.7"
-"@storybook/ui@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.10.tgz#f56095a1a39ae5a203f2ac7f3dba86341a5927d5"
- integrity sha512-6iaoaRAiTqB1inTw35vao+5hjcDE0Qa0A3a9ZIeNa6yHvpB1k0lO/N/0PMrRdVvySYpXVD1iry4z4QYdo1rU+w==
+"@storybook/theming@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.5.16.tgz#b999bdb98945b605b93b9dfdf7408535b701e2aa"
+ integrity sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==
dependencies:
- "@storybook/addons" "6.5.10"
- "@storybook/api" "6.5.10"
- "@storybook/channels" "6.5.10"
- "@storybook/client-logger" "6.5.10"
- "@storybook/components" "6.5.10"
- "@storybook/core-events" "6.5.10"
- "@storybook/router" "6.5.10"
+ "@storybook/client-logger" "6.5.16"
+ core-js "^3.8.2"
+ memoizerific "^1.11.3"
+ regenerator-runtime "^0.13.7"
+
+"@storybook/ui@6.5.16":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.16.tgz#c73bf456e672ecf2370b4365070088487fc0ce57"
+ integrity sha512-rHn/n12WM8BaXtZ3IApNZCiS+C4Oc5+Lkl4MoctX8V7QSml0SxZBB5hsJ/AiWkgbRxjQpa/L/Nt7/Qw0FjTH/A==
+ dependencies:
+ "@storybook/addons" "6.5.16"
+ "@storybook/api" "6.5.16"
+ "@storybook/channels" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/components" "6.5.16"
+ "@storybook/core-events" "6.5.16"
+ "@storybook/router" "6.5.16"
"@storybook/semver" "^7.3.2"
- "@storybook/theming" "6.5.10"
+ "@storybook/theming" "6.5.16"
core-js "^3.8.2"
memoizerific "^1.11.3"
qs "^6.10.0"
regenerator-runtime "^0.13.7"
resolve-from "^5.0.0"
-"@storybook/vue@6.5.10":
- version "6.5.10"
- resolved "https://registry.yarnpkg.com/@storybook/vue/-/vue-6.5.10.tgz#9074ba517d9dbf7587319b9d3c600c2fbd6c087a"
- integrity sha512-4MYYvRPkqTBqQUjCNXiTM/PJ6qfzKaECFtEe0H7TG+WP+TuKCCfTY2u1q4ru2qjf8BcSXUfpIWPlfEpZh7wdaQ==
+"@storybook/vue@^6.5.10":
+ version "6.5.16"
+ resolved "https://registry.yarnpkg.com/@storybook/vue/-/vue-6.5.16.tgz#e548995f468e1503a00c324814e3ab76cfee2c82"
+ integrity sha512-CFpBTAnOC4RZUKf5ZXQXj098D4HgZ+RyB4u45OhFbJFCDXnJQpRk0ANkJ2lyGPYr7/TgfsfZlq2FN8ilPqkk5A==
dependencies:
- "@storybook/addons" "6.5.10"
- "@storybook/client-logger" "6.5.10"
- "@storybook/core" "6.5.10"
- "@storybook/core-common" "6.5.10"
+ "@storybook/addons" "6.5.16"
+ "@storybook/client-logger" "6.5.16"
+ "@storybook/core" "6.5.16"
+ "@storybook/core-common" "6.5.16"
"@storybook/csf" "0.0.2--canary.4566f4d.1"
- "@storybook/docs-tools" "6.5.10"
- "@storybook/store" "6.5.10"
+ "@storybook/docs-tools" "6.5.16"
+ "@storybook/store" "6.5.16"
"@types/node" "^14.14.20 || ^16.0.0"
"@types/webpack-env" "^1.16.0"
core-js "^3.8.2"
@@ -5839,6 +6074,11 @@ json5@^2.1.2, json5@^2.1.3:
dependencies:
minimist "^1.2.5"
+json5@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
+ integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+
jsonfile@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
@@ -8335,11 +8575,6 @@ store2@^2.12.0:
resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf"
integrity sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw==
-storybook-mirage@^0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/storybook-mirage/-/storybook-mirage-0.0.4.tgz#572e5d310ad8f0dd963e5c341aa2402f8ed07749"
- integrity sha512-oGjsxyxmedXQtsVW1DDwKM1RocAD5zClFeOFtAhK46NcGXLJ31m2WQg5kL7YqrsriorrCZq4vvSy05DVCD7BKQ==
-
stream-browserify@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"