summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-10 09:09:39 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-10 09:09:39 +0000
commitc52b81f45762cb7f05a950689dfc6d51b197ea73 (patch)
treec44830c2fc21d13b81814958c44b09fa8d11c805
parent187ee320b39af22929d74c5a2d9b0650bf50a09b (diff)
downloadgitlab-ce-c52b81f45762cb7f05a950689dfc6d51b197ea73.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml51
-rw-r--r--app/assets/javascripts/monitoring/components/charts/annotations.js12
-rw-r--r--app/assets/javascripts/monitoring/components/charts/time_series.vue12
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss12
-rw-r--r--app/presenters/projects/prometheus/alert_presenter.rb2
-rw-r--r--app/services/metrics/dashboard/custom_metric_embed_service.rb47
-rw-r--r--changelogs/unreleased/sy-fix-multi-metric-embed.yml5
-rw-r--r--db/migrate/20200318183553_create_pypi_package_metadata.rb14
-rw-r--r--db/structure.sql12
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql15
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json34
-rw-r--r--doc/api/graphql/reference/index.md1
-rw-r--r--doc/user/incident_management/index.md4
-rw-r--r--doc/user/project/integrations/prometheus.md16
-rw-r--r--doc/user/project/issues/img/issue_health_status_dropdown_v12_10.pngbin0 -> 44744 bytes
-rw-r--r--doc/user/project/issues/index.md2
-rw-r--r--lib/gitlab/alerting/alert.rb10
-rw-r--r--locale/gitlab.pot33
-rw-r--r--spec/frontend/monitoring/components/charts/time_series_spec.js101
-rw-r--r--spec/lib/gitlab/alerting/alert_spec.rb10
-rw-r--r--spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb25
21 files changed, 307 insertions, 111 deletions
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index b1343afdb5e..61915aa798e 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -43,16 +43,16 @@ code_quality:
# We need to duplicate this job's definition because it seems it's impossible to
# override an included `only.refs`.
# See https://gitlab.com/gitlab-org/gitlab/issues/31371.
-# Once https://gitlab.com/gitlab-org/gitlab/merge_requests/16487 will be deployed
-# to GitLab.com, we should be able to use the template and set SAST_DISABLE_DIND: "true".
-sast:
+.sast:
extends:
- .default-retry
- .reports:rules:sast
- .use-docker-in-docker
stage: test
- allow_failure: true
+ # `needs: []` starts the job immediately in the pipeline
+ # https://docs.gitlab.com/ee/ci/yaml/README.html#needs
needs: []
+ allow_failure: true
artifacts:
paths:
- gl-sast-report.json # GitLab-specific
@@ -63,22 +63,39 @@ sast:
# emptying DOCKER_HOST so it can be detected properly on kubernetes executor
# with the script below
DOCKER_HOST: ""
+ DOCKER_DRIVER: overlay2
+ DOCKER_TLS_CERTDIR: ""
+ SAST_ANALYZER_IMAGE_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SAST_ANALYZER_IMAGE_TAG: 2
SAST_BRAKEMAN_LEVEL: 2 # GitLab-specific
SAST_EXCLUDED_PATHS: qa,spec,doc,ee/spec # GitLab-specific
script:
- - export SAST_VERSION=${SP_VERSION:-$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')}
- - |
- if ! docker info &>/dev/null; then
- if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
- export DOCKER_HOST='tcp://localhost:2375'
- fi
- fi
- - |
- ENVS=`printenv | grep -vE '^(DOCKER_|CI|GITLAB_|FF_|HOME|PWD|OLDPWD|PATH|SHLVL|HOSTNAME)' | sed -n '/^[^\t]/s/=.*//p' | sed '/^$/d' | sed 's/^/-e /g' | tr '\n' ' '`
- docker run "$ENVS" \
- --volume "$PWD:/code" \
- --volume /var/run/docker.sock:/var/run/docker.sock \
- "registry.gitlab.com/gitlab-org/security-products/sast:$SAST_VERSION" /app/bin/run /code
+ - /analyzer run
+
+brakeman-sast:
+ extends: .sast
+ image:
+ name: "$SAST_ANALYZER_IMAGE_PREFIX/brakeman:$SAST_ANALYZER_IMAGE_TAG"
+
+eslint-sast:
+ extends: .sast
+ image:
+ name: "$SAST_ANALYZER_IMAGE_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
+
+kubesec-sast:
+ extends: .sast
+ image:
+ name: "$SAST_ANALYZER_IMAGE_PREFIX/kubesec:$SAST_ANALYZER_IMAGE_TAG"
+
+nodejs-scan-sast:
+ extends: .sast
+ image:
+ name: "$SAST_ANALYZER_IMAGE_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
+
+secrets-sast:
+ extends: .sast
+ image:
+ name: "$SAST_ANALYZER_IMAGE_PREFIX/secrets:$SAST_ANALYZER_IMAGE_TAG"
# We need to duplicate this job's definition because it seems it's impossible to
# override an included `only.refs`.
diff --git a/app/assets/javascripts/monitoring/components/charts/annotations.js b/app/assets/javascripts/monitoring/components/charts/annotations.js
index b0c89d5e374..de2b0c69a88 100644
--- a/app/assets/javascripts/monitoring/components/charts/annotations.js
+++ b/app/assets/javascripts/monitoring/components/charts/annotations.js
@@ -87,11 +87,17 @@ export const generateAnnotationsSeries = ({ deployments = [], annotations = [] }
return {
name: 'deployments',
value: [deployment.createdAt, annotationsYAxisCoords.pos],
+ // style options
symbol: deployment.icon,
symbolSize: symbolSizes.default,
itemStyle: {
color: deployment.color,
},
+ // metadata that are accessible in `formatTooltipText` method
+ tooltipData: {
+ sha: deployment.sha.substring(0, 8),
+ commitUrl: deployment.commitUrl,
+ },
};
});
@@ -100,8 +106,12 @@ export const generateAnnotationsSeries = ({ deployments = [], annotations = [] }
return {
name: 'annotations',
value: [annotation.from, annotationsYAxisCoords.pos],
+ // style options
symbol: 'none',
- description: annotation.description,
+ // metadata that are accessible in `formatTooltipText` method
+ tooltipData: {
+ description: annotation.description,
+ },
};
});
diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue
index f4cd6bbbb34..24aa8480ce4 100644
--- a/app/assets/javascripts/monitoring/components/charts/time_series.vue
+++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue
@@ -262,19 +262,17 @@ export default {
params.seriesData.forEach(dataPoint => {
if (dataPoint.value) {
- const [xVal, yVal] = dataPoint.value;
+ const [, yVal] = dataPoint.value;
this.tooltip.type = dataPoint.name;
if (this.isTooltipOfType(this.tooltip.type, this.$options.tooltipTypes.deployments)) {
- const [deploy] = this.recentDeployments.filter(
- deployment => deployment.createdAt === xVal,
- );
- this.tooltip.sha = deploy.sha.substring(0, 8);
- this.tooltip.commitUrl = deploy.commitUrl;
+ const { data = {} } = dataPoint;
+ this.tooltip.sha = data?.tooltipData?.sha;
+ this.tooltip.commitUrl = data?.tooltipData?.commitUrl;
} else if (
this.isTooltipOfType(this.tooltip.type, this.$options.tooltipTypes.annotations)
) {
const { data } = dataPoint;
- this.tooltip.content.push(data?.description);
+ this.tooltip.content.push(data?.tooltipData?.description);
} else {
const { seriesName, color, dataIndex } = dataPoint;
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index ddda2de38cb..1131248dd3f 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -210,3 +210,15 @@
}
}
}
+
+.health-status {
+ .dropdown-body {
+ .health-divider {
+ border-top-color: $gray-200;
+ }
+
+ .dropdown-item:not(.health-dropdown-item) {
+ padding: 0;
+ }
+ }
+}
diff --git a/app/presenters/projects/prometheus/alert_presenter.rb b/app/presenters/projects/prometheus/alert_presenter.rb
index 02e22f8f46a..c03925c0871 100644
--- a/app/presenters/projects/prometheus/alert_presenter.rb
+++ b/app/presenters/projects/prometheus/alert_presenter.rb
@@ -3,7 +3,7 @@
module Projects
module Prometheus
class AlertPresenter < Gitlab::View::Presenter::Delegated
- RESERVED_ANNOTATIONS = %w(gitlab_incident_markdown title).freeze
+ RESERVED_ANNOTATIONS = %w(gitlab_incident_markdown gitlab_y_label title).freeze
GENERIC_ALERT_SUMMARY_ANNOTATIONS = %w(monitoring_tool service hosts).freeze
MARKDOWN_LINE_BREAK = " \n".freeze
INCIDENT_LABEL_NAME = IncidentManagement::CreateIssueService::INCIDENT_LABEL[:title].freeze
diff --git a/app/services/metrics/dashboard/custom_metric_embed_service.rb b/app/services/metrics/dashboard/custom_metric_embed_service.rb
index 456074ae6ad..22b592c7aa5 100644
--- a/app/services/metrics/dashboard/custom_metric_embed_service.rb
+++ b/app/services/metrics/dashboard/custom_metric_embed_service.rb
@@ -57,7 +57,7 @@ module Metrics
# @return [Hash]
override :raw_dashboard
def raw_dashboard
- panels_not_found!(identifiers) if panels.empty?
+ panels_not_found!(identifiers) if metrics.empty?
{ 'panel_groups' => [{ 'panels' => panels }] }
end
@@ -66,11 +66,20 @@ module Metrics
# Generated dashboard panels for each metric which
# matches the provided input.
+ #
+ # As the panel is generated
+ # on the fly, we're using default values for info
+ # not represented in the DB.
+ #
# @return [Array<Hash>]
def panels
- strong_memoize(:panels) do
- metrics.map { |metric| panel_for_metric(metric) }
- end
+ [{
+ type: DEFAULT_PANEL_TYPE,
+ weight: DEFAULT_PANEL_WEIGHT,
+ title: title,
+ y_label: y_label,
+ metrics: metrics.map(&:to_metric_hash)
+ }]
end
# Metrics which match the provided inputs.
@@ -78,12 +87,14 @@ module Metrics
# displayed in a single panel/chart.
# @return [ActiveRecord::AssociationRelation<PromtheusMetric>]
def metrics
- PrometheusMetricsFinder.new(
- project: project,
- group: group_key,
- title: title,
- y_label: y_label
- ).execute
+ strong_memoize(:metrics) do
+ PrometheusMetricsFinder.new(
+ project: project,
+ group: group_key,
+ title: title,
+ y_label: y_label
+ ).execute
+ end
end
# Returns a symbol representing the group that
@@ -101,22 +112,6 @@ module Metrics
.to_s
end
end
-
- # Returns a representation of a PromtheusMetric
- # as a dashboard panel. As the panel is generated
- # on the fly, we're using default values for info
- # not represented in the DB.
- #
- # @return [Hash]
- def panel_for_metric(metric)
- {
- type: DEFAULT_PANEL_TYPE,
- weight: DEFAULT_PANEL_WEIGHT,
- title: metric.title,
- y_label: metric.y_label,
- metrics: [metric.to_metric_hash]
- }
- end
end
end
end
diff --git a/changelogs/unreleased/sy-fix-multi-metric-embed.yml b/changelogs/unreleased/sy-fix-multi-metric-embed.yml
new file mode 100644
index 00000000000..26fbac61c69
--- /dev/null
+++ b/changelogs/unreleased/sy-fix-multi-metric-embed.yml
@@ -0,0 +1,5 @@
+---
+title: Show multimetric embeds on a single chart
+merge_request: 28841
+author:
+type: fixed
diff --git a/db/migrate/20200318183553_create_pypi_package_metadata.rb b/db/migrate/20200318183553_create_pypi_package_metadata.rb
new file mode 100644
index 00000000000..3f0204d51ac
--- /dev/null
+++ b/db/migrate/20200318183553_create_pypi_package_metadata.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreatePypiPackageMetadata < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ create_table :packages_pypi_metadata, id: false do |t|
+ t.references :package, primary_key: true, index: false, default: nil, foreign_key: { to_table: :packages_packages, on_delete: :cascade }, type: :bigint
+ t.string "required_python", null: false, limit: 50
+ end
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 3faa5499f6c..d45ad4f739c 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -4493,6 +4493,11 @@ CREATE SEQUENCE public.packages_packages_id_seq
ALTER SEQUENCE public.packages_packages_id_seq OWNED BY public.packages_packages.id;
+CREATE TABLE public.packages_pypi_metadata (
+ package_id bigint NOT NULL,
+ required_python character varying(50) NOT NULL
+);
+
CREATE TABLE public.packages_tags (
id bigint NOT NULL,
package_id integer NOT NULL,
@@ -8146,6 +8151,9 @@ ALTER TABLE ONLY public.packages_package_files
ALTER TABLE ONLY public.packages_packages
ADD CONSTRAINT packages_packages_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.packages_pypi_metadata
+ ADD CONSTRAINT packages_pypi_metadata_pkey PRIMARY KEY (package_id);
+
ALTER TABLE ONLY public.packages_tags
ADD CONSTRAINT packages_tags_pkey PRIMARY KEY (id);
@@ -11596,6 +11604,9 @@ ALTER TABLE ONLY public.board_labels
ALTER TABLE ONLY public.scim_identities
ADD CONSTRAINT fk_rails_9421a0bffb FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.packages_pypi_metadata
+ ADD CONSTRAINT fk_rails_9698717cdd FOREIGN KEY (package_id) REFERENCES public.packages_packages(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.packages_dependency_links
ADD CONSTRAINT fk_rails_96ef1c00d3 FOREIGN KEY (package_id) REFERENCES public.packages_packages(id) ON DELETE CASCADE;
@@ -13032,6 +13043,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200318164448
20200318165448
20200318175008
+20200318183553
20200319071702
20200319123041
20200319124127
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 583e27f3301..402415b985c 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -468,6 +468,11 @@ input CreateEpicInput {
clientMutationId: String
"""
+ Indicates if the epic is confidential. Will be ignored if `confidential_epics` feature flag is disabled
+ """
+ confidential: Boolean
+
+ """
The description of the epic
"""
description: String
@@ -2015,6 +2020,11 @@ type Epic implements Noteable {
closedAt: Time
"""
+ Indicates if the epic is confidential
+ """
+ confidential: Boolean
+
+ """
Timestamp of the epic's creation
"""
createdAt: Time
@@ -8904,6 +8914,11 @@ input UpdateEpicInput {
clientMutationId: String
"""
+ Indicates if the epic is confidential. Will be ignored if `confidential_epics` feature flag is disabled
+ """
+ confidential: Boolean
+
+ """
The description of the epic
"""
description: String
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 79d4088e566..c214d7c3299 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -1404,6 +1404,16 @@
"defaultValue": null
},
{
+ "name": "confidential",
+ "description": "Indicates if the epic is confidential. Will be ignored if `confidential_epics` feature flag is disabled",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
"name": "startDateFixed",
"description": "The start date of the epic",
"type": {
@@ -5933,6 +5943,20 @@
"deprecationReason": null
},
{
+ "name": "confidential",
+ "description": "Indicates if the epic is confidential",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "createdAt",
"description": "Timestamp of the epic's creation",
"args": [
@@ -27003,6 +27027,16 @@
"defaultValue": null
},
{
+ "name": "confidential",
+ "description": "Indicates if the epic is confidential. Will be ignored if `confidential_epics` feature flag is disabled",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
"name": "startDateFixed",
"description": "The start date of the epic",
"type": {
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 43e8677f384..fe5925b95d9 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -335,6 +335,7 @@ Represents an epic.
| --- | ---- | ---------- |
| `author` | User! | Author of the epic |
| `closedAt` | Time | Timestamp of the epic's closure |
+| `confidential` | Boolean | Indicates if the epic is confidential |
| `createdAt` | Time | Timestamp of the epic's creation |
| `descendantCounts` | EpicDescendantCount | Number of open and closed descendant epics and issues |
| `descendantWeightSum` | EpicDescendantWeights | Total weight of open and closed issues in the epic and its descendants |
diff --git a/doc/user/incident_management/index.md b/doc/user/incident_management/index.md
index 829fee47826..2b95128bffd 100644
--- a/doc/user/incident_management/index.md
+++ b/doc/user/incident_management/index.md
@@ -138,6 +138,4 @@ Incident Management features can be easily enabled & disabled via the Project se
#### Auto-creation
-GitLab Issues can automatically be created as a result of an Alert notification. An Issue created this way will contain error information to help you further debug the error.
-
-For [GitLab-managed alerting rules](../project/integrations/prometheus.md#setting-up-alerts-for-prometheus-metrics-ultimate), the issue will include an embedded chart for the query corresponding to the alert. The chart will show an hour of data surrounding the starting point of the incident, 30 minutes before and after.
+You can automatically create GitLab issues from an Alert notification. Issues created this way contain error information to help you debug the error. Appropriately configured alerts include an [embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues) for the query corresponding to the alert.
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 273ab9095c0..4b07ecd2743 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -802,6 +802,22 @@ It is also possible to embed either the default dashboard metrics or individual
![Embedded Metrics in issue templates](img/embed_metrics_issue_template.png)
+### Embedding metrics based on alerts in incident issues
+
+For [GitLab-managed alerting rules](#setting-up-alerts-for-prometheus-metrics-ultimate), the issue will include an embedded chart for the query corresponding to the alert. The chart displays an hour of data surrounding the starting point of the incident, 30 minutes before and after.
+
+For [manually configured Prometheus instances](#manual-configuration-of-prometheus), a chart corresponding to the query can be included if these requirements are met:
+
+- The alert corresponds to an environment managed through GitLab.
+- The alert corresponds to a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries).
+- The alert contains the required attributes listed in the chart below.
+
+| Attributes | Required | Description |
+| ---------- | -------- | ----------- |
+| `annotations/gitlab_environment_name` | Yes | Name of the GitLab-managed environment corresponding to the alert |
+| One of `annotations/title`, `annotations/summary`, `labels/alertname` | Yes | Will be used as the chart title |
+| `annotations/gitlab_y_label` | No | Will be used as the chart's y-axis label |
+
### Embedding Cluster Health Charts **(ULTIMATE)**
> [Introduced](<https://gitlab.com/gitlab-org/gitlab/issues/40997>) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
diff --git a/doc/user/project/issues/img/issue_health_status_dropdown_v12_10.png b/doc/user/project/issues/img/issue_health_status_dropdown_v12_10.png
new file mode 100644
index 00000000000..c0f0a0dfe16
--- /dev/null
+++ b/doc/user/project/issues/img/issue_health_status_dropdown_v12_10.png
Binary files differ
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index c020d6e5802..55e9967a370 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -177,7 +177,7 @@ that's progressing as planned or needs attention to keep on schedule:
- **Needs attention** (amber)
- **At risk** (red)
-!["On track" health status on an issue](img/issue_health_status_v12_10.png)
+!["On track" health status on an issue](img/issue_health_status_dropdown_v12_10.png)
You can then see issue statuses on the
[Epic tree](../../group/epics/index.md#issue-health-status-in-epic-tree-ultimate).
diff --git a/lib/gitlab/alerting/alert.rb b/lib/gitlab/alerting/alert.rb
index 531307b93d4..f6f52e392c6 100644
--- a/lib/gitlab/alerting/alert.rb
+++ b/lib/gitlab/alerting/alert.rb
@@ -69,6 +69,12 @@ module Gitlab
end
end
+ def y_label
+ strong_memoize(:y_label) do
+ parse_y_label_from_payload || title
+ end
+ end
+
def alert_markdown
strong_memoize(:alert_markdown) do
parse_alert_markdown_from_payload
@@ -162,6 +168,10 @@ module Gitlab
def parse_alert_markdown_from_payload
payload&.dig('annotations', 'gitlab_incident_markdown')
end
+
+ def parse_y_label_from_payload
+ payload&.dig('annotations', 'gitlab_y_label')
+ end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 92df6cf3135..78d1ba110b9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3850,9 +3850,6 @@ msgstr ""
msgid "Choose which shards you wish to synchronize to this secondary node"
msgstr ""
-msgid "Choose which status most accurately reflects the current state of this issue:"
-msgstr ""
-
msgid "Choose your framework"
msgstr ""
@@ -16950,6 +16947,9 @@ msgstr ""
msgid "Rename/Move"
msgstr ""
+msgid "Reopen"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17145,6 +17145,9 @@ msgstr ""
msgid "Requirement"
msgstr ""
+msgid "Requirement title cannot have more than %{limit} characters."
+msgstr ""
+
msgid "Requirements"
msgstr ""
@@ -18040,6 +18043,9 @@ msgstr ""
msgid "Select groups to replicate"
msgstr ""
+msgid "Select health status"
+msgstr ""
+
msgid "Select labels"
msgstr ""
@@ -18576,16 +18582,22 @@ msgstr ""
msgid "Side-by-side"
msgstr ""
+msgid "Sidebar|Assign health status"
+msgstr ""
+
msgid "Sidebar|Change weight"
msgstr ""
-msgid "Sidebar|None"
+msgid "Sidebar|Health status"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
+msgid "Sidebar|No status"
+msgstr ""
+
+msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Status"
+msgid "Sidebar|Only numeral characters allowed"
msgstr ""
msgid "Sidebar|Weight"
@@ -18813,6 +18825,9 @@ msgstr ""
msgid "Something went wrong while applying the suggestion. Please try again."
msgstr ""
+msgid "Something went wrong while archiving a requirement."
+msgstr ""
+
msgid "Something went wrong while closing the %{issuable}. Please try again later"
msgstr ""
@@ -18885,6 +18900,9 @@ msgstr ""
msgid "Something went wrong while performing the action."
msgstr ""
+msgid "Something went wrong while reopening a requirement."
+msgstr ""
+
msgid "Something went wrong while reopening the %{issuable}. Please try again later"
msgstr ""
@@ -24957,9 +24975,6 @@ msgstr ""
msgid "remove due date"
msgstr ""
-msgid "remove status"
-msgstr ""
-
msgid "remove weight"
msgstr ""
diff --git a/spec/frontend/monitoring/components/charts/time_series_spec.js b/spec/frontend/monitoring/components/charts/time_series_spec.js
index c9b670fd7a8..3aad4c87237 100644
--- a/spec/frontend/monitoring/components/charts/time_series_spec.js
+++ b/spec/frontend/monitoring/components/charts/time_series_spec.js
@@ -155,43 +155,56 @@ describe('Time series component', () => {
describe('methods', () => {
describe('formatTooltipText', () => {
- let mockDate;
- let mockCommitUrl;
- let generateSeriesData;
-
- beforeEach(() => {
- mockDate = deploymentData[0].created_at;
- mockCommitUrl = deploymentData[0].commitUrl;
- generateSeriesData = type => ({
- seriesData: [
- {
- seriesName: timeSeriesChart.vm.chartData[0].name,
- componentSubType: type,
- value: [mockDate, 5.55555],
- dataIndex: 0,
- ...(type === 'scatter' && { name: 'deployments' }),
- },
- ],
- value: mockDate,
- });
+ const mockCommitUrl = deploymentData[0].commitUrl;
+ const mockDate = deploymentData[0].created_at;
+ const mockSha = 'f5bcd1d9';
+ const mockLineSeriesData = () => ({
+ seriesData: [
+ {
+ seriesName: timeSeriesChart.vm.chartData[0].name,
+ componentSubType: 'line',
+ value: [mockDate, 5.55555],
+ dataIndex: 0,
+ },
+ ],
+ value: mockDate,
});
+ const annotationsMetadata = {
+ tooltipData: {
+ sha: mockSha,
+ commitUrl: mockCommitUrl,
+ },
+ };
+
+ const mockAnnotationsSeriesData = {
+ seriesData: [
+ {
+ componentSubType: 'scatter',
+ seriesName: 'series01',
+ dataIndex: 0,
+ value: [mockDate, 5.55555],
+ type: 'scatter',
+ name: 'deployments',
+ },
+ ],
+ value: mockDate,
+ };
+
it('does not throw error if data point is outside the zoom range', () => {
- const seriesDataWithoutValue = generateSeriesData('line');
- expect(
- timeSeriesChart.vm.formatTooltipText({
- ...seriesDataWithoutValue,
- seriesData: seriesDataWithoutValue.seriesData.map(data => ({
- ...data,
- value: undefined,
- })),
- }),
- ).toBeUndefined();
+ const seriesDataWithoutValue = {
+ ...mockLineSeriesData(),
+ seriesData: mockLineSeriesData().seriesData.map(data => ({
+ ...data,
+ value: undefined,
+ })),
+ };
+ expect(timeSeriesChart.vm.formatTooltipText(seriesDataWithoutValue)).toBeUndefined();
});
describe('when series is of line type', () => {
beforeEach(done => {
- timeSeriesChart.vm.formatTooltipText(generateSeriesData('line'));
+ timeSeriesChart.vm.formatTooltipText(mockLineSeriesData());
timeSeriesChart.vm.$nextTick(done);
});
@@ -223,7 +236,14 @@ describe('Time series component', () => {
describe('when series is of scatter type, for deployments', () => {
beforeEach(() => {
- timeSeriesChart.vm.formatTooltipText(generateSeriesData('scatter'));
+ timeSeriesChart.vm.formatTooltipText({
+ ...mockAnnotationsSeriesData,
+ seriesData: mockAnnotationsSeriesData.seriesData.map(data => ({
+ ...data,
+ data: annotationsMetadata,
+ })),
+ });
+ return timeSeriesChart.vm.$nextTick;
});
it('set tooltip type to deployments', () => {
@@ -242,6 +262,25 @@ describe('Time series component', () => {
expect(timeSeriesChart.vm.tooltip.commitUrl).toBe(mockCommitUrl);
});
});
+
+ describe('when series is of scatter type and deployments data is missing', () => {
+ beforeEach(() => {
+ timeSeriesChart.vm.formatTooltipText(mockAnnotationsSeriesData);
+ return timeSeriesChart.vm.$nextTick;
+ });
+
+ it('formats tooltip title', () => {
+ expect(timeSeriesChart.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM');
+ });
+
+ it('formats tooltip sha', () => {
+ expect(timeSeriesChart.vm.tooltip.sha).toBeUndefined();
+ });
+
+ it('formats tooltip commit url', () => {
+ expect(timeSeriesChart.vm.tooltip.commitUrl).toBeUndefined();
+ });
+ });
});
describe('setSvg', () => {
diff --git a/spec/lib/gitlab/alerting/alert_spec.rb b/spec/lib/gitlab/alerting/alert_spec.rb
index aaded28954e..8b67cf949ce 100644
--- a/spec/lib/gitlab/alerting/alert_spec.rb
+++ b/spec/lib/gitlab/alerting/alert_spec.rb
@@ -192,6 +192,16 @@ describe Gitlab::Alerting::Alert do
end
end
+ describe '#y_label' do
+ subject { alert.y_label }
+
+ it_behaves_like 'parse payload', 'annotations/gitlab_y_label'
+
+ context 'when y_label is not included in the payload' do
+ it_behaves_like 'parse payload', 'annotations/title'
+ end
+ end
+
describe '#alert_markdown' do
subject { alert.alert_markdown }
diff --git a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
index 2f03d18cd1f..1a9ddc87ab0 100644
--- a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
@@ -121,11 +121,18 @@ describe Metrics::Dashboard::CustomMetricEmbedService do
it_behaves_like 'valid embedded dashboard service response'
- it 'includes both metrics' do
+ it 'includes both metrics in a single panel' do
result = service_call
- included_queries = all_queries(result[:dashboard])
- expect(included_queries).to include('avg(metric_2)', 'avg(metric)')
+ panel_groups = result[:dashboard][:panel_groups]
+ panels = panel_groups[0][:panels]
+ metrics = panels[0][:metrics]
+ queries = metrics.map { |metric| metric[:query_range] }
+
+ expect(panel_groups.length).to eq(1)
+ expect(panels.length).to eq(1)
+ expect(metrics.length).to eq(2)
+ expect(queries).to include('avg(metric_2)', 'avg(metric)')
end
end
end
@@ -136,16 +143,4 @@ describe Metrics::Dashboard::CustomMetricEmbedService do
it_behaves_like 'misconfigured dashboard service response', :not_found
end
end
-
- private
-
- def all_queries(dashboard)
- dashboard[:panel_groups].flat_map do |group|
- group[:panels].flat_map do |panel|
- panel[:metrics].map do |metric|
- metric[:query_range]
- end
- end
- end
- end
end