summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG-EE.md8
-rw-r--r--app/assets/javascripts/vue_shared/components/bar_chart.vue13
-rw-r--r--app/finders/merge_requests_finder.rb12
-rw-r--r--app/models/application_setting.rb1
-rw-r--r--changelogs/unreleased/35739-add-mr-to-deployment-api.yml5
-rw-r--r--changelogs/unreleased/add-group-id-column.yml5
-rw-r--r--changelogs/unreleased/ag-add-app-multi-logger.yml5
-rw-r--r--changelogs/unreleased/error-tracking-api.yml5
-rw-r--r--changelogs/unreleased/pravi-gitlab-update-d3.yml5
-rw-r--r--changelogs/unreleased/security-project-import-vn-master.yml5
-rw-r--r--db/migrate/20200103190741_add_column_for_instance_administrators_group.rb12
-rw-r--r--db/migrate/20200103192859_add_fk_for_instance_administrators_group.rb22
-rw-r--r--db/migrate/20200103192914_add_index_for_instance_administrators_group.rb17
-rw-r--r--db/schema.rb3
-rw-r--r--doc/api/api_resources.md1
-rw-r--r--doc/api/deployments.md16
-rw-r--r--doc/api/error_tracking.md31
-rw-r--r--doc/api/merge_requests.md2
-rw-r--r--doc/development/logging.md82
-rw-r--r--doc/development/testing_guide/end_to_end/index.md4
-rw-r--r--doc/integration/saml.md2
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/deployments.rb20
-rw-r--r--lib/api/entities/error_tracking.rb13
-rw-r--r--lib/api/error_tracking.rb28
-rw-r--r--lib/api/helpers/merge_requests_helpers.rb68
-rw-r--r--lib/api/merge_requests.rb32
-rw-r--r--lib/gitlab/app_json_logger.rb9
-rw-r--r--lib/gitlab/app_logger.rb12
-rw-r--r--lib/gitlab/app_text_logger.rb13
-rw-r--r--lib/gitlab/multi_destination_logger.rb49
-rw-r--r--package.json2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb15
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb6
-rw-r--r--spec/finders/merge_requests_finder_spec.rb32
-rw-r--r--spec/lib/gitlab/app_json_logger_spec.rb18
-rw-r--r--spec/lib/gitlab/app_logger_spec.rb18
-rw-r--r--spec/lib/gitlab/app_text_logger_spec.rb18
-rw-r--r--spec/lib/gitlab/multi_destination_logger_spec.rb59
-rw-r--r--spec/requests/api/deployments_spec.rb42
-rw-r--r--spec/requests/api/error_tracking_spec.rb78
-rw-r--r--yarn.lock167
43 files changed, 802 insertions, 160 deletions
diff --git a/CHANGELOG-EE.md b/CHANGELOG-EE.md
index b52bdaef27d..e2aa876e4c0 100644
--- a/CHANGELOG-EE.md
+++ b/CHANGELOG-EE.md
@@ -1,5 +1,9 @@
Please view this file on the master branch, on stable branches it's out of date.
+## 12.6.4
+
+- No changes.
+
## 12.6.2
### Security (2 changes)
@@ -228,6 +232,10 @@ Please view this file on the master branch, on stable branches it's out of date.
- Remove IIFEs from jira_connect.js file. !19248 (nuwe1)
+## 12.4.8
+
+- No changes.
+
## 12.4.5
- No changes.
diff --git a/app/assets/javascripts/vue_shared/components/bar_chart.vue b/app/assets/javascripts/vue_shared/components/bar_chart.vue
index 25d7bfe515c..ff718eacc5b 100644
--- a/app/assets/javascripts/vue_shared/components/bar_chart.vue
+++ b/app/assets/javascripts/vue_shared/components/bar_chart.vue
@@ -124,9 +124,7 @@ export default {
},
},
mounted() {
- if (!this.allValuesEmpty) {
- this.draw();
- }
+ this.draw();
},
methods: {
draw() {
@@ -153,7 +151,14 @@ export default {
this.yScale = d3.scaleLinear().rangeRound([this.vbHeight, 0]);
this.xScale.domain(this.graphData.map(d => d.name));
- this.yScale.domain([0, d3.max(this.graphData.map(d => d.value))]);
+ /*
+ If we have all-zero graph we want graph to center 0 on axis and not to draw
+ any kind of ticks on Y axis. Infinity allows us to do that.
+
+ See https://gitlab.com/gitlab-org/gitlab/merge_requests/20627#note_251484582
+ for detailed explanation
+ */
+ this.yScale.domain([0, d3.max(this.graphData.map(d => d.value)) || Infinity]);
// Zoom/Panning Function
this.zoom = d3
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index 275a01330bf..410ad645cd9 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -39,6 +39,7 @@ class MergeRequestsFinder < IssuableFinder
def filter_items(_items)
items = by_commit(super)
+ items = by_deployment(items)
items = by_source_branch(items)
items = by_wip(items)
items = by_target_branch(items)
@@ -101,6 +102,17 @@ class MergeRequestsFinder < IssuableFinder
.or(table[:title].matches('WIP %'))
.or(table[:title].matches('[WIP]%'))
end
+
+ def by_deployment(items)
+ return items unless deployment_id
+
+ items.includes(:deployment_merge_requests)
+ .where(deployment_merge_requests: { deployment_id: deployment_id })
+ end
+
+ def deployment_id
+ @deployment_id ||= params[:deployment_id].presence
+ end
end
MergeRequestsFinder.prepend_if_ee('EE::MergeRequestsFinder')
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index a0a600a340e..10d15e84b8d 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -11,6 +11,7 @@ class ApplicationSetting < ApplicationRecord
add_authentication_token_field :static_objects_external_storage_auth_token
belongs_to :instance_administration_project, class_name: "Project"
+ belongs_to :instance_administrators_group, class_name: "Group"
# Include here so it can override methods from
# `add_authentication_token_field`
diff --git a/changelogs/unreleased/35739-add-mr-to-deployment-api.yml b/changelogs/unreleased/35739-add-mr-to-deployment-api.yml
new file mode 100644
index 00000000000..13dabb2fae1
--- /dev/null
+++ b/changelogs/unreleased/35739-add-mr-to-deployment-api.yml
@@ -0,0 +1,5 @@
+---
+title: Add API support for retrieving merge requests deployed in a deployment
+merge_request: 21837
+author:
+type: added
diff --git a/changelogs/unreleased/add-group-id-column.yml b/changelogs/unreleased/add-group-id-column.yml
new file mode 100644
index 00000000000..dab953b372e
--- /dev/null
+++ b/changelogs/unreleased/add-group-id-column.yml
@@ -0,0 +1,5 @@
+---
+title: Save Instance Administrators group ID in DB
+merge_request: 22600
+author:
+type: changed
diff --git a/changelogs/unreleased/ag-add-app-multi-logger.yml b/changelogs/unreleased/ag-add-app-multi-logger.yml
new file mode 100644
index 00000000000..739861ab1ee
--- /dev/null
+++ b/changelogs/unreleased/ag-add-app-multi-logger.yml
@@ -0,0 +1,5 @@
+---
+title: Add structured logging for application logs
+merge_request: 22379
+author:
+type: other
diff --git a/changelogs/unreleased/error-tracking-api.yml b/changelogs/unreleased/error-tracking-api.yml
new file mode 100644
index 00000000000..7face12f23d
--- /dev/null
+++ b/changelogs/unreleased/error-tracking-api.yml
@@ -0,0 +1,5 @@
+---
+title: Add API for getting sentry error tracking settings of a project
+merge_request: 21788
+author: raju249
+type: added
diff --git a/changelogs/unreleased/pravi-gitlab-update-d3.yml b/changelogs/unreleased/pravi-gitlab-update-d3.yml
new file mode 100644
index 00000000000..32d492a42fa
--- /dev/null
+++ b/changelogs/unreleased/pravi-gitlab-update-d3.yml
@@ -0,0 +1,5 @@
+---
+title: Update d3 to 5.12
+merge_request: 20627
+author: Praveen Arimbrathodiyil
+type: other
diff --git a/changelogs/unreleased/security-project-import-vn-master.yml b/changelogs/unreleased/security-project-import-vn-master.yml
deleted file mode 100644
index 930358626fd..00000000000
--- a/changelogs/unreleased/security-project-import-vn-master.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix private objects exposure when using Project Import functionality
-merge_request:
-author:
-type: security
diff --git a/db/migrate/20200103190741_add_column_for_instance_administrators_group.rb b/db/migrate/20200103190741_add_column_for_instance_administrators_group.rb
new file mode 100644
index 00000000000..5afc7dc6a4d
--- /dev/null
+++ b/db/migrate/20200103190741_add_column_for_instance_administrators_group.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddColumnForInstanceAdministratorsGroup < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings, :instance_administrators_group_id, :integer
+ end
+end
diff --git a/db/migrate/20200103192859_add_fk_for_instance_administrators_group.rb b/db/migrate/20200103192859_add_fk_for_instance_administrators_group.rb
new file mode 100644
index 00000000000..0ad37d6bd29
--- /dev/null
+++ b/db/migrate/20200103192859_add_fk_for_instance_administrators_group.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddFkForInstanceAdministratorsGroup < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key(
+ :application_settings,
+ :namespaces,
+ column: :instance_administrators_group_id,
+ on_delete: :nullify
+ )
+ end
+
+ def down
+ remove_foreign_key :application_settings, column: :instance_administrators_group_id
+ end
+end
diff --git a/db/migrate/20200103192914_add_index_for_instance_administrators_group.rb b/db/migrate/20200103192914_add_index_for_instance_administrators_group.rb
new file mode 100644
index 00000000000..703dcf5d0e3
--- /dev/null
+++ b/db/migrate/20200103192914_add_index_for_instance_administrators_group.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexForInstanceAdministratorsGroup < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :application_settings, :instance_administrators_group_id
+ end
+
+ def down
+ remove_concurrent_index :application_settings, :instance_administrators_group_id
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ea2df01e1e2..689428ea4cb 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -365,9 +365,11 @@ ActiveRecord::Schema.define(version: 2020_01_08_233040) do
t.text "encrypted_slack_app_verification_token"
t.string "encrypted_slack_app_verification_token_iv", limit: 255
t.boolean "updating_name_disabled_for_users", default: false, null: false
+ t.integer "instance_administrators_group_id"
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id"
+ t.index ["instance_administrators_group_id"], name: "index_application_settings_on_instance_administrators_group_id"
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id"
end
@@ -4414,6 +4416,7 @@ ActiveRecord::Schema.define(version: 2020_01_08_233040) do
add_foreign_key "analytics_repository_file_edits", "projects", on_delete: :cascade
add_foreign_key "analytics_repository_files", "projects", on_delete: :cascade
add_foreign_key "application_settings", "namespaces", column: "custom_project_templates_group_id", on_delete: :nullify
+ add_foreign_key "application_settings", "namespaces", column: "instance_administrators_group_id", name: "fk_e8a145f3a7", on_delete: :nullify
add_foreign_key "application_settings", "projects", column: "file_template_project_id", name: "fk_ec757bd087", on_delete: :nullify
add_foreign_key "application_settings", "projects", column: "instance_administration_project_id", on_delete: :nullify
add_foreign_key "application_settings", "users", column: "usage_stats_set_by_user_id", name: "fk_964370041d", on_delete: :nullify
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index d14c6c8feca..6eba9bf23bf 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -29,6 +29,7 @@ The following API resources are available in the project context:
| [Deployments](deployments.md) | `/projects/:id/deployments` |
| [Discussions](discussions.md) (threaded comments) | `/projects/:id/issues/.../discussions`, `/projects/:id/snippets/.../discussions`, `/projects/:id/merge_requests/.../discussions`, `/projects/:id/commits/.../discussions` (also available for groups) |
| [Environments](environments.md) | `/projects/:id/environments` |
+| [Error Tracking](error_tracking.md) | `/projects/:id/error_tracking/settings` |
| [Events](events.md) | `/projects/:id/events` (also available for users and standalone) |
| [Issues](issues.md) | `/projects/:id/issues` (also available for groups and standalone) |
| [Issues Statistics](issues_statistics.md) | `/projects/:id/issues_statistics` (also available for groups and standalone) |
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index 916c99d5f89..2b5942f6b7a 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -349,3 +349,19 @@ Example of a response:
"deployable": null
}
```
+
+## List of merge requests associated with a deployment
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/35739) in GitLab 12.7.
+
+This API retrieves the list of merge requests shipped with a given deployment:
+
+```
+GET /projects/:id/deployments/:deployment_id/merge_requests
+```
+
+It supports the same parameters as the [Merge Requests API](./merge_requests.md#list-merge-requests) and will return a response using the same format:
+
+```bash
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/42"
+```
diff --git a/doc/api/error_tracking.md b/doc/api/error_tracking.md
new file mode 100644
index 00000000000..77dc7f8629f
--- /dev/null
+++ b/doc/api/error_tracking.md
@@ -0,0 +1,31 @@
+# Error Tracking settings API
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34940) in GitLab 12.7.
+
+## Error Tracking project settings
+
+The project settings API allows you to retrieve the Error Tracking settings for a project. Only for project maintainers.
+
+### Get Error Tracking settings
+
+```
+GET /projects/:id/error_tracking/settings
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+
+```bash
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/error_tracking/settings
+```
+
+Example response:
+
+```json
+{
+ "project_name": "sample sentry project",
+ "sentry_external_url": "https://sentry.io/myawesomeproject/project",
+ "api_url": "https://sentry.io/api/0/projects/myawesomeproject/project"
+}
+```
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index c722c966273..b59cb8068c9 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -550,7 +550,7 @@ Parameters:
},
"user" : {
"can_merge" : false
- }
+ },
"assignee": {
"id": 1,
"name": "Administrator",
diff --git a/doc/development/logging.md b/doc/development/logging.md
index 2eb140d3b7e..5d6b2d535b8 100644
--- a/doc/development/logging.md
+++ b/doc/development/logging.md
@@ -127,6 +127,88 @@ importer progresses. Here's what to do:
logger.info(message: "Import error", error_code: 1, error: "I/O failure")
```
+## Multi-destination Logging
+
+GitLab is transitioning from unstructured/plaintext logs to structured/JSON logs. During this transition period some logs will be recorded in multiple formats through multi-destination logging.
+
+### How to use multi-destination logging
+
+Create a new logger class, inheriting from `MultiDestinationLogger` and add an array of loggers to a `LOGGERS` constant. The loggers should be classes that descend from `Gitlab::Logger`. e.g. the user defined loggers in the following examples, could be inheriting from `Gitlab::Logger` and `Gitlab::JsonLogger`, respectively.
+
+You must specify one of the loggers as the `primary_logger`. The `primary_logger` will be used when information about this multi-destination logger is displayed in the app, e.g. using the `Gitlab::Logger.read_latest` method.
+
+The following example sets one of the defined `LOGGERS` as a `primary_logger`.
+
+```ruby
+module Gitlab
+ class FancyMultiLogger < Gitlab::MultiDestinationLogger
+ LOGGERS = [UnstructuredLogger, StructuredLogger].freeze
+
+ def self.loggers
+ LOGGERS
+ end
+
+ def primary_logger
+ UnstructuredLogger
+ end
+ end
+end
+```
+
+You can now call the usual logging methods on this multi-logger, e.g.
+
+```ruby
+FancyMultiLogger.info(message: "Information")
+```
+
+This message will be logged by each logger registered in `FancyMultiLogger.loggers`.
+
+### Passing a string or hash for logging
+
+When passing a string or hash to a `MultiDestinationLogger`, the log lines could be formatted differently, depending on the kinds of `LOGGERS` set.
+
+e.g. let's partially define the loggers from the previous example:
+
+```ruby
+module Gitlab
+ # Similar to AppTextLogger
+ class UnstructuredLogger < Gitlab::Logger
+ ...
+ end
+
+ # Similar to AppJsonLogger
+ class StructuredLogger < Gitlab::JsonLogger
+ ...
+ end
+end
+```
+
+Here are some examples of how messages would be handled by both the loggers.
+
+1. When passing a string
+
+```ruby
+FancyMultiLogger.info("Information")
+
+# UnstructuredLogger
+I, [2020-01-13T12:02:41.566219 #6652] INFO -- : Information
+
+# StructuredLogger
+{:severity=>"INFO", :time=>"2020-01-13T11:02:41.559Z", :correlation_id=>"b1701f7ecc4be4bcd4c2d123b214e65a", :message=>"Information"}
+```
+
+1. When passing a hash
+
+```ruby
+FancyMultiLogger.info({:message=>"This is my message", :project_id=>123})
+
+# UnstructuredLogger
+I, [2020-01-13T12:06:09.856766 #8049] INFO -- : {:message=>"This is my message", :project_id=>123}
+
+# StructuredLogger
+{:severity=>"INFO", :time=>"2020-01-13T11:06:09.851Z", :correlation_id=>"d7e0886f096db9a8526a4f89da0e45f6", :message=>"This is my message", :project_id=>123}
+```
+
## Exception Handling
It often happens that you catch the exception and want to track it.
diff --git a/doc/development/testing_guide/end_to_end/index.md b/doc/development/testing_guide/end_to_end/index.md
index 85cad3971c3..96141a5d68d 100644
--- a/doc/development/testing_guide/end_to_end/index.md
+++ b/doc/development/testing_guide/end_to_end/index.md
@@ -34,8 +34,8 @@ a pipeline in the [`gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/) projec
by triggering the `package-and-qa` manual action in the `test` stage (not
available for forks).
-**This runs end-to-end tests against a custom Omnibus package built from your
-merge request's changes.**
+**This runs end-to-end tests against a custom CE and EE (with an Ultimate license)
+Omnibus package built from your merge request's changes.**
Manual action that starts end-to-end tests is also available in merge requests
in [Omnibus GitLab][omnibus-gitlab].
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index a667c2e84c9..11e768194bc 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -155,7 +155,7 @@ Identity Provider.
### Requirements
First you need to tell GitLab where to look for group information. For this you
-need to make sure that your IdP server sends a specific `AttributeStament` along
+need to make sure that your IdP server sends a specific `AttributeStatement` along
with the regular SAML response. Here is an example:
```xml
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 555639a4b62..1aee4fd30ee 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -117,6 +117,7 @@ module API
mount ::API::DeployKeys
mount ::API::Deployments
mount ::API::Environments
+ mount ::API::ErrorTracking
mount ::API::Events
mount ::API::Features
mount ::API::Files
diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb
index 84d1d8a0aac..62bda64896b 100644
--- a/lib/api/deployments.rb
+++ b/lib/api/deployments.rb
@@ -127,6 +127,26 @@ module API
render_validation_error!(deployment)
end
end
+
+ helpers Helpers::MergeRequestsHelpers
+
+ desc 'Get all merge requests of a deployment' do
+ detail 'This feature was introduced in GitLab 12.7.'
+ success Entities::MergeRequestBasic
+ end
+ params do
+ requires :deployment_id, type: Integer, desc: 'The deployment ID'
+ use :merge_requests_base_params
+ end
+
+ get ':id/deployments/:deployment_id/merge_requests' do
+ authorize! :read_deployment, user_project
+
+ mr_params = declared_params.merge(deployment_id: params[:deployment_id])
+ merge_requests = MergeRequestsFinder.new(current_user, mr_params).execute
+
+ present merge_requests, { with: Entities::MergeRequestBasic, current_user: current_user }
+ end
end
end
end
diff --git a/lib/api/entities/error_tracking.rb b/lib/api/entities/error_tracking.rb
new file mode 100644
index 00000000000..0180572a6cc
--- /dev/null
+++ b/lib/api/entities/error_tracking.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ module ErrorTracking
+ class ProjectSetting < Grape::Entity
+ expose :project_name
+ expose :sentry_external_url
+ expose :api_url
+ end
+ end
+ end
+end
diff --git a/lib/api/error_tracking.rb b/lib/api/error_tracking.rb
new file mode 100644
index 00000000000..f92f1326daa
--- /dev/null
+++ b/lib/api/error_tracking.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module API
+ class ErrorTracking < Grape::API
+ before { authenticate! }
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+
+ resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ desc 'Get error tracking settings for the project' do
+ detail 'This feature was introduced in GitLab 12.7.'
+ success Entities::ErrorTracking::ProjectSetting
+ end
+
+ get ':id/error_tracking/settings' do
+ authorize! :admin_operations, user_project
+
+ setting = user_project.error_tracking_setting
+
+ not_found!('Error Tracking Setting') unless setting
+
+ present setting, with: Entities::ErrorTracking::ProjectSetting
+ end
+ end
+ end
+end
diff --git a/lib/api/helpers/merge_requests_helpers.rb b/lib/api/helpers/merge_requests_helpers.rb
new file mode 100644
index 00000000000..0126d7a3756
--- /dev/null
+++ b/lib/api/helpers/merge_requests_helpers.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module API
+ module Helpers
+ module MergeRequestsHelpers
+ extend Grape::API::Helpers
+ include ::API::Helpers::CustomValidators
+
+ params :merge_requests_base_params do
+ optional :state,
+ type: String,
+ values: %w[opened closed locked merged all],
+ default: 'all',
+ desc: 'Return opened, closed, locked, merged, or all merge requests'
+ optional :order_by,
+ type: String,
+ values: %w[created_at updated_at],
+ default: 'created_at',
+ desc: 'Return merge requests ordered by `created_at` or `updated_at` fields.'
+ optional :sort,
+ type: String,
+ values: %w[asc desc],
+ default: 'desc',
+ desc: 'Return merge requests sorted in `asc` or `desc` order.'
+ optional :milestone, type: String, desc: 'Return merge requests for a specific milestone'
+ optional :labels,
+ type: Array[String],
+ coerce_with: Validations::Types::LabelsList.coerce,
+ desc: 'Comma-separated list of label names'
+ optional :with_labels_details, type: Boolean, desc: 'Return titles of labels and other details', default: false
+ optional :created_after, type: DateTime, desc: 'Return merge requests created after the specified time'
+ optional :created_before, type: DateTime, desc: 'Return merge requests created before the specified time'
+ optional :updated_after, type: DateTime, desc: 'Return merge requests updated after the specified time'
+ optional :updated_before, type: DateTime, desc: 'Return merge requests updated before the specified time'
+ optional :view,
+ type: String,
+ values: %w[simple],
+ desc: 'If simple, returns the `iid`, URL, title, description, and basic state of merge request'
+ optional :author_id, type: Integer, desc: 'Return merge requests which are authored by the user with the given ID'
+ optional :assignee_id,
+ types: [Integer, String],
+ integer_none_any: true,
+ desc: 'Return merge requests which are assigned to the user with the given ID'
+ optional :scope,
+ type: String,
+ values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all],
+ desc: 'Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`'
+ optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji'
+ optional :source_branch, type: String, desc: 'Return merge requests with the given source branch'
+ optional :source_project_id, type: Integer, desc: 'Return merge requests with the given source project id'
+ optional :target_branch, type: String, desc: 'Return merge requests with the given target branch'
+ optional :search,
+ type: String,
+ desc: 'Search merge requests for text present in the title, description, or any combination of these'
+ optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma'
+ optional :wip, type: String, values: %w[yes no], desc: 'Search merge requests for WIP in the title'
+ end
+
+ params :optional_scope_param do
+ optional :scope,
+ type: String,
+ values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all],
+ default: 'created_by_me',
+ desc: 'Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`'
+ end
+ end
+ end
+end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 8e65fe2b7a2..9ac268e5b31 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -7,6 +7,7 @@ module API
before { authenticate_non_get! }
helpers ::Gitlab::IssuableMetadata
+ helpers Helpers::MergeRequestsHelpers
# EE::API::MergeRequests would override the following helpers
helpers do
@@ -107,33 +108,7 @@ module API
end
params :merge_requests_params do
- optional :state, type: String, values: %w[opened closed locked merged all], default: 'all',
- desc: 'Return opened, closed, locked, merged, or all merge requests'
- optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at',
- desc: 'Return merge requests ordered by `created_at` or `updated_at` fields.'
- optional :sort, type: String, values: %w[asc desc], default: 'desc',
- desc: 'Return merge requests sorted in `asc` or `desc` order.'
- optional :milestone, type: String, desc: 'Return merge requests for a specific milestone'
- optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
- optional :with_labels_details, type: Boolean, desc: 'Return titles of labels and other details', default: false
- optional :created_after, type: DateTime, desc: 'Return merge requests created after the specified time'
- optional :created_before, type: DateTime, desc: 'Return merge requests created before the specified time'
- optional :updated_after, type: DateTime, desc: 'Return merge requests updated after the specified time'
- optional :updated_before, type: DateTime, desc: 'Return merge requests updated before the specified time'
- optional :view, type: String, values: %w[simple], desc: 'If simple, returns the `iid`, URL, title, description, and basic state of merge request'
- optional :author_id, type: Integer, desc: 'Return merge requests which are authored by the user with the given ID'
- optional :assignee_id, types: [Integer, String], integer_none_any: true,
- desc: 'Return merge requests which are assigned to the user with the given ID'
- optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all],
- desc: 'Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`'
- optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji'
- optional :source_branch, type: String, desc: 'Return merge requests with the given source branch'
- optional :source_project_id, type: Integer, desc: 'Return merge requests with the given source project id'
- optional :target_branch, type: String, desc: 'Return merge requests with the given target branch'
- optional :search, type: String, desc: 'Search merge requests for text present in the title, description, or any combination of these'
- optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma'
- optional :wip, type: String, values: %w[yes no], desc: 'Search merge requests for WIP in the title'
-
+ use :merge_requests_base_params
use :optional_merge_requests_search_params
use :pagination
end
@@ -145,8 +120,7 @@ module API
end
params do
use :merge_requests_params
- optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me',
- desc: 'Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`'
+ use :optional_scope_param
end
get do
authenticate! unless params[:scope] == 'all'
diff --git a/lib/gitlab/app_json_logger.rb b/lib/gitlab/app_json_logger.rb
new file mode 100644
index 00000000000..e29b205e1bf
--- /dev/null
+++ b/lib/gitlab/app_json_logger.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class AppJsonLogger < Gitlab::JsonLogger
+ def self.file_name_noext
+ 'application_json'
+ end
+ end
+end
diff --git a/lib/gitlab/app_logger.rb b/lib/gitlab/app_logger.rb
index 5edec8b3efe..3f5e9adf925 100644
--- a/lib/gitlab/app_logger.rb
+++ b/lib/gitlab/app_logger.rb
@@ -1,13 +1,15 @@
# frozen_string_literal: true
module Gitlab
- class AppLogger < Gitlab::Logger
- def self.file_name_noext
- 'application'
+ class AppLogger < Gitlab::MultiDestinationLogger
+ LOGGERS = [Gitlab::AppTextLogger, Gitlab::AppJsonLogger].freeze
+
+ def self.loggers
+ LOGGERS
end
- def format_message(severity, timestamp, progname, msg)
- "#{timestamp.to_s(:long)}: #{msg}\n"
+ def self.primary_logger
+ Gitlab::AppTextLogger
end
end
end
diff --git a/lib/gitlab/app_text_logger.rb b/lib/gitlab/app_text_logger.rb
new file mode 100644
index 00000000000..59ac57b2bb4
--- /dev/null
+++ b/lib/gitlab/app_text_logger.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class AppTextLogger < Gitlab::Logger
+ def self.file_name_noext
+ 'application'
+ end
+
+ def format_message(severity, timestamp, progname, msg)
+ "#{timestamp.to_s(:long)}: #{msg}\n"
+ end
+ end
+end
diff --git a/lib/gitlab/multi_destination_logger.rb b/lib/gitlab/multi_destination_logger.rb
new file mode 100644
index 00000000000..b6b19e81389
--- /dev/null
+++ b/lib/gitlab/multi_destination_logger.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class MultiDestinationLogger < ::Logger
+ def close
+ loggers.each(&:close)
+ end
+
+ def self.debug(message)
+ loggers.each { |logger| logger.build.debug(message) }
+ end
+
+ def self.error(message)
+ loggers.each { |logger| logger.build.error(message) }
+ end
+
+ def self.warn(message)
+ loggers.each { |logger| logger.build.warn(message) }
+ end
+
+ def self.info(message)
+ loggers.each { |logger| logger.build.info(message) }
+ end
+
+ def self.read_latest
+ primary_logger.read_latest
+ end
+
+ def self.file_name
+ primary_logger.file_name
+ end
+
+ def self.full_log_path
+ primary_logger.full_log_path
+ end
+
+ def self.file_name_noext
+ primary_logger.file_name_noext
+ end
+
+ def self.loggers
+ raise NotImplementedError
+ end
+
+ def self.primary_logger
+ raise NotImplementedError
+ end
+ end
+end
diff --git a/package.json b/package.json
index 938b2cdecf4..95bf5214b78 100644
--- a/package.json
+++ b/package.json
@@ -66,7 +66,7 @@
"core-js": "^3.2.1",
"cropper": "^2.3.0",
"css-loader": "^1.0.0",
- "d3": "^4.13.0",
+ "d3": "^5.12.0",
"d3-scale": "^1.0.7",
"d3-selection": "^1.2.0",
"dateformat": "^3.0.3",
diff --git a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
index 90290b4f2a0..eecf485a518 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
@@ -22,8 +22,15 @@ module QA
expect(page).to have_content(/@#{user.username}(\n| )?Given access/)
- # Wait for Action Mailer to deliver messages
- mailhog_json = Support::Retrier.retry_until(sleep_interval: 1) do
+ mailhog_items = mailhog_json.dig('items')
+
+ expect(mailhog_items).to include(an_object_satisfying { |o| /project was granted/ === o.dig('Content', 'Headers', 'Subject', 0) })
+ end
+
+ private
+
+ def mailhog_json
+ Support::Retrier.retry_until(sleep_interval: 1) do
Runtime::Logger.debug(%Q[retrieving "#{QA::Runtime::MailHog.api_messages_url}"])
mailhog_response = get QA::Runtime::MailHog.api_messages_url
@@ -33,10 +40,6 @@ module QA
# Expect at least two invitation messages: group and project
mailhog_data if mailhog_data.dig('total') >= 2
end
-
- # Check json result from mailhog
- mailhog_items = mailhog_json.dig('items')
- expect(mailhog_items).to include(an_object_satisfying { |o| /project was granted/ === o.dig('Content', 'Headers', 'Subject', 0) })
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index 254efb741b3..32605bc8970 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -28,11 +28,9 @@ module QA
end
before do
- issue = Resource::Issue.fabricate_via_api! do |issue|
+ Resource::Issue.fabricate_via_api! do |issue|
issue.title = issue_title
- end
-
- issue.visit!
+ end.visit!
end
it 'user comments on an issue with an attachment' do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
index a4f6b0bb1bf..a0652971693 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
@@ -8,11 +8,9 @@ module QA
before do
Flow::Login.sign_in
- issue = Resource::Issue.fabricate_via_api! do |issue|
+ Resource::Issue.fabricate_via_api! do |issue|
issue.title = issue_title
- end
-
- issue.visit!
+ end.visit!
end
it 'user filters comments and activities in an issue' do
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index bc85a622119..849387b72bd 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -166,6 +166,38 @@ describe MergeRequestsFinder do
expect(scalar_params).to include(:wip, :assignee_id)
end
+
+ context 'filter by deployment' do
+ let_it_be(:project_with_repo) { create(:project, :repository) }
+
+ it 'returns the relevant merge requests' do
+ deployment1 = create(
+ :deployment,
+ project: project_with_repo,
+ sha: project_with_repo.commit.id,
+ merge_requests: [merge_request1, merge_request2]
+ )
+ create(
+ :deployment,
+ project: project_with_repo,
+ sha: project_with_repo.commit.id,
+ merge_requests: [merge_request3]
+ )
+ params = { deployment_id: deployment1.id }
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
+ end
+
+ context 'when a deployment does not contain any merge requests' do
+ it 'returns an empty result' do
+ params = { deployment_id: create(:deployment, project: project_with_repo, sha: project_with_repo.commit.sha).id }
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to be_empty
+ end
+ end
+ end
end
context 'assignee filtering' do
diff --git a/spec/lib/gitlab/app_json_logger_spec.rb b/spec/lib/gitlab/app_json_logger_spec.rb
new file mode 100644
index 00000000000..22a398f8bca
--- /dev/null
+++ b/spec/lib/gitlab/app_json_logger_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::AppJsonLogger do
+ subject { described_class.new('/dev/null') }
+
+ let(:hash_message) { { 'message' => 'Message', 'project_id' => '123' } }
+ let(:string_message) { 'Information' }
+
+ it 'logs a hash as a JSON' do
+ expect(JSON.parse(subject.format_message('INFO', Time.now, nil, hash_message))).to include(hash_message)
+ end
+
+ it 'logs a string as a JSON' do
+ expect(JSON.parse(subject.format_message('INFO', Time.now, nil, string_message))).to include('message' => string_message)
+ end
+end
diff --git a/spec/lib/gitlab/app_logger_spec.rb b/spec/lib/gitlab/app_logger_spec.rb
index 3b21104b15d..132a10b9409 100644
--- a/spec/lib/gitlab/app_logger_spec.rb
+++ b/spec/lib/gitlab/app_logger_spec.rb
@@ -2,13 +2,21 @@
require 'spec_helper'
-describe Gitlab::AppLogger, :request_store do
+describe Gitlab::AppLogger do
subject { described_class }
- it 'builds a logger once' do
- expect(::Logger).to receive(:new).and_call_original
+ it 'builds a Gitlab::Logger object twice' do
+ expect(Gitlab::Logger).to receive(:new)
+ .exactly(described_class.loggers.size)
+ .and_call_original
- subject.info('hello world')
- subject.error('hello again')
+ subject.info('Hello World!')
+ end
+
+ it 'logs info to AppLogger and AppJsonLogger' do
+ expect_any_instance_of(Gitlab::AppTextLogger).to receive(:info).and_call_original
+ expect_any_instance_of(Gitlab::AppJsonLogger).to receive(:info).and_call_original
+
+ subject.info('Hello World!')
end
end
diff --git a/spec/lib/gitlab/app_text_logger_spec.rb b/spec/lib/gitlab/app_text_logger_spec.rb
new file mode 100644
index 00000000000..06d3e643608
--- /dev/null
+++ b/spec/lib/gitlab/app_text_logger_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::AppTextLogger do
+ subject { described_class.new('/dev/null') }
+
+ let(:hash_message) { { message: 'Message', project_id: 123 } }
+ let(:string_message) { 'Information' }
+
+ it 'logs a hash as string' do
+ expect(subject.format_message('INFO', Time.now, nil, hash_message )).to include(hash_message.to_s)
+ end
+
+ it 'logs a string unchanged' do
+ expect(subject.format_message('INFO', Time.now, nil, string_message)).to include(string_message)
+ end
+end
diff --git a/spec/lib/gitlab/multi_destination_logger_spec.rb b/spec/lib/gitlab/multi_destination_logger_spec.rb
new file mode 100644
index 00000000000..7acd7906a26
--- /dev/null
+++ b/spec/lib/gitlab/multi_destination_logger_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+class FakeLogger
+end
+
+class LoggerA < Gitlab::Logger
+ def self.file_name_noext
+ 'loggerA'
+ end
+end
+
+class LoggerB < Gitlab::JsonLogger
+ def self.file_name_noext
+ 'loggerB'
+ end
+end
+
+class TestLogger < Gitlab::MultiDestinationLogger
+ LOGGERS = [LoggerA, LoggerB].freeze
+
+ def self.loggers
+ LOGGERS
+ end
+end
+
+class EmptyLogger < Gitlab::MultiDestinationLogger
+ def self.loggers
+ []
+ end
+end
+
+describe Gitlab::MultiDestinationLogger do
+ after(:all) do
+ TestLogger.loggers.each do |logger|
+ log_file_path = "#{Rails.root}/log/#{logger.file_name}"
+ File.delete(log_file_path)
+ end
+ end
+
+ context 'with no primary logger set' do
+ subject { EmptyLogger }
+
+ it 'primary_logger raises an error' do
+ expect { subject.primary_logger }.to raise_error(NotImplementedError)
+ end
+ end
+
+ context 'with 2 loggers set' do
+ subject { TestLogger }
+
+ it 'logs info to 2 loggers' do
+ expect(subject.loggers).to all(receive(:build).and_call_original)
+
+ subject.info('Hello World')
+ end
+ end
+end
diff --git a/spec/requests/api/deployments_spec.rb b/spec/requests/api/deployments_spec.rb
index 7e184cea3c0..9add328f6a8 100644
--- a/spec/requests/api/deployments_spec.rb
+++ b/spec/requests/api/deployments_spec.rb
@@ -343,6 +343,48 @@ describe API::Deployments do
end
end
+ describe 'GET /projects/:id/deployments/:deployment_id/merge_requests' do
+ let(:project) { create(:project, :repository) }
+ let!(:deployment) { create(:deployment, :success, project: project) }
+
+ subject { get api("/projects/#{project.id}/deployments/#{deployment.id}/merge_requests", user) }
+
+ context 'when a user is not a member of the deployment project' do
+ let(:user) { build(:user) }
+
+ it 'returns a 404 status code' do
+ subject
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ context 'when a user member of the deployment project' do
+ let_it_be(:project2) { create(:project) }
+ let!(:merge_request1) { create(:merge_request, source_project: project, target_project: project) }
+ let!(:merge_request2) { create(:merge_request, source_project: project, target_project: project, state: 'closed') }
+ let!(:merge_request3) { create(:merge_request, source_project: project2, target_project: project2) }
+
+ it 'returns the relevant merge requests linked to a deployment for a project' do
+ deployment.merge_requests << [merge_request1, merge_request2]
+
+ subject
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.map { |d| d['id'] }).to contain_exactly(merge_request1.id, merge_request2.id)
+ end
+
+ context 'when a deployment is not associated to any existing merge requests' do
+ it 'returns an empty array' do
+ subject
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response).to eq([])
+ end
+ end
+ end
+ end
+
context 'prevent N + 1 queries' do
context 'when the endpoint returns multiple records' do
let(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/error_tracking_spec.rb b/spec/requests/api/error_tracking_spec.rb
new file mode 100644
index 00000000000..af337f34a68
--- /dev/null
+++ b/spec/requests/api/error_tracking_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::ErrorTracking do
+ describe "GET /projects/:id/error_tracking/settings" do
+ let(:user) { create(:user) }
+ let(:setting) { create(:project_error_tracking_setting) }
+ let(:project) { setting.project }
+
+ def make_request
+ get api("/projects/#{project.id}/error_tracking/settings", user)
+ end
+
+ context 'when authenticated as maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'returns project settings' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq(
+ 'project_name' => setting.project_name,
+ 'sentry_external_url' => setting.sentry_external_url,
+ 'api_url' => setting.api_url
+ )
+ end
+ end
+
+ context 'without a project setting' do
+ let(:project) { create(:project) }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'returns 404' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message'])
+ .to eq('404 Error Tracking Setting Not Found')
+ end
+ end
+
+ context 'when authenticated as reporter' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it 'returns 403' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'when authenticated as non-member' do
+ it 'returns 404' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when unauthenticated' do
+ let(:user) { nil }
+
+ it 'returns 401' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+ end
+end
diff --git a/yarn.lock b/yarn.lock
index a3251391d1d..c7e5e2af1f3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3237,17 +3237,17 @@ cyclist@~0.2.2:
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
-d3-array@1, d3-array@1.2.1, d3-array@^1.1.1, d3-array@^1.2.0:
+d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
integrity sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==
-d3-axis@1, d3-axis@1.0.8:
+d3-axis@1:
version "1.0.8"
resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.8.tgz#31a705a0b535e65759de14173a31933137f18efa"
integrity sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=
-d3-brush@1, d3-brush@1.0.4:
+d3-brush@1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.4.tgz#00c2f238019f24f6c0a194a26d41a1530ffe7bc4"
integrity sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=
@@ -3258,7 +3258,7 @@ d3-brush@1, d3-brush@1.0.4:
d3-selection "1"
d3-transition "1"
-d3-chord@1, d3-chord@1.0.4:
+d3-chord@1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.4.tgz#7dec4f0ba886f713fe111c45f763414f6f74ca2c"
integrity sha1-fexPC6iG9xP+ERxF92NBT290yiw=
@@ -3266,12 +3266,12 @@ d3-chord@1, d3-chord@1.0.4:
d3-array "1"
d3-path "1"
-d3-collection@1, d3-collection@1.0.4:
+d3-collection@1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.4.tgz#342dfd12837c90974f33f1cc0a785aea570dcdc2"
integrity sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=
-d3-color@1, d3-color@1.0.3:
+d3-color@1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b"
integrity sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=
@@ -3283,12 +3283,12 @@ d3-contour@1:
dependencies:
d3-array "^1.1.1"
-d3-dispatch@1, d3-dispatch@1.0.3:
+d3-dispatch@1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8"
integrity sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=
-d3-drag@1, d3-drag@1.2.1:
+d3-drag@1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.1.tgz#df8dd4c502fb490fc7462046a8ad98a5c479282d"
integrity sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==
@@ -3296,7 +3296,7 @@ d3-drag@1, d3-drag@1.2.1:
d3-dispatch "1"
d3-selection "1"
-d3-dsv@1, d3-dsv@1.0.8:
+d3-dsv@1:
version "1.0.8"
resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.8.tgz#907e240d57b386618dc56468bacfe76bf19764ae"
integrity sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==
@@ -3305,7 +3305,7 @@ d3-dsv@1, d3-dsv@1.0.8:
iconv-lite "0.4"
rw "1"
-d3-ease@1, d3-ease@1.0.3:
+d3-ease@1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
integrity sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=
@@ -3317,7 +3317,7 @@ d3-fetch@1:
dependencies:
d3-dsv "1"
-d3-force@1, d3-force@1.1.0:
+d3-force@1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.1.0.tgz#cebf3c694f1078fcc3d4daf8e567b2fbd70d4ea3"
integrity sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==
@@ -3327,65 +3327,50 @@ d3-force@1, d3-force@1.1.0:
d3-quadtree "1"
d3-timer "1"
-d3-format@1, d3-format@1.2.2:
+d3-format@1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.2.tgz#1a39c479c8a57fe5051b2e67a3bee27061a74e7a"
integrity sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==
-d3-geo@1, d3-geo@1.9.1:
+d3-geo@1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.9.1.tgz#157e3b0f917379d0f73bebfff3be537f49fa7356"
integrity sha512-l9wL/cEQkyZQYXw3xbmLsH3eQ5ij+icNfo4r0GrLa5rOCZR/e/3am45IQ0FvQ5uMsv+77zBRunLc9ufTWSQYFA==
dependencies:
d3-array "1"
-d3-hierarchy@1, d3-hierarchy@1.1.5:
+d3-hierarchy@1:
version "1.1.5"
resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz#a1c845c42f84a206bcf1c01c01098ea4ddaa7a26"
integrity sha1-ochFxC+Eoga88cAcAQmOpN2qeiY=
-d3-interpolate@1, d3-interpolate@1.1.6:
+d3-interpolate@1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6"
integrity sha512-mOnv5a+pZzkNIHtw/V6I+w9Lqm9L5bG3OTXPM5A+QO0yyVMQ4W1uZhR+VOJmazaOZXri2ppbiZ5BUNWT0pFM9A==
dependencies:
d3-color "1"
-d3-path@1, d3-path@1.0.5:
+d3-path@1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
integrity sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=
-d3-polygon@1, d3-polygon@1.0.3:
+d3-polygon@1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.3.tgz#16888e9026460933f2b179652ad378224d382c62"
integrity sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=
-d3-quadtree@1, d3-quadtree@1.0.3:
+d3-quadtree@1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.3.tgz#ac7987e3e23fe805a990f28e1b50d38fcb822438"
integrity sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=
-d3-queue@3.0.7:
- version "3.0.7"
- resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618"
- integrity sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=
-
-d3-random@1, d3-random@1.1.0:
+d3-random@1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3"
integrity sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=
-d3-request@1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/d3-request/-/d3-request-1.0.6.tgz#a1044a9ef4ec28c824171c9379fae6d79474b19f"
- integrity sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==
- dependencies:
- d3-collection "1"
- d3-dispatch "1"
- d3-dsv "1"
- xmlhttprequest "1"
-
d3-scale-chromatic@1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz#dad4366f0edcb288f490128979c3c793583ed3c0"
@@ -3394,61 +3379,61 @@ d3-scale-chromatic@1:
d3-color "1"
d3-interpolate "1"
-d3-scale@1.0.7, d3-scale@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.7.tgz#fa90324b3ea8a776422bd0472afab0b252a0945d"
- integrity sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==
+d3-scale@2:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f"
+ integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==
dependencies:
d3-array "^1.2.0"
d3-collection "1"
- d3-color "1"
d3-format "1"
d3-interpolate "1"
d3-time "1"
d3-time-format "2"
-d3-scale@2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f"
- integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==
+d3-scale@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.7.tgz#fa90324b3ea8a776422bd0472afab0b252a0945d"
+ integrity sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==
dependencies:
d3-array "^1.2.0"
d3-collection "1"
+ d3-color "1"
d3-format "1"
d3-interpolate "1"
d3-time "1"
d3-time-format "2"
-d3-selection@1, d3-selection@1.3.0, d3-selection@^1.1.0, d3-selection@^1.2.0:
+d3-selection@1, d3-selection@^1.1.0, d3-selection@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==
-d3-shape@1, d3-shape@1.2.0:
+d3-shape@1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
integrity sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=
dependencies:
d3-path "1"
-d3-time-format@2, d3-time-format@2.1.1:
+d3-time-format@2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.1.tgz#85b7cdfbc9ffca187f14d3c456ffda268081bb31"
integrity sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==
dependencies:
d3-time "1"
-d3-time@1, d3-time@1.0.8:
+d3-time@1:
version "1.0.8"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.8.tgz#dbd2d6007bf416fe67a76d17947b784bffea1e84"
integrity sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==
-d3-timer@1, d3-timer@1.0.7:
+d3-timer@1:
version "1.0.7"
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531"
integrity sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==
-d3-transition@1, d3-transition@1.1.1:
+d3-transition@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.1.tgz#d8ef89c3b848735b060e54a39b32aaebaa421039"
integrity sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==
@@ -3460,12 +3445,12 @@ d3-transition@1, d3-transition@1.1.1:
d3-selection "^1.1.0"
d3-timer "1"
-d3-voronoi@1, d3-voronoi@1.1.2:
+d3-voronoi@1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
integrity sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=
-d3-zoom@1, d3-zoom@1.7.1:
+d3-zoom@1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.1.tgz#02f43b3c3e2db54f364582d7e4a236ccc5506b63"
integrity sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==
@@ -3476,43 +3461,44 @@ d3-zoom@1, d3-zoom@1.7.1:
d3-selection "1"
d3-transition "1"
-d3@^4.13.0:
- version "4.13.0"
- resolved "https://registry.yarnpkg.com/d3/-/d3-4.13.0.tgz#ab236ff8cf0cfc27a81e69bf2fb7518bc9b4f33d"
- integrity sha512-l8c4+0SldjVKLaE2WG++EQlqD7mh/dmQjvi2L2lKPadAVC+TbJC4ci7Uk9bRi+To0+ansgsS0iWfPjD7DBy+FQ==
- dependencies:
- d3-array "1.2.1"
- d3-axis "1.0.8"
- d3-brush "1.0.4"
- d3-chord "1.0.4"
- d3-collection "1.0.4"
- d3-color "1.0.3"
- d3-dispatch "1.0.3"
- d3-drag "1.2.1"
- d3-dsv "1.0.8"
- d3-ease "1.0.3"
- d3-force "1.1.0"
- d3-format "1.2.2"
- d3-geo "1.9.1"
- d3-hierarchy "1.1.5"
- d3-interpolate "1.1.6"
- d3-path "1.0.5"
- d3-polygon "1.0.3"
- d3-quadtree "1.0.3"
- d3-queue "3.0.7"
- d3-random "1.1.0"
- d3-request "1.0.6"
- d3-scale "1.0.7"
- d3-selection "1.3.0"
- d3-shape "1.2.0"
- d3-time "1.0.8"
- d3-time-format "2.1.1"
- d3-timer "1.0.7"
- d3-transition "1.1.1"
- d3-voronoi "1.1.2"
- d3-zoom "1.7.1"
-
-d3@^5.14, d3@^5.7.0:
+d3@^5.12.0, d3@^5.7.0:
+ version "5.12.0"
+ resolved "https://registry.yarnpkg.com/d3/-/d3-5.12.0.tgz#0ddeac879c28c882317cd439b495290acd59ab61"
+ integrity sha512-flYVMoVuhPFHd9zVCe2BxIszUWqBcd5fvQGMNRmSiBrgdnh6Vlruh60RJQTouAK9xPbOB0plxMvBm4MoyODXNg==
+ dependencies:
+ d3-array "1"
+ d3-axis "1"
+ d3-brush "1"
+ d3-chord "1"
+ d3-collection "1"
+ d3-color "1"
+ d3-contour "1"
+ d3-dispatch "1"
+ d3-drag "1"
+ d3-dsv "1"
+ d3-ease "1"
+ d3-fetch "1"
+ d3-force "1"
+ d3-format "1"
+ d3-geo "1"
+ d3-hierarchy "1"
+ d3-interpolate "1"
+ d3-path "1"
+ d3-polygon "1"
+ d3-quadtree "1"
+ d3-random "1"
+ d3-scale "2"
+ d3-scale-chromatic "1"
+ d3-selection "1"
+ d3-shape "1"
+ d3-time "1"
+ d3-time-format "2"
+ d3-timer "1"
+ d3-transition "1"
+ d3-voronoi "1"
+ d3-zoom "1"
+
+d3@^5.14:
version "5.15.0"
resolved "https://registry.yarnpkg.com/d3/-/d3-5.15.0.tgz#ffd44958e6a3cb8a59a84429c45429b8bca5677a"
integrity sha512-C+E80SL2nLLtmykZ6klwYj5rPqB5nlfN5LdWEAVdWPppqTD8taoJi2PxLZjPeYT8FFRR2yucXq+kBlOnnvZeLg==
@@ -12135,11 +12121,6 @@ xmlhttprequest-ssl@~1.5.4:
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
-xmlhttprequest@1:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
- integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=
-
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"