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>2021-09-16 00:11:12 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-16 00:11:12 +0300
commita7aff3e0e4deb15c0902e0f948eb300ba77f3e47 (patch)
treec294fb9c39d5619fb3cac6f4a8d520deb8403dca
parent27d1ed4ddff6c2649544a968c2842140272d9c9d (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/error_tracking_settings/components/app.vue79
-rw-r--r--app/assets/javascripts/error_tracking_settings/index.js11
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/actions.js4
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/mutations.js14
-rw-r--r--app/assets/javascripts/error_tracking_settings/store/state.js1
-rw-r--r--app/assets/javascripts/error_tracking_settings/utils.js10
-rw-r--r--app/controllers/projects/settings/operations_controller.rb1
-rw-r--r--app/experiments/security_reports_mr_widget_prompt_experiment.rb14
-rw-r--r--app/services/projects/operations/update_service.rb1
-rw-r--r--app/views/projects/settings/operations/_error_tracking.html.haml1
-rw-r--r--config/feature_flags/development/ci_pipeline_add_job_with_lock.yml2
-rw-r--r--config/feature_flags/experiment/security_reports_mr_widget_prompt.yml8
-rw-r--r--config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml3
-rw-r--r--config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml3
-rw-r--r--config/pseudonymizer.yml1
-rw-r--r--db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb26
-rw-r--r--db/post_migrate/20210909152027_remove_container_registry_enabled.rb17
-rw-r--r--db/schema_migrations/202109021441441
-rw-r--r--db/schema_migrations/202109091520271
-rw-r--r--db/structure.sql13
-rw-r--r--doc/administration/merge_request_diffs.md6
-rw-r--r--doc/user/packages/debian_repository/index.md2
-rw-r--r--lib/gitlab/usage_data_counters/hll_redis_counter.rb20
-rw-r--r--locale/gitlab.pot12
-rw-r--r--spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb15
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb4
-rw-r--r--spec/features/projects/settings/monitor_settings_spec.rb27
-rw-r--r--spec/frontend/error_tracking_settings/components/app_spec.js80
-rw-r--r--spec/frontend/error_tracking_settings/mock.js4
-rw-r--r--spec/frontend/error_tracking_settings/store/actions_spec.js6
-rw-r--r--spec/frontend/error_tracking_settings/store/mutation_spec.js8
-rw-r--r--spec/frontend/error_tracking_settings/utils_spec.js2
-rw-r--r--spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb2
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb5
-rw-r--r--spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb21
-rw-r--r--spec/services/projects/operations/update_service_spec.rb4
-rw-r--r--spec/support/helpers/bare_repo_operations.rb19
38 files changed, 368 insertions, 81 deletions
diff --git a/app/assets/javascripts/error_tracking_settings/components/app.vue b/app/assets/javascripts/error_tracking_settings/components/app.vue
index d188574e721..e12d9cc2b07 100644
--- a/app/assets/javascripts/error_tracking_settings/components/app.vue
+++ b/app/assets/javascripts/error_tracking_settings/components/app.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlFormGroup, GlFormCheckbox } from '@gitlab/ui';
+import { GlButton, GlFormGroup, GlFormCheckbox, GlFormRadioGroup, GlFormRadio } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import ErrorTrackingForm from './error_tracking_form.vue';
import ProjectDropdown from './project_dropdown.vue';
@@ -10,6 +10,8 @@ export default {
GlButton,
GlFormCheckbox,
GlFormGroup,
+ GlFormRadioGroup,
+ GlFormRadio,
ProjectDropdown,
},
props: {
@@ -22,6 +24,10 @@ export default {
type: String,
required: true,
},
+ initialIntegrated: {
+ type: String,
+ required: true,
+ },
initialProject: {
type: String,
required: false,
@@ -49,12 +55,20 @@ export default {
'isProjectInvalid',
'projectSelectionLabel',
]),
- ...mapState(['enabled', 'projects', 'selectedProject', 'settingsLoading', 'token']),
+ ...mapState([
+ 'enabled',
+ 'integrated',
+ 'projects',
+ 'selectedProject',
+ 'settingsLoading',
+ 'token',
+ ]),
},
created() {
this.setInitialState({
apiHost: this.initialApiHost,
enabled: this.initialEnabled,
+ integrated: this.initialIntegrated,
project: this.initialProject,
token: this.initialToken,
listProjectsEndpoint: this.listProjectsEndpoint,
@@ -62,7 +76,13 @@ export default {
});
},
methods: {
- ...mapActions(['setInitialState', 'updateEnabled', 'updateSelectedProject', 'updateSettings']),
+ ...mapActions([
+ 'setInitialState',
+ 'updateEnabled',
+ 'updateIntegrated',
+ 'updateSelectedProject',
+ 'updateSettings',
+ ]),
handleSubmit() {
this.updateSettings();
},
@@ -76,27 +96,44 @@ export default {
:label="s__('ErrorTracking|Enable error tracking')"
label-for="error-tracking-enabled"
>
- <gl-form-checkbox
- id="error-tracking-enabled"
- :checked="enabled"
- @change="updateEnabled($event)"
- >
+ <gl-form-checkbox id="error-tracking-enabled" :checked="enabled" @change="updateEnabled">
{{ s__('ErrorTracking|Active') }}
</gl-form-checkbox>
</gl-form-group>
- <error-tracking-form />
- <div class="form-group">
- <project-dropdown
- :has-projects="hasProjects"
- :invalid-project-label="invalidProjectLabel"
- :is-project-invalid="isProjectInvalid"
- :dropdown-label="dropdownLabel"
- :project-selection-label="projectSelectionLabel"
- :projects="projects"
- :selected-project="selectedProject"
- :token="token"
- @select-project="updateSelectedProject"
- />
+ <gl-form-group
+ :label="s__('ErrorTracking|Error tracking backend')"
+ data-testid="tracking-backend-settings"
+ >
+ <gl-form-radio-group name="explicit" :checked="integrated" @change="updateIntegrated">
+ <gl-form-radio name="error-tracking-integrated" :value="false">
+ {{ __('Sentry') }}
+ <template #help>
+ {{ __('Requires you to deploy or set up cloud-hosted Sentry.') }}
+ </template>
+ </gl-form-radio>
+ <gl-form-radio name="error-tracking-integrated" :value="true">
+ {{ __('GitLab') }}
+ <template #help>
+ {{ __('Uses GitLab as a lightweight alternative to Sentry.') }}
+ </template>
+ </gl-form-radio>
+ </gl-form-radio-group>
+ </gl-form-group>
+ <div v-if="!integrated" class="js-sentry-setting-form" data-testid="sentry-setting-form">
+ <error-tracking-form />
+ <div class="form-group">
+ <project-dropdown
+ :has-projects="hasProjects"
+ :invalid-project-label="invalidProjectLabel"
+ :is-project-invalid="isProjectInvalid"
+ :dropdown-label="dropdownLabel"
+ :project-selection-label="projectSelectionLabel"
+ :projects="projects"
+ :selected-project="selectedProject"
+ :token="token"
+ @select-project="updateSelectedProject"
+ />
+ </div>
</div>
<gl-button
:disabled="settingsLoading"
diff --git a/app/assets/javascripts/error_tracking_settings/index.js b/app/assets/javascripts/error_tracking_settings/index.js
index ce315963723..324b3292834 100644
--- a/app/assets/javascripts/error_tracking_settings/index.js
+++ b/app/assets/javascripts/error_tracking_settings/index.js
@@ -5,7 +5,15 @@ import createStore from './store';
export default () => {
const formContainerEl = document.querySelector('.js-error-tracking-form');
const {
- dataset: { apiHost, enabled, project, token, listProjectsEndpoint, operationsSettingsEndpoint },
+ dataset: {
+ apiHost,
+ enabled,
+ integrated,
+ project,
+ token,
+ listProjectsEndpoint,
+ operationsSettingsEndpoint,
+ },
} = formContainerEl;
return new Vue({
@@ -16,6 +24,7 @@ export default () => {
props: {
initialApiHost: apiHost,
initialEnabled: enabled,
+ initialIntegrated: integrated,
initialProject: project,
initialToken: token,
listProjectsEndpoint,
diff --git a/app/assets/javascripts/error_tracking_settings/store/actions.js b/app/assets/javascripts/error_tracking_settings/store/actions.js
index d402d0336d9..972ad58c617 100644
--- a/app/assets/javascripts/error_tracking_settings/store/actions.js
+++ b/app/assets/javascripts/error_tracking_settings/store/actions.js
@@ -79,6 +79,10 @@ export const updateEnabled = ({ commit }, enabled) => {
commit(types.UPDATE_ENABLED, enabled);
};
+export const updateIntegrated = ({ commit }, integrated) => {
+ commit(types.UPDATE_INTEGRATED, integrated);
+};
+
export const updateToken = ({ commit }, token) => {
commit(types.UPDATE_TOKEN, token);
commit(types.RESET_CONNECT);
diff --git a/app/assets/javascripts/error_tracking_settings/store/mutation_types.js b/app/assets/javascripts/error_tracking_settings/store/mutation_types.js
index bf3df383ddc..2cfa14c9b64 100644
--- a/app/assets/javascripts/error_tracking_settings/store/mutation_types.js
+++ b/app/assets/javascripts/error_tracking_settings/store/mutation_types.js
@@ -6,6 +6,7 @@ export const UPDATE_API_HOST = 'UPDATE_API_HOST';
export const UPDATE_CONNECT_ERROR = 'UPDATE_CONNECT_ERROR';
export const UPDATE_CONNECT_SUCCESS = 'UPDATE_CONNECT_SUCCESS';
export const UPDATE_ENABLED = 'UPDATE_ENABLED';
+export const UPDATE_INTEGRATED = 'UPDATE_INTEGRATED';
export const UPDATE_SELECTED_PROJECT = 'UPDATE_SELECTED_PROJECT';
export const UPDATE_SETTINGS_LOADING = 'UPDATE_SETTINGS_LOADING';
export const UPDATE_TOKEN = 'UPDATE_TOKEN';
diff --git a/app/assets/javascripts/error_tracking_settings/store/mutations.js b/app/assets/javascripts/error_tracking_settings/store/mutations.js
index 2242169aa1e..a1b43ccaaee 100644
--- a/app/assets/javascripts/error_tracking_settings/store/mutations.js
+++ b/app/assets/javascripts/error_tracking_settings/store/mutations.js
@@ -20,9 +20,18 @@ export default {
},
[types.SET_INITIAL_STATE](
state,
- { apiHost, enabled, project, token, listProjectsEndpoint, operationsSettingsEndpoint },
+ {
+ apiHost,
+ enabled,
+ integrated,
+ project,
+ token,
+ listProjectsEndpoint,
+ operationsSettingsEndpoint,
+ },
) {
state.enabled = parseBoolean(enabled);
+ state.integrated = parseBoolean(integrated);
state.apiHost = apiHost;
state.token = token;
state.listProjectsEndpoint = listProjectsEndpoint;
@@ -38,6 +47,9 @@ export default {
[types.UPDATE_ENABLED](state, enabled) {
state.enabled = enabled;
},
+ [types.UPDATE_INTEGRATED](state, integrated) {
+ state.integrated = integrated;
+ },
[types.UPDATE_TOKEN](state, token) {
state.token = token;
},
diff --git a/app/assets/javascripts/error_tracking_settings/store/state.js b/app/assets/javascripts/error_tracking_settings/store/state.js
index ab616f11e83..ee5597abeb3 100644
--- a/app/assets/javascripts/error_tracking_settings/store/state.js
+++ b/app/assets/javascripts/error_tracking_settings/store/state.js
@@ -1,6 +1,7 @@
export default () => ({
apiHost: '',
enabled: false,
+ integrated: false,
token: '',
projects: [],
isLoadingProjects: false,
diff --git a/app/assets/javascripts/error_tracking_settings/utils.js b/app/assets/javascripts/error_tracking_settings/utils.js
index 5d18ac8e802..7ef5f7bbd34 100644
--- a/app/assets/javascripts/error_tracking_settings/utils.js
+++ b/app/assets/javascripts/error_tracking_settings/utils.js
@@ -1,6 +1,12 @@
export const projectKeys = ['name', 'organizationName', 'organizationSlug', 'slug'];
-export const transformFrontendSettings = ({ apiHost, enabled, token, selectedProject }) => {
+export const transformFrontendSettings = ({
+ apiHost,
+ enabled,
+ integrated,
+ token,
+ selectedProject,
+}) => {
const project = selectedProject
? {
slug: selectedProject.slug,
@@ -10,7 +16,7 @@ export const transformFrontendSettings = ({ apiHost, enabled, token, selectedPro
}
: null;
- return { api_host: apiHost || null, enabled, token: token || null, project };
+ return { api_host: apiHost || null, enabled, integrated, token: token || null, project };
};
export const getDisplayName = (project) => `${project.organizationName} | ${project.slug}`;
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index e32815b6239..56e201c592f 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -136,6 +136,7 @@ module Projects
error_tracking_setting_attributes: [
:enabled,
+ :integrated,
:api_host,
:token,
project: [:slug, :name, :organization_slug, :organization_name]
diff --git a/app/experiments/security_reports_mr_widget_prompt_experiment.rb b/app/experiments/security_reports_mr_widget_prompt_experiment.rb
new file mode 100644
index 00000000000..fa0ba8e24d4
--- /dev/null
+++ b/app/experiments/security_reports_mr_widget_prompt_experiment.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class SecurityReportsMrWidgetPromptExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
+ def publish(_result = nil)
+ super
+
+ publish_to_database
+ end
+
+ # This is a purely client side experiment, and since we don't have a nicer
+ # way to define variants yet, we define them here.
+ def candidate_behavior
+ end
+end
diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb
index 51b8e3c6c54..ef74f3e6e7a 100644
--- a/app/services/projects/operations/update_service.rb
+++ b/app/services/projects/operations/update_service.rb
@@ -94,6 +94,7 @@ module Projects
}
}
params[:error_tracking_setting_attributes][:token] = settings[:token] unless /\A\*+\z/.match?(settings[:token]) # Don't update token if we receive masked value
+ params[:error_tracking_setting_attributes][:integrated] = settings[:integrated] unless settings[:integrated].nil?
params
end
diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml
index 4ef9e1bd6fb..6b2a1468eec 100644
--- a/app/views/projects/settings/operations/_error_tracking.html.haml
+++ b/app/views/projects/settings/operations/_error_tracking.html.haml
@@ -17,4 +17,5 @@
project: error_tracking_setting_project_json,
api_host: setting.api_host,
enabled: setting.enabled.to_json,
+ integrated: setting.integrated.to_json,
token: setting.token.present? ? '*' * 12 : nil } }
diff --git a/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml b/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml
index 48aa64ba7f4..6a708013ca5 100644
--- a/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml
+++ b/config/feature_flags/development/ci_pipeline_add_job_with_lock.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337628
milestone: '14.2'
type: development
group: group::pipeline authoring
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/experiment/security_reports_mr_widget_prompt.yml b/config/feature_flags/experiment/security_reports_mr_widget_prompt.yml
new file mode 100644
index 00000000000..ca6d17b1720
--- /dev/null
+++ b/config/feature_flags/experiment/security_reports_mr_widget_prompt.yml
@@ -0,0 +1,8 @@
+---
+name: security_reports_mr_widget_prompt
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70086
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340436
+milestone: '14.3'
+type: experiment
+group: group::adoption
+default_enabled: false
diff --git a/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml
index dea3cb13db0..66b8e714723 100644
--- a/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210216184559_ci_templates_total_unique_counts_monthly.yml
@@ -7,7 +7,8 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: broken
+status: removed
+milestone_removed: '14.3'
repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332466
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml
index 96d25513545..cf0e69c6da2 100644
--- a/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210216184557_ci_templates_total_unique_counts_weekly.yml
@@ -7,7 +7,8 @@ product_stage: configure
product_group: group::configure
product_category: infrastructure_as_code
value_type: number
-status: broken
+status: removed
+milestone_removed: '14.3'
repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332466
time_frame: 7d
data_source: redis_hll
diff --git a/config/pseudonymizer.yml b/config/pseudonymizer.yml
index 532fbe3b70f..cd8db9d8dc5 100644
--- a/config/pseudonymizer.yml
+++ b/config/pseudonymizer.yml
@@ -385,7 +385,6 @@ tables:
- public_builds
- last_repository_check_failed
- last_repository_check_at
- - container_registry_enabled
- only_allow_merge_if_pipeline_succeeds
- has_external_issue_tracker
- repository_storage
diff --git a/db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb b/db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb
new file mode 100644
index 00000000000..f04c5cd6561
--- /dev/null
+++ b/db/post_migrate/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class DropTemporaryColumnsAndTriggersForCiBuildNeeds < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = 'ci_build_needs'
+ TEMPORARY_COLUMN = 'build_id_convert_to_bigint'
+ MAIN_COLUMN = 'build_id'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, MAIN_COLUMN)
+ end
+ end
+
+ def down
+ check_trigger_permissions!(TABLE)
+
+ with_lock_retries do
+ add_column(TABLE, TEMPORARY_COLUMN, :int, default: 0, null: false)
+ install_rename_triggers(TABLE, MAIN_COLUMN, TEMPORARY_COLUMN)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+end
diff --git a/db/post_migrate/20210909152027_remove_container_registry_enabled.rb b/db/post_migrate/20210909152027_remove_container_registry_enabled.rb
new file mode 100644
index 00000000000..d97faaf58d2
--- /dev/null
+++ b/db/post_migrate/20210909152027_remove_container_registry_enabled.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveContainerRegistryEnabled < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_column :projects, :container_registry_enabled
+ end
+ end
+
+ def down
+ with_lock_retries do
+ add_column :projects, :container_registry_enabled, :boolean # rubocop:disable Migration/AddColumnsToWideTables
+ end
+ end
+end
diff --git a/db/schema_migrations/20210902144144 b/db/schema_migrations/20210902144144
new file mode 100644
index 00000000000..330569f1beb
--- /dev/null
+++ b/db/schema_migrations/20210902144144
@@ -0,0 +1 @@
+c99df310082dd6f5faff3cfd90dfca88af26d840889910ebac0e73ba483a09b2 \ No newline at end of file
diff --git a/db/schema_migrations/20210909152027 b/db/schema_migrations/20210909152027
new file mode 100644
index 00000000000..39db0c43aa6
--- /dev/null
+++ b/db/schema_migrations/20210909152027
@@ -0,0 +1 @@
+abed3f9a6c188890d3dcd21f73a09347f8ccec0f6cc448220fadba5cbda17281 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 3453df441cd..6ccb49396d0 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -64,15 +64,6 @@ RETURN NULL;
END
$$;
-CREATE FUNCTION trigger_21e7a2602957() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."build_id_convert_to_bigint" := NEW."build_id";
- RETURN NEW;
-END;
-$$;
-
CREATE FUNCTION trigger_3f6129be01d2() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -11227,7 +11218,6 @@ ALTER SEQUENCE chat_teams_id_seq OWNED BY chat_teams.id;
CREATE TABLE ci_build_needs (
id integer NOT NULL,
- build_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
name text NOT NULL,
artifacts boolean DEFAULT true NOT NULL,
optional boolean DEFAULT false NOT NULL,
@@ -18184,7 +18174,6 @@ CREATE TABLE projects (
public_builds boolean DEFAULT true NOT NULL,
last_repository_check_failed boolean,
last_repository_check_at timestamp without time zone,
- container_registry_enabled boolean,
only_allow_merge_if_pipeline_succeeds boolean DEFAULT false NOT NULL,
has_external_issue_tracker boolean,
repository_storage character varying DEFAULT 'default'::character varying NOT NULL,
@@ -27322,8 +27311,6 @@ ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_p
ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_partitions_static.product_analytics_events_experimental_63_pkey;
-CREATE TRIGGER trigger_21e7a2602957 BEFORE INSERT OR UPDATE ON ci_build_needs FOR EACH ROW EXECUTE FUNCTION trigger_21e7a2602957();
-
CREATE TRIGGER trigger_3f6129be01d2 BEFORE INSERT OR UPDATE ON ci_builds FOR EACH ROW EXECUTE FUNCTION trigger_3f6129be01d2();
CREATE TRIGGER trigger_542d6c2ad72e BEFORE INSERT OR UPDATE ON ci_builds_metadata FOR EACH ROW EXECUTE FUNCTION trigger_542d6c2ad72e();
diff --git a/doc/administration/merge_request_diffs.md b/doc/administration/merge_request_diffs.md
index 1133bff204c..d6b9fa2b8d3 100644
--- a/doc/administration/merge_request_diffs.md
+++ b/doc/administration/merge_request_diffs.md
@@ -265,3 +265,9 @@ by assigning different processes to different parts of the table. The `BATCH`
and `UPDATE_DELAY` parameters allow the speed of the migration to be traded off
against concurrent access to the table. The `ANSI` parameter should be set to
false if your terminal does not support ANSI escape codes.
+
+By default, `sudo` does not preserve existing environment variables. You should append them, rather than prefix them.
+
+```shell
+sudo gitlab-rake gitlab:external_diffs:force_object_storage START_ID=59946109 END_ID=59946109 UPDATE_DELAY=5
+```
diff --git a/doc/user/packages/debian_repository/index.md b/doc/user/packages/debian_repository/index.md
index 28489bb89b2..29641380753 100644
--- a/doc/user/packages/debian_repository/index.md
+++ b/doc/user/packages/debian_repository/index.md
@@ -78,7 +78,7 @@ packages on the group level, create a distribution with the same `codename`.
To create a project-level distribution:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/debian_distributions?codename=unstable
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<project_id>/debian_distributions?codename=unstable"
```
Example response:
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index 96562a44391..8fc8bb5d344 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -18,6 +18,24 @@ module Gitlab
KNOWN_EVENTS_PATH = File.expand_path('known_events/*.yml', __dir__)
ALLOWED_AGGREGATIONS = %i(daily weekly).freeze
+ CATEGORIES_FOR_TOTALS = %w[
+ analytics
+ code_review
+ compliance
+ deploy_token_packages
+ ecosystem
+ epic_boards_usage
+ epics_usage
+ ide_edit
+ incident_management
+ issues_edit
+ pipeline_authoring
+ quickactions
+ search
+ testing
+ user_packages
+ ].freeze
+
# Track event on entity_id
# Increment a Redis HLL counter for unique event_name and entity_id
#
@@ -90,7 +108,7 @@ module Gitlab
hash["#{event}_monthly"] = unique_events(**monthly_time_range.merge(event_names: [event]))
end
- if eligible_for_totals?(events_names)
+ if eligible_for_totals?(events_names) && CATEGORIES_FOR_TOTALS.include?(category)
event_results["#{category}_total_unique_counts_weekly"] = unique_events(**weekly_time_range.merge(event_names: events_names))
event_results["#{category}_total_unique_counts_monthly"] = unique_events(**monthly_time_range.merge(event_names: events_names))
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9fe1eb7a262..2ce4bc6f2e8 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -13366,6 +13366,9 @@ msgstr ""
msgid "ErrorTracking|Enable error tracking"
msgstr ""
+msgid "ErrorTracking|Error tracking backend"
+msgstr ""
+
msgid "ErrorTracking|If you self-host Sentry, enter your Sentry instance's full URL. If you use Sentry's hosted solution, enter https://sentry.io"
msgstr ""
@@ -28637,6 +28640,9 @@ msgstr[1] ""
msgid "Requires values to meet regular expression requirements."
msgstr ""
+msgid "Requires you to deploy or set up cloud-hosted Sentry."
+msgstr ""
+
msgid "Requires your primary GitLab email address."
msgstr ""
@@ -30517,6 +30523,9 @@ msgstr ""
msgid "Send service data"
msgstr ""
+msgid "Sentry"
+msgstr ""
+
msgid "Sentry API URL"
msgstr ""
@@ -37013,6 +37022,9 @@ msgstr ""
msgid "UsersSelect|Unassigned"
msgstr ""
+msgid "Uses GitLab as a lightweight alternative to Sentry."
+msgstr ""
+
msgid "Using %{code_start}::%{code_end} denotes a %{link_start}scoped label set%{link_end}"
msgstr ""
diff --git a/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb b/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
new file mode 100644
index 00000000000..4328ff12d42
--- /dev/null
+++ b/spec/experiments/security_reports_mr_widget_prompt_experiment_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SecurityReportsMrWidgetPromptExperiment do
+ it "defines a control and candidate" do
+ expect(subject.behaviors.keys).to match_array(%w[control candidate])
+ end
+
+ it "publishes to the database" do
+ expect(subject).to receive(:publish_to_database)
+
+ subject.publish
+ end
+end
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 1efcc329e32..60963d95ae5 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe 'Search bar', :js do
expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size)
end
- it 'resets the dropdown filters', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/9985' do
+ it 'resets the dropdown filters' do
filtered_search.click
hint_offset = get_left_style(find('#js-dropdown-hint')['style'])
@@ -103,7 +103,7 @@ RSpec.describe 'Search bar', :js do
find('.filtered-search-box .clear-search').click
filtered_search.click
- expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6)
+ expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', minimum: 6)
expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset)
end
end
diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb
index 2d8c418b7d0..e3d75c30e5e 100644
--- a/spec/features/projects/settings/monitor_settings_spec.rb
+++ b/spec/features/projects/settings/monitor_settings_spec.rb
@@ -150,6 +150,33 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
assert_text('Connection failed. Check Auth Token and try again.')
end
end
+
+ context 'integrated error tracking backend' do
+ it 'successfully fills and submits the form' do
+ visit project_settings_operations_path(project)
+
+ wait_for_requests
+
+ within '.js-error-tracking-settings' do
+ click_button('Expand')
+ end
+
+ expect(page).to have_content('Error tracking backend')
+
+ within '.js-error-tracking-settings' do
+ check('Active')
+ choose('GitLab')
+ end
+
+ expect(page).not_to have_content('Sentry API URL')
+
+ click_button('Save changes')
+
+ wait_for_requests
+
+ assert_text('Your changes have been saved')
+ end
+ end
end
context 'grafana integration settings form' do
diff --git a/spec/frontend/error_tracking_settings/components/app_spec.js b/spec/frontend/error_tracking_settings/components/app_spec.js
index e0be81b3899..30541ba68a5 100644
--- a/spec/frontend/error_tracking_settings/components/app_spec.js
+++ b/spec/frontend/error_tracking_settings/components/app_spec.js
@@ -1,6 +1,9 @@
+import { GlFormRadioGroup, GlFormRadio } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ErrorTrackingSettings from '~/error_tracking_settings/components/app.vue';
import ErrorTrackingForm from '~/error_tracking_settings/components/error_tracking_form.vue';
import ProjectDropdown from '~/error_tracking_settings/components/project_dropdown.vue';
@@ -14,20 +17,31 @@ describe('error tracking settings app', () => {
let wrapper;
function mountComponent() {
- wrapper = shallowMount(ErrorTrackingSettings, {
- localVue,
- store, // Override the imported store
- propsData: {
- initialEnabled: 'true',
- initialApiHost: TEST_HOST,
- initialToken: 'someToken',
- initialProject: null,
- listProjectsEndpoint: TEST_HOST,
- operationsSettingsEndpoint: TEST_HOST,
- },
- });
+ wrapper = extendedWrapper(
+ shallowMount(ErrorTrackingSettings, {
+ localVue,
+ store, // Override the imported store
+ propsData: {
+ initialEnabled: 'true',
+ initialIntegrated: 'false',
+ initialApiHost: TEST_HOST,
+ initialToken: 'someToken',
+ initialProject: null,
+ listProjectsEndpoint: TEST_HOST,
+ operationsSettingsEndpoint: TEST_HOST,
+ },
+ }),
+ );
}
+ const findBackendSettingsSection = () => wrapper.findByTestId('tracking-backend-settings');
+ const findBackendSettingsRadioGroup = () =>
+ findBackendSettingsSection().findComponent(GlFormRadioGroup);
+ const findBackendSettingsRadioButtons = () =>
+ findBackendSettingsRadioGroup().findAllComponents(GlFormRadio);
+ const findElementWithText = (wrappers, text) => wrappers.filter((item) => item.text() === text);
+ const findSentrySettings = () => wrapper.findByTestId('sentry-setting-form');
+
beforeEach(() => {
store = createStore();
@@ -62,4 +76,46 @@ describe('error tracking settings app', () => {
});
});
});
+
+ describe('tracking-backend settings', () => {
+ it('contains a form-group with the correct label', () => {
+ expect(findBackendSettingsSection().attributes('label')).toBe('Error tracking backend');
+ });
+
+ it('contains a radio group', () => {
+ expect(findBackendSettingsRadioGroup().exists()).toBe(true);
+ });
+
+ it('contains the correct radio buttons', () => {
+ expect(findBackendSettingsRadioButtons()).toHaveLength(2);
+
+ expect(findElementWithText(findBackendSettingsRadioButtons(), 'Sentry')).toHaveLength(1);
+ expect(findElementWithText(findBackendSettingsRadioButtons(), 'GitLab')).toHaveLength(1);
+ });
+
+ it('toggles the sentry-settings section when sentry is selected as a tracking-backend', async () => {
+ expect(findSentrySettings().exists()).toBe(true);
+
+ // set the "integrated" setting to "true"
+ findBackendSettingsRadioGroup().vm.$emit('change', true);
+
+ await nextTick();
+
+ expect(findSentrySettings().exists()).toBe(false);
+ });
+
+ it.each([true, false])(
+ 'calls the `updateIntegrated` action when the setting changes to `%s`',
+ (integrated) => {
+ jest.spyOn(store, 'dispatch').mockImplementation();
+
+ expect(store.dispatch).toHaveBeenCalledTimes(0);
+
+ findBackendSettingsRadioGroup().vm.$emit('change', integrated);
+
+ expect(store.dispatch).toHaveBeenCalledTimes(1);
+ expect(store.dispatch).toHaveBeenCalledWith('updateIntegrated', integrated);
+ },
+ );
+ });
});
diff --git a/spec/frontend/error_tracking_settings/mock.js b/spec/frontend/error_tracking_settings/mock.js
index e64a6d1fe14..b2d7a912518 100644
--- a/spec/frontend/error_tracking_settings/mock.js
+++ b/spec/frontend/error_tracking_settings/mock.js
@@ -42,6 +42,7 @@ export const sampleBackendProject = {
export const sampleFrontendSettings = {
apiHost: 'apiHost',
enabled: false,
+ integrated: false,
token: 'token',
selectedProject: {
slug: normalizedProject.slug,
@@ -54,6 +55,7 @@ export const sampleFrontendSettings = {
export const transformedSettings = {
api_host: 'apiHost',
enabled: false,
+ integrated: false,
token: 'token',
project: {
slug: normalizedProject.slug,
@@ -71,6 +73,7 @@ export const defaultProps = {
export const initialEmptyState = {
apiHost: '',
enabled: false,
+ integrated: false,
project: null,
token: '',
listProjectsEndpoint: TEST_HOST,
@@ -80,6 +83,7 @@ export const initialEmptyState = {
export const initialPopulatedState = {
apiHost: 'apiHost',
enabled: true,
+ integrated: true,
project: JSON.stringify(projectList[0]),
token: 'token',
listProjectsEndpoint: TEST_HOST,
diff --git a/spec/frontend/error_tracking_settings/store/actions_spec.js b/spec/frontend/error_tracking_settings/store/actions_spec.js
index 281db7d9686..1b9be042dd4 100644
--- a/spec/frontend/error_tracking_settings/store/actions_spec.js
+++ b/spec/frontend/error_tracking_settings/store/actions_spec.js
@@ -202,5 +202,11 @@ describe('error tracking settings actions', () => {
done,
);
});
+
+ it.each([true, false])('should set the `integrated` flag to `%s`', async (payload) => {
+ await testAction(actions.updateIntegrated, payload, state, [
+ { type: types.UPDATE_INTEGRATED, payload },
+ ]);
+ });
});
});
diff --git a/spec/frontend/error_tracking_settings/store/mutation_spec.js b/spec/frontend/error_tracking_settings/store/mutation_spec.js
index 78fd56904b3..ecf1c91c08a 100644
--- a/spec/frontend/error_tracking_settings/store/mutation_spec.js
+++ b/spec/frontend/error_tracking_settings/store/mutation_spec.js
@@ -25,6 +25,7 @@ describe('error tracking settings mutations', () => {
expect(state.apiHost).toEqual('');
expect(state.enabled).toEqual(false);
+ expect(state.integrated).toEqual(false);
expect(state.selectedProject).toEqual(null);
expect(state.token).toEqual('');
expect(state.listProjectsEndpoint).toEqual(TEST_HOST);
@@ -38,6 +39,7 @@ describe('error tracking settings mutations', () => {
expect(state.apiHost).toEqual('apiHost');
expect(state.enabled).toEqual(true);
+ expect(state.integrated).toEqual(true);
expect(state.selectedProject).toEqual(projectList[0]);
expect(state.token).toEqual('token');
expect(state.listProjectsEndpoint).toEqual(TEST_HOST);
@@ -78,5 +80,11 @@ describe('error tracking settings mutations', () => {
expect(state.connectSuccessful).toBe(false);
expect(state.connectError).toBe(false);
});
+
+ it.each([true, false])('should update `integrated` to `%s`', (integrated) => {
+ mutations[types.UPDATE_INTEGRATED](state, integrated);
+
+ expect(state.integrated).toBe(integrated);
+ });
});
});
diff --git a/spec/frontend/error_tracking_settings/utils_spec.js b/spec/frontend/error_tracking_settings/utils_spec.js
index 4b144f7daf1..61e75cdc45e 100644
--- a/spec/frontend/error_tracking_settings/utils_spec.js
+++ b/spec/frontend/error_tracking_settings/utils_spec.js
@@ -11,12 +11,14 @@ describe('error tracking settings utils', () => {
const emptyFrontendSettingsObject = {
apiHost: '',
enabled: false,
+ integrated: false,
token: '',
selectedProject: null,
};
const transformedEmptySettingsObject = {
api_host: null,
enabled: false,
+ integrated: false,
token: null,
project: null,
};
diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
index 887759014f5..427dd4a205e 100644
--- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
@@ -462,6 +462,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
allow(described_class).to receive(:known_events).and_return(known_events)
allow(described_class).to receive(:categories).and_return(%w(category1 category2))
+ stub_const('Gitlab::UsageDataCounters::HLLRedisCounter::CATEGORIES_FOR_TOTALS', %w(category1 category2))
+
described_class.track_event('event1_slot', values: entity1, time: 2.days.ago)
described_class.track_event('event2_slot', values: entity2, time: 2.days.ago)
described_class.track_event('event2_slot', values: entity3, time: 2.weeks.ago)
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 5d85ad5ad01..d96cd8a2db4 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -1279,9 +1279,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
subject { described_class.redis_hll_counters }
let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories }
- let(:ineligible_total_categories) do
- %w[source_code ci_secrets_management incident_management_alerts snippets terraform incident_management_oncall secure network_policies]
- end
context 'with redis_hll_tracking feature enabled' do
it 'has all known_events' do
@@ -1296,7 +1293,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
metrics = keys.map { |key| "#{key}_weekly" } + keys.map { |key| "#{key}_monthly" }
- if ineligible_total_categories.exclude?(category)
+ if ::Gitlab::UsageDataCounters::HLLRedisCounter::CATEGORIES_FOR_TOTALS.include?(category)
metrics.append("#{category}_total_unique_counts_weekly", "#{category}_total_unique_counts_monthly")
end
diff --git a/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb b/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb
new file mode 100644
index 00000000000..1b35982c41d
--- /dev/null
+++ b/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_temporary_columns_and_triggers_for_ci_build_needs')
+
+RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildNeeds do
+ let(:ci_build_needs_table) { table(:ci_build_needs) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ci_build_needs_table.column_names).to include('build_id_convert_to_bigint')
+ }
+
+ migration.after -> {
+ ci_build_needs_table.reset_column_information
+ expect(ci_build_needs_table.column_names).not_to include('build_id_convert_to_bigint')
+ }
+ end
+ end
+end
diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index 1d9d5f6e938..a71fafb2121 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -153,6 +153,7 @@ RSpec.describe Projects::Operations::UpdateService do
{
error_tracking_setting_attributes: {
enabled: false,
+ integrated: true,
api_host: 'http://gitlab.com/',
token: 'token',
project: {
@@ -174,6 +175,7 @@ RSpec.describe Projects::Operations::UpdateService do
project.reload
expect(project.error_tracking_setting).not_to be_enabled
+ expect(project.error_tracking_setting.integrated).to be_truthy
expect(project.error_tracking_setting.api_url).to eq(
'http://gitlab.com/api/0/projects/org/project/'
)
@@ -206,6 +208,7 @@ RSpec.describe Projects::Operations::UpdateService do
{
error_tracking_setting_attributes: {
enabled: true,
+ integrated: true,
api_host: 'http://gitlab.com/',
token: 'token',
project: {
@@ -222,6 +225,7 @@ RSpec.describe Projects::Operations::UpdateService do
expect(result[:status]).to eq(:success)
expect(project.error_tracking_setting).to be_enabled
+ expect(project.error_tracking_setting.integrated).to be_truthy
expect(project.error_tracking_setting.api_url).to eq(
'http://gitlab.com/api/0/projects/org/project/'
)
diff --git a/spec/support/helpers/bare_repo_operations.rb b/spec/support/helpers/bare_repo_operations.rb
index cd2dcecd1b6..e29e12a15f6 100644
--- a/spec/support/helpers/bare_repo_operations.rb
+++ b/spec/support/helpers/bare_repo_operations.rb
@@ -17,25 +17,6 @@ class BareRepoOperations
commit_id[0]
end
- def commit_file(file, dst_path, branch = 'master')
- head_id = execute(['show', '--format=format:%H', '--no-patch', branch], allow_failure: true)[0] || Gitlab::Git::EMPTY_TREE_ID
-
- execute(['read-tree', '--empty'])
- execute(['read-tree', head_id])
-
- blob_id = execute(['hash-object', '--stdin', '-w']) do |stdin|
- stdin.write(file.read)
- end
-
- execute(['update-index', '--add', '--cacheinfo', '100644', blob_id[0], dst_path])
-
- tree_id = execute(['write-tree'])
-
- commit_id = commit_tree(tree_id[0], "Add #{dst_path}", parent: head_id)
-
- execute(['update-ref', "refs/heads/#{branch}", commit_id])
- end
-
private
def execute(args, allow_failure: false)