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:
-rw-r--r--.rubocop.yml3
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue5
-rw-r--r--app/assets/javascripts/monitoring/components/embeds/metric_embed.vue18
-rw-r--r--app/assets/javascripts/monitoring/constants.js25
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js4
-rw-r--r--app/assets/javascripts/monitoring/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js18
-rw-r--r--app/assets/javascripts/releases/components/app_index.vue2
-rw-r--r--app/assets/javascripts/releases/components/release_block.vue10
-rw-r--r--app/workers/reactive_caching_worker.rb2
-rw-r--r--changelogs/unreleased/nfriend-fix-guest-user-releases.yml5
-rw-r--r--changelogs/unreleased/refactor-member-spec.yml5
-rw-r--r--changelogs/unreleased/refator-wiki-page.yml5
-rw-r--r--doc/administration/high_availability/README.md161
-rw-r--r--doc/development/documentation/styleguide.md9
-rw-r--r--doc/user/application_security/container_scanning/index.md1
-rw-r--r--doc/user/project/issues/img/issue_health_status_v12_10.pngbin0 -> 35262 bytes
-rw-r--r--doc/user/project/issues/index.md10
-rw-r--r--locale/gitlab.pot3
-rw-r--r--qa/qa/runtime/browser.rb4
-rw-r--r--spec/features/projects/releases/user_views_releases_spec.rb114
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js16
-rw-r--r--spec/frontend/monitoring/components/embeds/metric_embed_spec.js3
-rw-r--r--spec/frontend/monitoring/store/actions_spec.js10
-rw-r--r--spec/frontend/monitoring/store/mutations_spec.js52
-rw-r--r--spec/frontend/releases/components/release_block_spec.js8
-rw-r--r--spec/models/member_spec.rb4
-rw-r--r--spec/models/wiki_page_spec.rb2
-rw-r--r--spec/workers/reactive_caching_worker_spec.rb8
29 files changed, 324 insertions, 184 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index de04e0cbcfe..4b3931a7cab 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -410,13 +410,10 @@ RSpec/RepeatedExample:
- 'spec/models/ability_spec.rb'
- 'spec/models/ci/build_spec.rb'
- 'spec/models/concerns/issuable_spec.rb'
- - 'spec/models/member_spec.rb'
- 'spec/models/project_services/chat_message/pipeline_message_spec.rb'
- - 'spec/models/wiki_page_spec.rb'
- 'spec/routing/admin_routing_spec.rb'
- 'spec/rubocop/cop/migration/update_large_table_spec.rb'
- 'spec/services/notification_service_spec.rb'
- 'spec/services/web_hook_service_spec.rb'
- - 'ee/spec/models/group_spec.rb'
- 'ee/spec/services/boards/lists/update_service_spec.rb'
- 'ee/spec/services/geo/repository_verification_primary_service_spec.rb'
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 531d23bb6e5..0ceea21fda3 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -250,7 +250,7 @@ export default {
},
},
created() {
- this.setEndpoints({
+ this.setInitialState({
metricsEndpoint: this.metricsEndpoint,
deploymentsEndpoint: this.deploymentsEndpoint,
dashboardEndpoint: this.dashboardEndpoint,
@@ -258,6 +258,7 @@ export default {
currentDashboard: this.currentDashboard,
projectPath: this.projectPath,
logsPath: this.logsPath,
+ currentEnvironmentName: this.currentEnvironmentName,
});
},
mounted() {
@@ -273,7 +274,7 @@ export default {
'setTimeRange',
'fetchData',
'setGettingStartedEmptyState',
- 'setEndpoints',
+ 'setInitialState',
'setPanelGroupMetrics',
'filterEnvironments',
]),
diff --git a/app/assets/javascripts/monitoring/components/embeds/metric_embed.vue b/app/assets/javascripts/monitoring/components/embeds/metric_embed.vue
index 8a44e6bd737..3f8b0f76997 100644
--- a/app/assets/javascripts/monitoring/components/embeds/metric_embed.vue
+++ b/app/assets/javascripts/monitoring/components/embeds/metric_embed.vue
@@ -64,7 +64,10 @@ export default {
},
},
mounted() {
- this.setInitialState();
+ this.setInitialState({
+ dashboardEndpoint: removeTimeRangeParams(this.dashboardUrl),
+ });
+ this.setShowErrorBanner(false);
this.setTimeRange(this.timeRange);
this.fetchDashboard();
@@ -90,11 +93,8 @@ export default {
fetchDashboard(dispatch, payload) {
return dispatch(`${this.namespace}/fetchDashboard`, payload);
},
- setEndpoints(dispatch, payload) {
- return dispatch(`${this.namespace}/setEndpoints`, payload);
- },
- setFeatureFlags(dispatch, payload) {
- return dispatch(`${this.namespace}/setFeatureFlags`, payload);
+ setInitialState(dispatch, payload) {
+ return dispatch(`${this.namespace}/setInitialState`, payload);
},
setShowErrorBanner(dispatch, payload) {
return dispatch(`${this.namespace}/setShowErrorBanner`, payload);
@@ -108,12 +108,6 @@ export default {
this.elWidth = this.$el.clientWidth;
}, sidebarAnimationDuration);
},
- setInitialState() {
- this.setEndpoints({
- dashboardEndpoint: removeTimeRangeParams(this.dashboardUrl),
- });
- this.setShowErrorBanner(false);
- },
},
};
</script>
diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js
index f9a911ddf03..3990a8d1f61 100644
--- a/app/assets/javascripts/monitoring/constants.js
+++ b/app/assets/javascripts/monitoring/constants.js
@@ -79,3 +79,28 @@ export const dateFormats = {
timeOfDay: 'h:MM TT',
default: 'dd mmm yyyy, h:MMTT',
};
+
+/**
+ * These Vuex store properties are allowed to be
+ * replaced dynamically after component has been created
+ * and initial state has been set.
+ *
+ * Currently used in `receiveMetricsDashboardSuccess` action.
+ */
+export const endpointKeys = [
+ 'metricsEndpoint',
+ 'deploymentsEndpoint',
+ 'dashboardEndpoint',
+ 'dashboardsEndpoint',
+ 'currentDashboard',
+ 'projectPath',
+ 'logsPath',
+];
+
+/**
+ * These Vuex store properties are set as soon as the
+ * dashboard component has been created. The values are
+ * passed as data-* attributes and received by dashboard
+ * as Vue props.
+ */
+export const initialStateKeys = [...endpointKeys, 'currentEnvironmentName'];
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index 7ea43d57039..86f416240c8 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -30,8 +30,8 @@ export const setGettingStartedEmptyState = ({ commit }) => {
commit(types.SET_GETTING_STARTED_EMPTY_STATE);
};
-export const setEndpoints = ({ commit }, endpoints) => {
- commit(types.SET_ENDPOINTS, endpoints);
+export const setInitialState = ({ commit }, initialState) => {
+ commit(types.SET_INITIAL_STATE, initialState);
};
export const setTimeRange = ({ commit }, timeRange) => {
diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js
index 8873142accc..09eb7dc1673 100644
--- a/app/assets/javascripts/monitoring/stores/mutation_types.js
+++ b/app/assets/javascripts/monitoring/stores/mutation_types.js
@@ -17,6 +17,7 @@ export const RECEIVE_METRIC_RESULT_FAILURE = 'RECEIVE_METRIC_RESULT_FAILURE';
export const SET_TIME_RANGE = 'SET_TIME_RANGE';
export const SET_ALL_DASHBOARDS = 'SET_ALL_DASHBOARDS';
export const SET_ENDPOINTS = 'SET_ENDPOINTS';
+export const SET_INITIAL_STATE = 'SET_INITIAL_STATE';
export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE';
export const SET_NO_DATA_EMPTY_STATE = 'SET_NO_DATA_EMPTY_STATE';
export const SET_SHOW_ERROR_BANNER = 'SET_SHOW_ERROR_BANNER';
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index 7aac98821c9..2e10d189087 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -3,7 +3,7 @@ import pick from 'lodash/pick';
import * as types from './mutation_types';
import { mapToDashboardViewModel, normalizeQueryResult } from './utils';
import { BACKOFF_TIMEOUT } from '../../lib/utils/common_utils';
-import { metricStates } from '../constants';
+import { endpointKeys, initialStateKeys, metricStates } from '../constants';
import httpStatusCodes from '~/lib/utils/http_status';
/**
@@ -150,19 +150,11 @@ export default {
state: emptyStateFromError(error),
});
},
+ [types.SET_INITIAL_STATE](state, initialState = {}) {
+ Object.assign(state, pick(initialState, initialStateKeys));
+ },
[types.SET_ENDPOINTS](state, endpoints = {}) {
- const endpointKeys = [
- 'metricsEndpoint',
- 'deploymentsEndpoint',
- 'dashboardEndpoint',
- 'dashboardsEndpoint',
- 'currentDashboard',
- 'projectPath',
- 'logsPath',
- ];
- Object.entries(pick(endpoints, endpointKeys)).forEach(([key, value]) => {
- state[key] = value;
- });
+ Object.assign(state, pick(endpoints, endpointKeys));
},
[types.SET_TIME_RANGE](state, timeRange) {
state.timeRange = timeRange;
diff --git a/app/assets/javascripts/releases/components/app_index.vue b/app/assets/javascripts/releases/components/app_index.vue
index 511b3cda9c8..215a376fc76 100644
--- a/app/assets/javascripts/releases/components/app_index.vue
+++ b/app/assets/javascripts/releases/components/app_index.vue
@@ -103,7 +103,7 @@ export default {
<div v-else-if="shouldRenderSuccessState" class="js-success-state">
<release-block
v-for="(release, index) in releases"
- :key="release.tagName"
+ :key="index"
:release="release"
:class="{ 'linked-card': releases.length > 1 && index !== releases.length - 1 }"
/>
diff --git a/app/assets/javascripts/releases/components/release_block.vue b/app/assets/javascripts/releases/components/release_block.vue
index 515aa629476..58045b57d80 100644
--- a/app/assets/javascripts/releases/components/release_block.vue
+++ b/app/assets/javascripts/releases/components/release_block.vue
@@ -37,7 +37,11 @@ export default {
};
},
computed: {
- id() {
+ htmlId() {
+ if (!this.release.tagName) {
+ return null;
+ }
+
return slugify(this.release.tagName);
},
assets() {
@@ -72,7 +76,7 @@ export default {
this.renderGFM();
const hash = getLocationHash();
- if (hash && slugify(hash) === this.id) {
+ if (hash && slugify(hash) === this.htmlId) {
this.isHighlighted = true;
setTimeout(() => {
this.isHighlighted = false;
@@ -89,7 +93,7 @@ export default {
};
</script>
<template>
- <div :id="id" :class="{ 'bg-line-target-blue': isHighlighted }" class="card release-block">
+ <div :id="htmlId" :class="{ 'bg-line-target-blue': isHighlighted }" class="card release-block">
<release-block-header :release="release" />
<div class="card-body">
<div v-if="shouldRenderMilestoneInfo">
diff --git a/app/workers/reactive_caching_worker.rb b/app/workers/reactive_caching_worker.rb
index 1921ac6619b..513033281e5 100644
--- a/app/workers/reactive_caching_worker.rb
+++ b/app/workers/reactive_caching_worker.rb
@@ -15,7 +15,7 @@ class ReactiveCachingWorker # rubocop:disable Scalability/IdempotentWorker
def self.context_for_arguments(arguments)
class_name, *_other_args = arguments
- Gitlab::ApplicationContext.new(related_class: class_name)
+ Gitlab::ApplicationContext.new(related_class: class_name.to_s)
end
def perform(class_name, id, *args)
diff --git a/changelogs/unreleased/nfriend-fix-guest-user-releases.yml b/changelogs/unreleased/nfriend-fix-guest-user-releases.yml
new file mode 100644
index 00000000000..784fd421fc0
--- /dev/null
+++ b/changelogs/unreleased/nfriend-fix-guest-user-releases.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Releases page for Guest users of private projects
+merge_request: 28447
+author:
+type: fixed
diff --git a/changelogs/unreleased/refactor-member-spec.yml b/changelogs/unreleased/refactor-member-spec.yml
new file mode 100644
index 00000000000..21288aa9ad9
--- /dev/null
+++ b/changelogs/unreleased/refactor-member-spec.yml
@@ -0,0 +1,5 @@
+---
+title: Refactor duplicate member specs
+merge_request: 28574
+author: Rajendra Kadam
+type: added
diff --git a/changelogs/unreleased/refator-wiki-page.yml b/changelogs/unreleased/refator-wiki-page.yml
new file mode 100644
index 00000000000..91fc65354d9
--- /dev/null
+++ b/changelogs/unreleased/refator-wiki-page.yml
@@ -0,0 +1,5 @@
+---
+title: Refactor duplicate specs in wiki page specs
+merge_request: 28551
+author: Rajendra Kadam
+type: added
diff --git a/doc/administration/high_availability/README.md b/doc/administration/high_availability/README.md
index 2bc2f28e4c5..b5258a66e59 100644
--- a/doc/administration/high_availability/README.md
+++ b/doc/administration/high_availability/README.md
@@ -161,20 +161,20 @@ On different cloud vendors a best effort like for like can be used.
- **Test RPS rates:** API: 40 RPS, Web: 4 RPS, Git: 4 RPS
- **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues)
-| Service | Nodes | Configuration[^8] | GCP type |
-| ----------------------------|-------|-----------------------|---------------|
-| GitLab Rails[^1] | 3 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 |
-| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Gitaly[^2] [^5] [^7] | X | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis[^3] | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 |
-| Consul + Sentinel[^3] | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 |
-| Cloud Object Storage[^4] | - | - | - |
-| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
+| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] |
+| ----------------------------|-------|-----------------------|---------------|--------------|
+| GitLab Rails[^1] | 3 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge |
+| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Gitaly[^2] [^5] [^7] | X | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis[^3] | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large |
+| Consul + Sentinel[^3] | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large |
+| Cloud Object Storage[^4] | - | - | - | - |
+| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
### 5,000 user configuration
@@ -182,20 +182,20 @@ On different cloud vendors a best effort like for like can be used.
- **Test RPS rates:** API: 100 RPS, Web: 10 RPS, Git: 10 RPS
- **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues)
-| Service | Nodes | Configuration[^8] | GCP type |
-| ----------------------------|-------|-----------------------|---------------|
-| GitLab Rails[^1] | 3 | 16 vCPU, 14.4GB Memory | n1-highcpu-16 |
-| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Gitaly[^2] [^5] [^7] | X | 8 vCPU, 30GB Memory | n1-standard-8 |
-| Redis[^3] | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 |
-| Consul + Sentinel[^3] | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 |
-| Cloud Object Storage[^4] | - | - | - |
-| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
+| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] |
+| ----------------------------|-------|------------------------|---------------|--------------|
+| GitLab Rails[^1] | 3 | 16 vCPU, 14.4GB Memory | n1-highcpu-16 | c5.4xlarge |
+| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Gitaly[^2] [^5] [^7] | X | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge |
+| Redis[^3] | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large |
+| Consul + Sentinel[^3] | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large |
+| Cloud Object Storage[^4] | - | - | - | - |
+| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
### 10,000 user configuration
@@ -203,23 +203,23 @@ On different cloud vendors a best effort like for like can be used.
- **Test RPS rates:** API: 200 RPS, Web: 20 RPS, Git: 20 RPS
- **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues)
-| Service | Nodes | Configuration[^8] | GCP type |
-| ----------------------------|-------|-----------------------|---------------|
-| GitLab Rails[^1] | 3 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 |
-| PostgreSQL | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Gitaly[^2] [^5] [^7] | X | 16 vCPU, 60GB Memory | n1-standard-16 |
-| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small |
-| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small |
-| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Cloud Object Storage[^4] | - | - | - |
-| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
+| Service | Nodes | GCP Configuration[^8] | GCP type | AWS type[^9] |
+| ----------------------------|-------|------------------------|----------------|--------------|
+| GitLab Rails[^1] | 3 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge |
+| PostgreSQL | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Gitaly[^2] [^5] [^7] | X | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge |
+| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small |
+| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small |
+| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Cloud Object Storage[^4] | - | - | - | - |
+| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
### 25,000 user configuration
@@ -227,23 +227,23 @@ On different cloud vendors a best effort like for like can be used.
- **Test RPS rates:** API: 500 RPS, Web: 50 RPS, Git: 50 RPS
- **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues)
-| Service | Nodes | Configuration[^8] | GCP type |
-| ----------------------------|-------|-----------------------|---------------|
-| GitLab Rails[^1] | 5 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 |
-| PostgreSQL | 3 | 8 vCPU, 30GB Memory | n1-standard-8 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Gitaly[^2] [^5] [^7] | X | 32 vCPU, 120GB Memory | n1-standard-32 |
-| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small |
-| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small |
-| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Cloud Object Storage[^4] | - | - | - |
-| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Internal load balancing node[^6] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
+| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] |
+| ----------------------------|-------|------------------------|----------------|--------------|
+| GitLab Rails[^1] | 5 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge |
+| PostgreSQL | 3 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Gitaly[^2] [^5] [^7] | X | 32 vCPU, 120GB Memory | n1-standard-32 | m5.8xlarge |
+| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small |
+| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small |
+| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Cloud Object Storage[^4] | - | - | - | - |
+| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Internal load balancing node[^6] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
### 50,000 user configuration
@@ -251,23 +251,23 @@ On different cloud vendors a best effort like for like can be used.
- **Test RPS rates:** API: 1000 RPS, Web: 100 RPS, Git: 100 RPS
- **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues)
-| Service | Nodes | Configuration[^8] | GCP type |
-| ----------------------------|-------|-----------------------|---------------|
-| GitLab Rails[^1] | 12 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 |
-| PostgreSQL | 3 | 16 vCPU, 60GB Memory | n1-standard-16 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Gitaly[^2] [^5] [^7] | X | 64 vCPU, 240GB Memory | n1-standard-64 |
-| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small |
-| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small |
-| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 |
-| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| Cloud Object Storage[^4] | - | - | - |
-| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 |
-| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 |
-| Internal load balancing node[^6] | 1 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 |
+| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] |
+| ----------------------------|-------|------------------------|----------------|--------------|
+| GitLab Rails[^1] | 12 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge |
+| PostgreSQL | 3 | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Gitaly[^2] [^5] [^7] | X | 64 vCPU, 240GB Memory | n1-standard-64 | m5.16xlarge |
+| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small |
+| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small |
+| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge |
+| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| Cloud Object Storage[^4] | - | - | - | - |
+| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge |
+| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large |
+| Internal load balancing node[^6] | 1 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge |
[^1]: In our architectures we run each GitLab Rails node using the Puma webserver
and have its number of workers set to 90% of available CPUs along with 4 threads.
@@ -311,3 +311,6 @@ On different cloud vendors a best effort like for like can be used.
or higher, are required for your CPU or Node counts accordingly. For more info a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
+
+[^9]: AWS-equivalent configurations are rough suggestions and may change in the
+ future. They have not yet been tested and validated.
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 940c660dc35..c3f134b569d 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -1460,6 +1460,15 @@ Example response:
```
````
+### Fake user information
+
+You may need to demonstrate an API call or a cURL command that includes the name
+and email address of a user. Don't use real user information in API calls:
+
+- **Email addresses**: Use an email address ending in `example.com`.
+- **Names**: Use strings like `Example Username`. Alternatively, use diverse or non-gendered names with
+ common surnames, such as `Sidney Jones`, `Zhang Wei`. or `Maria Garcia`.
+
### Fake tokens
There may be times where a token is needed to demonstrate an API call using
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 8d0cb8507e6..a368fa4ae02 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -170,6 +170,7 @@ using environment variables.
| Environment Variable | Description | Default |
| ------ | ------ | ------ |
| `KLAR_TRACE` | Set to true to enable more verbose output from klar. | `"false"` |
+| `CLAIR_TRACE` | Set to true to enable more verbose output from the clair server process. | `"false"` |
| `DOCKER_USER` | Username for accessing a Docker registry requiring authentication. | `$CI_REGISTRY_USER` |
| `DOCKER_PASSWORD` | Password for accessing a Docker registry requiring authentication. | `$CI_REGISTRY_PASSWORD` |
| `CLAIR_OUTPUT` | Severity level threshold. Vulnerabilities with severity level higher than or equal to this threshold will be outputted. Supported levels are `Unknown`, `Negligible`, `Low`, `Medium`, `High`, `Critical` and `Defcon1`. | `Unknown` |
diff --git a/doc/user/project/issues/img/issue_health_status_v12_10.png b/doc/user/project/issues/img/issue_health_status_v12_10.png
new file mode 100644
index 00000000000..bcd6af144fb
--- /dev/null
+++ b/doc/user/project/issues/img/issue_health_status_v12_10.png
Binary files differ
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index e213f92c297..af19c7f2b4a 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -168,15 +168,15 @@ requires [GraphQL](../../../api/graphql/index.md) to be enabled.
### Status **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36427) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36427) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
To help you track the status of your issues, you can assign a status to each issue to flag work that's progressing as planned or needs attention to keep on schedule:
-- `On track` (green)
-- `Needs attention` (amber)
-- `At risk` (red)
+- **On track** (green)
+- **Needs attention** (amber)
+- **At risk** (red)
-!["On track" health status on an issue](img/issue_health_status_v12_9.png)
+!["On track" health status on an issue](img/issue_health_status_v12_10.png)
---
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b2d55f35a62..75d4542e2e3 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -24701,6 +24701,9 @@ msgstr ""
msgid "remove due date"
msgstr ""
+msgid "remove status"
+msgstr ""
+
msgid "remove weight"
msgstr ""
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index 7777d06b6f5..adb496e9ef0 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -51,9 +51,7 @@ module QA
metadata[:type] = :feature
end
- config.around(:each) do |example|
- example.run
-
+ config.append_after(:each) do |example|
if example.metadata[:screenshot]
screenshot = example.metadata[:screenshot][:image] || example.metadata[:screenshot][:html]
example.metadata[:stdout] = %{[[ATTACHMENT|#{screenshot}]]}
diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb
index a4ba81ffeb9..e21d8ec16e1 100644
--- a/spec/features/projects/releases/user_views_releases_spec.rb
+++ b/spec/features/projects/releases/user_views_releases_spec.rb
@@ -3,41 +3,33 @@
require 'spec_helper'
describe 'User views releases', :js do
- let!(:project) { create(:project, :repository) }
- let!(:release) { create(:release, project: project ) }
- let!(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, :private) }
+ let_it_be(:release) { create(:release, project: project, name: 'The first release' ) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:guest) { create(:user) }
before do
- project.add_maintainer(user)
-
- gitlab_sign_in(user)
+ project.add_maintainer(maintainer)
+ project.add_guest(guest)
end
- it 'sees the release' do
- visit project_releases_path(project)
-
- expect(page).to have_content(release.name)
- expect(page).to have_content(release.tag)
- expect(page).not_to have_content('Upcoming Release')
- end
-
- context 'when there is a link as an asset' do
- let!(:release_link) { create(:release_link, release: release, url: url ) }
- let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release) << release_link.filepath }
+ context('when the user is a maintainer') do
+ before do
+ gitlab_sign_in(maintainer)
+ end
- it 'sees the link' do
+ it 'sees the release' do
visit project_releases_path(project)
- page.within('.js-assets-list') do
- expect(page).to have_link release_link.name, href: direct_asset_link
- expect(page).not_to have_content('(external source)')
- end
+ expect(page).to have_content(release.name)
+ expect(page).to have_content(release.tag)
+ expect(page).not_to have_content('Upcoming Release')
end
- context 'when there is a link redirect' do
- let!(:release_link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) }
+ context 'when there is a link as an asset' do
+ let!(:release_link) { create(:release_link, release: release, url: url ) }
let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
+ let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release) << release_link.filepath }
it 'sees the link' do
visit project_releases_path(project)
@@ -47,39 +39,73 @@ describe 'User views releases', :js do
expect(page).not_to have_content('(external source)')
end
end
- end
- context 'when url points to external resource' do
- let(:url) { 'http://google.com/download' }
+ context 'when there is a link redirect' do
+ let!(:release_link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) }
+ let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- it 'sees that the link is external resource' do
- visit project_releases_path(project)
+ it 'sees the link' do
+ visit project_releases_path(project)
- page.within('.js-assets-list') do
- expect(page).to have_content('(external source)')
+ page.within('.js-assets-list') do
+ expect(page).to have_link release_link.name, href: direct_asset_link
+ expect(page).not_to have_content('(external source)')
+ end
+ end
+ end
+
+ context 'when url points to external resource' do
+ let(:url) { 'http://google.com/download' }
+
+ it 'sees that the link is external resource' do
+ visit project_releases_path(project)
+
+ page.within('.js-assets-list') do
+ expect(page).to have_content('(external source)')
+ end
end
end
end
- end
- context 'with an upcoming release' do
- let(:tomorrow) { Time.zone.now + 1.day }
- let!(:release) { create(:release, project: project, released_at: tomorrow ) }
+ context 'with an upcoming release' do
+ let(:tomorrow) { Time.zone.now + 1.day }
+ let!(:release) { create(:release, project: project, released_at: tomorrow ) }
- it 'sees the upcoming tag' do
- visit project_releases_path(project)
+ it 'sees the upcoming tag' do
+ visit project_releases_path(project)
+
+ expect(page).to have_content('Upcoming Release')
+ end
+ end
+
+ context 'with a tag containing a slash' do
+ it 'sees the release' do
+ release = create :release, :with_evidence, project: project, tag: 'debian/2.4.0-1'
+ visit project_releases_path(project)
- expect(page).to have_content('Upcoming Release')
+ expect(page).to have_content(release.name)
+ expect(page).to have_content(release.tag)
+ end
end
end
- context 'with a tag containing a slash' do
- it 'sees the release' do
- release = create :release, :with_evidence, project: project, tag: 'debian/2.4.0-1'
+ context('when the user is a guest') do
+ before do
+ gitlab_sign_in(guest)
+ end
+
+ it 'renders release info except for Git-related data' do
visit project_releases_path(project)
- expect(page).to have_content(release.name)
- expect(page).to have_content(release.tag)
+ within('.release-block') do
+ expect(page).to have_content(release.description)
+
+ # The following properties (sometimes) include Git info,
+ # so they are not rendered for Guest users
+ expect(page).not_to have_content(release.name)
+ expect(page).not_to have_content(release.tag)
+ expect(page).not_to have_content(release.commit.short_id)
+ end
end
end
end
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index b9d838085a1..ec25c9e169a 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -88,11 +88,17 @@ describe('Dashboard', () => {
expect(findEnvironmentsDropdown().exists()).toBe(true);
});
- it('sets endpoints: logs path', () => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/setEndpoints',
- expect.objectContaining({ logsPath: propsData.logsPath }),
- );
+ it('sets initial state', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setInitialState', {
+ currentDashboard: '',
+ currentEnvironmentName: 'production',
+ dashboardEndpoint: 'https://invalid',
+ dashboardsEndpoint: 'https://invalid',
+ deploymentsEndpoint: null,
+ logsPath: '/path/to/logs',
+ metricsEndpoint: 'http://test.host/monitoring/mock',
+ projectPath: '/path/to/project',
+ });
});
});
diff --git a/spec/frontend/monitoring/components/embeds/metric_embed_spec.js b/spec/frontend/monitoring/components/embeds/metric_embed_spec.js
index d0fe22cefec..b829cd53479 100644
--- a/spec/frontend/monitoring/components/embeds/metric_embed_spec.js
+++ b/spec/frontend/monitoring/components/embeds/metric_embed_spec.js
@@ -26,9 +26,8 @@ describe('MetricEmbed', () => {
beforeEach(() => {
actions = {
- setFeatureFlags: jest.fn(),
+ setInitialState: jest.fn(),
setShowErrorBanner: jest.fn(),
- setEndpoints: jest.fn(),
setTimeRange: jest.fn(),
fetchDashboard: jest.fn(),
};
diff --git a/spec/frontend/monitoring/store/actions_spec.js b/spec/frontend/monitoring/store/actions_spec.js
index 203bc6f4e0e..e9f9aa0ba18 100644
--- a/spec/frontend/monitoring/store/actions_spec.js
+++ b/spec/frontend/monitoring/store/actions_spec.js
@@ -16,7 +16,7 @@ import {
fetchEnvironmentsData,
fetchPrometheusMetrics,
fetchPrometheusMetric,
- setEndpoints,
+ setInitialState,
filterEnvironments,
setGettingStartedEmptyState,
duplicateSystemDashboard,
@@ -208,14 +208,14 @@ describe('Monitoring store actions', () => {
});
});
- describe('Set endpoints', () => {
+ describe('Set initial state', () => {
let mockedState;
beforeEach(() => {
mockedState = storeState();
});
- it('should commit SET_ENDPOINTS mutation', done => {
+ it('should commit SET_INITIAL_STATE mutation', done => {
testAction(
- setEndpoints,
+ setInitialState,
{
metricsEndpoint: 'additional_metrics.json',
deploymentsEndpoint: 'deployments.json',
@@ -223,7 +223,7 @@ describe('Monitoring store actions', () => {
mockedState,
[
{
- type: types.SET_ENDPOINTS,
+ type: types.SET_INITIAL_STATE,
payload: {
metricsEndpoint: 'additional_metrics.json',
deploymentsEndpoint: 'deployments.json',
diff --git a/spec/frontend/monitoring/store/mutations_spec.js b/spec/frontend/monitoring/store/mutations_spec.js
index 5a79b8ef49c..0310c7e9510 100644
--- a/spec/frontend/monitoring/store/mutations_spec.js
+++ b/spec/frontend/monitoring/store/mutations_spec.js
@@ -86,6 +86,58 @@ describe('Monitoring mutations', () => {
expect(typeof stateCopy.deploymentData[0]).toEqual('object');
});
});
+
+ describe('SET_INITIAL_STATE', () => {
+ it('should set all the endpoints', () => {
+ mutations[types.SET_INITIAL_STATE](stateCopy, {
+ metricsEndpoint: 'additional_metrics.json',
+ deploymentsEndpoint: 'deployments.json',
+ dashboardEndpoint: 'dashboard.json',
+ projectPath: '/gitlab-org/gitlab-foss',
+ currentEnvironmentName: 'production',
+ });
+ expect(stateCopy.metricsEndpoint).toEqual('additional_metrics.json');
+ expect(stateCopy.deploymentsEndpoint).toEqual('deployments.json');
+ expect(stateCopy.dashboardEndpoint).toEqual('dashboard.json');
+ expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
+ expect(stateCopy.currentEnvironmentName).toEqual('production');
+ });
+
+ it('should not remove previously set properties', () => {
+ const defaultLogsPath = stateCopy.logsPath;
+
+ mutations[types.SET_INITIAL_STATE](stateCopy, {
+ logsPath: defaultLogsPath,
+ });
+ mutations[types.SET_INITIAL_STATE](stateCopy, {
+ dashboardEndpoint: 'dashboard.json',
+ });
+ mutations[types.SET_INITIAL_STATE](stateCopy, {
+ projectPath: '/gitlab-org/gitlab-foss',
+ });
+ mutations[types.SET_INITIAL_STATE](stateCopy, {
+ currentEnvironmentName: 'canary',
+ });
+
+ expect(stateCopy).toMatchObject({
+ logsPath: defaultLogsPath,
+ dashboardEndpoint: 'dashboard.json',
+ projectPath: '/gitlab-org/gitlab-foss',
+ currentEnvironmentName: 'canary',
+ });
+ });
+
+ it('should not update unknown properties', () => {
+ mutations[types.SET_INITIAL_STATE](stateCopy, {
+ dashboardEndpoint: 'dashboard.json',
+ someOtherProperty: 'some invalid value', // someOtherProperty is not allowed
+ });
+
+ expect(stateCopy.dashboardEndpoint).toBe('dashboard.json');
+ expect(stateCopy.someOtherProperty).toBeUndefined();
+ });
+ });
+
describe('SET_ENDPOINTS', () => {
it('should set all the endpoints', () => {
mutations[types.SET_ENDPOINTS](stateCopy, {
diff --git a/spec/frontend/releases/components/release_block_spec.js b/spec/frontend/releases/components/release_block_spec.js
index 7ea2379ea35..9846fcb65eb 100644
--- a/spec/frontend/releases/components/release_block_spec.js
+++ b/spec/frontend/releases/components/release_block_spec.js
@@ -165,6 +165,14 @@ describe('Release block', () => {
});
});
+ it('does not set the ID if tagName is missing', () => {
+ release.tagName = undefined;
+
+ return factory(release).then(() => {
+ expect(wrapper.attributes().id).toBeUndefined();
+ });
+ });
+
describe('evidence block', () => {
it('renders the evidence block when the evidence is available and the feature flag is true', () =>
factory(release, { releaseEvidenceCollection: true }).then(() =>
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index cd9d7c16f88..e922542a984 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -38,10 +38,6 @@ describe Member do
expect(member).not_to be_valid
end
-
- it "is valid otherwise" do
- expect(member).to be_valid
- end
end
context "when an invite email is not provided" do
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index e8e80a8c7f4..0a0611bdeb8 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -577,6 +577,8 @@ describe WikiPage do
end
it 'returns false when version is nil' do
+ expect(latest_page).to receive(:version) { nil }
+
expect(latest_page.historical?).to be_falsy
end
diff --git a/spec/workers/reactive_caching_worker_spec.rb b/spec/workers/reactive_caching_worker_spec.rb
index c39a97b4eee..603ce6160ce 100644
--- a/spec/workers/reactive_caching_worker_spec.rb
+++ b/spec/workers/reactive_caching_worker_spec.rb
@@ -37,5 +37,13 @@ describe ReactiveCachingWorker do
expect(scheduled_job).to include('meta.related_class' => 'Environment')
end
+
+ it 'sets the related class on the job when it was passed as a class' do
+ described_class.perform_async(Project, 1, 'other', 'argument')
+
+ scheduled_job = described_class.jobs.first
+
+ expect(scheduled_job).to include('meta.related_class' => 'Project')
+ end
end
end