Commit 045c0f95 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 669c24d9
# Make sure to update all the similar conditions in other CI config files if you modify these conditions
.if-canonical-gitlab-schedule: &if-canonical-gitlab-schedule
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_PIPELINE_SOURCE == "schedule"'
.notify: .notify:
image: ruby:2.6-alpine image: ruby:2.6-alpine
stage: notification stage: notification
...@@ -11,13 +15,13 @@ ...@@ -11,13 +15,13 @@
variables: variables:
COMMIT_NOTES_URL: "https://${CI_SERVER_HOST}/${CI_PROJECT_PATH}/commit/${CI_COMMIT_SHA}#notes-list" COMMIT_NOTES_URL: "https://${CI_SERVER_HOST}/${CI_PROJECT_PATH}/commit/${CI_COMMIT_SHA}#notes-list"
schedule:package-and-qa:notify-failure: package-and-qa:notify-failure:
extends: extends: .notify
- .only:variables_refs-canonical-dot-com-schedules rules:
- .notify - <<: *if-canonical-gitlab-schedule
when: manual # TODO: remove notify job if not necessary
script: script:
- 'export NOTIFICATION_MESSAGE=":skull_and_crossbones: Scheduled QA against master failed! :skull_and_crossbones: See ${CI_PIPELINE_URL}. For downstream pipelines, see ${COMMIT_NOTES_URL}"' - 'export NOTIFICATION_MESSAGE=":skull_and_crossbones: Scheduled QA against master failed! :skull_and_crossbones: See ${CI_PIPELINE_URL}. For downstream pipelines, see ${COMMIT_NOTES_URL}"'
- 'notify_on_job_failure schedule:package-and-qa qa-master "${NOTIFICATION_MESSAGE}" ci_failing' - 'notify_on_job_failure package-and-qa qa-master "${NOTIFICATION_MESSAGE}" ci_failing'
needs: ["schedule:package-and-qa"] needs: ["package-and-qa"]
allow_failure: true allow_failure: true
when: manual # TODO: remove notify job if not necessary
# Make sure to update all the similar conditions in other CI config files if you modify these conditions # Make sure to update all the similar conditions in other CI config files if you modify these conditions
.if-canonical-gitlab-and-merge-request: &if-canonical-gitlab-and-merge-request .if-canonical-gitlab-schedule: &if-canonical-gitlab-schedule
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_PIPELINE_SOURCE == "schedule"'
# Make sure to update all the similar conditions in other CI config files if you modify these conditions
.if-canonical-gitlab-merge-request: &if-canonical-gitlab-merge-request
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_MERGE_REQUEST_IID' if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_MERGE_REQUEST_IID'
# Make sure to update all the similar patterns in other CI config files if you modify these patterns # Make sure to update all the similar patterns in other CI config files if you modify these patterns
...@@ -68,19 +72,13 @@ qa:selectors-foss: ...@@ -68,19 +72,13 @@ qa:selectors-foss:
package-and-qa: package-and-qa:
extends: .package-and-qa-base extends: .package-and-qa-base
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *qa-patterns changes: *qa-patterns
when: on_success when: on_success
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-patterns changes: *code-patterns
when: manual when: manual
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"] - <<: *if-canonical-gitlab-schedule
allow_failure: true when: on_success
schedule:package-and-qa:
extends:
- .package-and-qa-base
- .default-only
- .only:variables_refs-canonical-dot-com-schedules
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"] needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
allow_failure: true allow_failure: true
# Make sure to update all the similar conditions in other CI config files if you modify these conditions # Make sure to update all the similar conditions in other CI config files if you modify these conditions
.if-canonical-gitlab: &if-canonical-gitlab .if-canonical-gitlab-schedule: &if-canonical-gitlab-schedule
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/' if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_PIPELINE_SOURCE == "schedule"'
# Make sure to update all the similar conditions in other CI config files if you modify these conditions # Make sure to update all the similar conditions in other CI config files if you modify these conditions
.if-canonical-gitlab-and-merge-request: &if-canonical-gitlab-and-merge-request .if-canonical-gitlab-merge-request: &if-canonical-gitlab-merge-request
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_MERGE_REQUEST_IID' if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_MERGE_REQUEST_IID'
# Make sure to update all the similar patterns in other CI config files if you modify these patterns # Make sure to update all the similar patterns in other CI config files if you modify these patterns
...@@ -44,9 +44,11 @@ build-qa-image: ...@@ -44,9 +44,11 @@ build-qa-image:
extends: .review-docker extends: .review-docker
stage: prepare stage: prepare
rules: rules:
- <<: *if-canonical-gitlab - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: on_success when: on_success
- <<: *if-canonical-gitlab-schedule
when: on_success
script: script:
- '[[ ! -d "ee/" ]] || export GITLAB_EDITION="ee"' - '[[ ! -d "ee/" ]] || export GITLAB_EDITION="ee"'
- export QA_MASTER_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab/gitlab-${GITLAB_EDITION}-qa:master" - export QA_MASTER_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab/gitlab-${GITLAB_EDITION}-qa:master"
...@@ -157,7 +159,7 @@ schedule:review-build-cng: ...@@ -157,7 +159,7 @@ schedule:review-build-cng:
review-deploy: review-deploy:
extends: .review-deploy-base extends: .review-deploy-base
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: on_success when: on_success
...@@ -184,7 +186,7 @@ review-stop-failed-deployment: ...@@ -184,7 +186,7 @@ review-stop-failed-deployment:
extends: .base-review-stop extends: .base-review-stop
stage: prepare stage: prepare
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: on_success when: on_success
script: script:
...@@ -194,7 +196,7 @@ review-stop: ...@@ -194,7 +196,7 @@ review-stop:
extends: .base-review-stop extends: .base-review-stop
stage: review stage: review
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: manual when: manual
allow_failure: true allow_failure: true
...@@ -235,7 +237,7 @@ review-stop: ...@@ -235,7 +237,7 @@ review-stop:
review-qa-smoke: review-qa-smoke:
extends: .review-qa-base extends: .review-qa-base
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: on_success when: on_success
script: script:
...@@ -244,7 +246,7 @@ review-qa-smoke: ...@@ -244,7 +246,7 @@ review-qa-smoke:
review-qa-all: review-qa-all:
extends: .review-qa-base extends: .review-qa-base
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: manual when: manual
parallel: 5 parallel: 5
...@@ -276,7 +278,7 @@ review-qa-all: ...@@ -276,7 +278,7 @@ review-qa-all:
review-performance: review-performance:
extends: .review-performance-base extends: .review-performance-base
rules: rules:
- <<: *if-canonical-gitlab-and-merge-request - <<: *if-canonical-gitlab-merge-request
changes: *code-qa-patterns changes: *code-qa-patterns
when: on_success when: on_success
needs: ["review-deploy"] needs: ["review-deploy"]
......
...@@ -24,7 +24,7 @@ const EMPTY_STAGE_TEXTS = { ...@@ -24,7 +24,7 @@ const EMPTY_STAGE_TEXTS = {
'The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.', 'The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.',
), ),
production: __( production: __(
'The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.', 'The total stage shows the time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.',
), ),
}; };
......
...@@ -55,9 +55,18 @@ jQuery.ajaxSetup({ ...@@ -55,9 +55,18 @@ jQuery.ajaxSetup({
}, },
}); });
function disableJQueryAnimations() {
$.fx.off = true;
}
// Disable jQuery animations
if (gon && gon.disable_animations) {
disableJQueryAnimations();
}
// inject test utilities if necessary // inject test utilities if necessary
if (process.env.NODE_ENV !== 'production' && gon && gon.test_env) { if (process.env.NODE_ENV !== 'production' && gon && gon.test_env) {
$.fx.off = true; disableJQueryAnimations();
import(/* webpackMode: "eager" */ './test_utils/'); import(/* webpackMode: "eager" */ './test_utils/');
} }
......
...@@ -46,6 +46,8 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -46,6 +46,8 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:vue_issuable_sidebar, project.group) push_frontend_feature_flag(:vue_issuable_sidebar, project.group)
end end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
respond_to :html respond_to :html
alias_method :designs, :show alias_method :designs, :show
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
= stylesheet_link_tag "application", media: "all" = stylesheet_link_tag "application", media: "all"
= stylesheet_link_tag "print", media: "print" = stylesheet_link_tag "print", media: "print"
= stylesheet_link_tag "test", media: "all" if Rails.env.test? = stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
= stylesheet_link_tag 'performance_bar' if performance_bar_enabled? = stylesheet_link_tag 'performance_bar' if performance_bar_enabled?
= stylesheet_link_tag "highlight/themes/#{user_color_scheme}", media: "all" = stylesheet_link_tag "highlight/themes/#{user_color_scheme}", media: "all"
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The collection of events added to the data gathered for that stage."), "aria-hidden" => "true" } %i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The collection of events added to the data gathered for that stage."), "aria-hidden" => "true" }
%li.total-time-header.pr-5.text-right %li.total-time-header.pr-5.text-right
%span.stage-name.font-weight-bold %span.stage-name.font-weight-bold
{{ __('Total Time') }} {{ __('Time') }}
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The time taken by each data entry gathered by that stage."), "aria-hidden" => "true" } %i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The time taken by each data entry gathered by that stage."), "aria-hidden" => "true" }
.stage-panel-body .stage-panel-body
%nav.stage-nav %nav.stage-nav
......
---
title: Fix for 500 when error stack trace is empty
merge_request: 119205
author:
type: fixed
---
title: Reduce Gitaly calls needed for issue discussions
merge_request:
author:
type: performance
---
title: Add a config for disabling CSS and jQuery animations
merge_request: 22217
author:
type: added
...@@ -166,7 +166,7 @@ module Gitlab ...@@ -166,7 +166,7 @@ module Gitlab
config.assets.precompile << "page_bundles/xterm.css" config.assets.precompile << "page_bundles/xterm.css"
config.assets.precompile << "performance_bar.css" config.assets.precompile << "performance_bar.css"
config.assets.precompile << "lib/ace.js" config.assets.precompile << "lib/ace.js"
config.assets.precompile << "test.css" config.assets.precompile << "disable_animations.css"
config.assets.precompile << "snippets.css" config.assets.precompile << "snippets.css"
config.assets.precompile << "locale/**/app.js" config.assets.precompile << "locale/**/app.js"
config.assets.precompile << "emoji_sprites.css" config.assets.precompile << "emoji_sprites.css"
......
...@@ -150,6 +150,9 @@ production: &base ...@@ -150,6 +150,9 @@ production: &base
## Impersonation settings ## Impersonation settings
impersonation_enabled: true impersonation_enabled: true
## Disable jQuery and CSS animations
# disable_animations: true
## Reply by email ## Reply by email
# Allow users to comment on issues and merge requests by replying to notification emails. # Allow users to comment on issues and merge requests by replying to notification emails.
# For documentation on how to set this up, see http://doc.gitlab.com/ce/administration/reply_by_email.html # For documentation on how to set this up, see http://doc.gitlab.com/ce/administration/reply_by_email.html
...@@ -807,7 +810,7 @@ production: &base ...@@ -807,7 +810,7 @@ production: &base
# CAUTION! # CAUTION!
# This allows users to login with the specified providers without two factor. Define the allowed providers # This allows users to login with the specified providers without two factor. Define the allowed providers
# using an array, e.g. ["twitter", 'google_oauth2'], or as true/false to allow all providers or none. # using an array, e.g. ["twitter", 'google_oauth2'], or as true/false to allow all providers or none.
# This option should only be configured for providers which already have two factor. # This option should only be configured for providers which already have two factor.
# This configration dose not apply to SAML. # This configration dose not apply to SAML.
# (default: false) # (default: false)
allow_bypass_two_factor: ["twitter", 'google_oauth2'] allow_bypass_two_factor: ["twitter", 'google_oauth2']
......
...@@ -77,8 +77,8 @@ end ...@@ -77,8 +77,8 @@ end
Some start/end event pairs are not "compatible" with each other. For example: Some start/end event pairs are not "compatible" with each other. For example:
- "Issue created" to "Merge Request created": The event classes are defined on different domain models, the `object_type` method is different. - "Issue created" to "Merge Request created": The event classes are defined on different domain models, the `object_type` method is different.
- "Issue closed" to "Issue created": Issue must be created first before it can be closed. - "Issue closed" to "Issue created": Issue must be created first before it can be closed.
- "Issue closed" to "Issue closed": Duration is always 0. - "Issue closed" to "Issue closed": Duration is always 0.
The `StageEvents` module describes the allowed `start_event` and `end_event` pairings (`PAIRING_RULES` constant). If a new event is added, it needs to be registered in this module. The `StageEvents` module describes the allowed `start_event` and `end_event` pairings (`PAIRING_RULES` constant). If a new event is added, it needs to be registered in this module.
......
...@@ -156,7 +156,7 @@ This is similar to the `.only:variables-canonical-dot-com` + `.except:refs-maste ...@@ -156,7 +156,7 @@ This is similar to the `.only:variables-canonical-dot-com` + `.except:refs-maste
CI definitions: CI definitions:
```yaml ```yaml
.if-canonical-gitlab-and-merge-request: &if-canonical-gitlab-and-merge-request .if-canonical-gitlab-merge-request: &if-canonical-gitlab-merge-request
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_MERGE_REQUEST_IID' if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_MERGE_REQUEST_IID'
``` ```
...@@ -210,9 +210,7 @@ graph RL; ...@@ -210,9 +210,7 @@ graph RL;
M[coverage]; M[coverage];
N[pages]; N[pages];
O[static-analysis]; O[static-analysis];
P["schedule:package-and-qa<br/>(master schedule only)"];
Q[package-and-qa]; Q[package-and-qa];
R[package-and-qa-manual];
S["RSpec<br/>(e.g. rspec unit pg9)"] S["RSpec<br/>(e.g. rspec unit pg9)"]
T[retrieve-tests-metadata]; T[retrieve-tests-metadata];
...@@ -259,10 +257,6 @@ subgraph "`review` stage" ...@@ -259,10 +257,6 @@ subgraph "`review` stage"
subgraph "`qa` stage" subgraph "`qa` stage"
Q --> |needs| C; Q --> |needs| C;
Q --> |needs| F; Q --> |needs| F;
R --> |needs| C;
R --> |needs| F;
P --> |needs| C;
P --> |needs| F;
review-qa-smoke -.-> |needs and depends on| G; review-qa-smoke -.-> |needs and depends on| G;
review-qa-all -.-> |needs and depends on| G; review-qa-all -.-> |needs and depends on| G;
review-performance -.-> |needs and depends on| G; review-performance -.-> |needs and depends on| G;
...@@ -271,8 +265,7 @@ subgraph "`qa` stage" ...@@ -271,8 +265,7 @@ subgraph "`qa` stage"
end end
subgraph "`notification` stage" subgraph "`notification` stage"
NOTIFICATION1["schedule:package-and-qa:notify-success<br>(on_success)"] -.-> |needs| P; NOTIFICATION2["package-and-qa:notify-failure<br>(manual)"] -.-> |needs| Q;
NOTIFICATION2["schedule:package-and-qa:notify-failure<br>(on_failure)"] -.-> |needs| P;
end end
subgraph "`post-test` stage" subgraph "`post-test` stage"
......
...@@ -27,11 +27,11 @@ You can find these nightly pipelines at `https://gitlab.com/gitlab-org/quality/s ...@@ -27,11 +27,11 @@ You can find these nightly pipelines at `https://gitlab.com/gitlab-org/quality/s
### Testing code in merge requests ### Testing code in merge requests
#### Using the `package-and-qa-manual` job #### Using the `package-and-qa` job
It is possible to run end-to-end tests for a merge request, eventually being run in It is possible to run end-to-end tests for a merge request, eventually being run in
a pipeline in the [`gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/) project, a pipeline in the [`gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/) project,
by triggering the `package-and-qa-manual` manual action in the `test` stage (not by triggering the `package-and-qa` manual action in the `test` stage (not
available for forks). available for forks).
**This runs end-to-end tests against a custom Omnibus package built from your **This runs end-to-end tests against a custom Omnibus package built from your
...@@ -53,7 +53,7 @@ graph LR ...@@ -53,7 +53,7 @@ graph LR
B2[`Trigger-qa` stage<br>`Trigger:qa-test` job] -.->|2. Triggers a gitlab-qa pipeline and wait for it to be done| A3 B2[`Trigger-qa` stage<br>`Trigger:qa-test` job] -.->|2. Triggers a gitlab-qa pipeline and wait for it to be done| A3
subgraph "gitlab-foss/gitlab pipeline" subgraph "gitlab-foss/gitlab pipeline"
A1[`test` stage<br>`package-and-qa-manual` job] A1[`test` stage<br>`package-and-qa` job]
end end
subgraph "omnibus-gitlab pipeline" subgraph "omnibus-gitlab pipeline"
...@@ -61,7 +61,7 @@ subgraph "omnibus-gitlab pipeline" ...@@ -61,7 +61,7 @@ subgraph "omnibus-gitlab pipeline"
end end
subgraph "gitlab-qa pipeline" subgraph "gitlab-qa pipeline"
A3>QA jobs run] -.->|3. Reports back the pipeline result to the `package-and-qa-manual` job<br>and post the result on the original commit tested| A1 A3>QA jobs run] -.->|3. Reports back the pipeline result to the `package-and-qa` job<br>and post the result on the original commit tested| A1
end end
``` ```
......
...@@ -40,7 +40,7 @@ the time it would take to build packages and test everything. ...@@ -40,7 +40,7 @@ the time it would take to build packages and test everything.
That is why when someone changes `t.text_field :login` to That is why when someone changes `t.text_field :login` to
`t.text_field :username` in the _new session_ view we won't know about this `t.text_field :username` in the _new session_ view we won't know about this
change until our GitLab QA nightly pipeline fails, or until someone triggers change until our GitLab QA nightly pipeline fails, or until someone triggers
`package-and-qa-manual` action in their merge request. `package-and-qa` action in their merge request.
Obviously such a change would break all tests. We call this problem a _fragile Obviously such a change would break all tests. We call this problem a _fragile
tests problem_. tests problem_.
...@@ -171,8 +171,8 @@ and we should prefer the `data-qa-selector` method of definition. ...@@ -171,8 +171,8 @@ and we should prefer the `data-qa-selector` method of definition.
> Introduced in GitLab 12.5 > Introduced in GitLab 12.5
A common occurrence in automated testing is selecting a single "one-of-many" element. A common occurrence in automated testing is selecting a single "one-of-many" element.
In a list of several items, how do you differentiate what you are selecting on? In a list of several items, how do you differentiate what you are selecting on?
The most common workaround for this is via text matching. Instead, a better practice is The most common workaround for this is via text matching. Instead, a better practice is
by matching on that specific element by a unique identifier, rather than by text. by matching on that specific element by a unique identifier, rather than by text.
......
...@@ -44,8 +44,8 @@ There are seven stages that are tracked as part of the Cycle Analytics calculati ...@@ -44,8 +44,8 @@ There are seven stages that are tracked as part of the Cycle Analytics calculati
- Time spent on code review - Time spent on code review
- **Staging** (Continuous Deployment) - **Staging** (Continuous Deployment)
- Time between merging and deploying to production - Time between merging and deploying to production
- **Production** (Total) - **Total** (Total)
- Total lifecycle time; i.e. the velocity of the project or team - Total lifecycle time. That is, the velocity of the project or team. [Previously known](https://gitlab.com/gitlab-org/gitlab/issues/38317) as **Production**.
## Date ranges ## Date ranges
...@@ -60,12 +60,12 @@ GitLab provides the ability to filter analytics based on a date range. To filter ...@@ -60,12 +60,12 @@ GitLab provides the ability to filter analytics based on a date range. To filter
## How the data is measured ## How the data is measured
Cycle Analytics records cycle time and data based on the project issues with the Cycle Analytics records cycle time and data based on the project issues with the
exception of the staging and production stages, where only data deployed to exception of the staging and total stages, where only data deployed to
production are measured. production are measured.
Specifically, if your CI is not set up and you have not defined a `production` Specifically, if your CI is not set up and you have not defined a `production`
or `production/*` [environment](../../ci/yaml/README.md#environment), then you will not have any or `production/*` [environment](../../ci/yaml/README.md#environment), then you will not have any
data for those stages. data for this stage.
Each stage of Cycle Analytics is further described in the table below. Each stage of Cycle Analytics is further described in the table below.
...@@ -77,7 +77,7 @@ Each stage of Cycle Analytics is further described in the table below. ...@@ -77,7 +77,7 @@ Each stage of Cycle Analytics is further described in the table below.
| Test | Measures the median time to run the entire pipeline for that project. It's related to the time GitLab CI takes to run every job for the commits pushed to that merge request defined in the previous stage. It is basically the start->finish time for all pipelines. | | Test | Measures the median time to run the entire pipeline for that project. It's related to the time GitLab CI takes to run every job for the commits pushed to that merge request defined in the previous stage. It is basically the start->finish time for all pipelines. |
| Review | Measures the median time taken to review the merge request that has closing issue pattern, between its creation and until it's merged. | | Review | Measures the median time taken to review the merge request that has closing issue pattern, between its creation and until it's merged. |
| Staging | Measures the median time between merging the merge request with closing issue pattern until the very first deployment to production. It's tracked by the environment set to `production` or matching `production/*` (case-sensitive, `Production` won't work) in your GitLab CI configuration. If there isn't a production environment, this is not tracked. | | Staging | Measures the median time between merging the merge request with closing issue pattern until the very first deployment to production. It's tracked by the environment set to `production` or matching `production/*` (case-sensitive, `Production` won't work) in your GitLab CI configuration. If there isn't a production environment, this is not tracked. |
| Production| The sum of all time (medians) taken to run the entire process, from issue creation to deploying the code to production. | | Total | The sum of all time (medians) taken to run the entire process, from issue creation to deploying the code to production. [Previously known](https://gitlab.com/gitlab-org/gitlab/issues/38317) as **Production**. |
How this works, behind the scenes: How this works, behind the scenes:
...@@ -124,7 +124,7 @@ environments is configured. ...@@ -124,7 +124,7 @@ environments is configured.
1. Now that the merge request is merged, a deployment to the `production` 1. Now that the merge request is merged, a deployment to the `production`
environment starts and finishes at 19:30 (stop of **Staging** stage). environment starts and finishes at 19:30 (stop of **Staging** stage).
1. The cycle completes and the sum of the median times of the previous stages 1. The cycle completes and the sum of the median times of the previous stages
is recorded to the **Production** stage. That is the time between creating an is recorded to the **Total** stage. That is the time between creating an
issue and deploying its relevant merge request to production. issue and deploying its relevant merge request to production.
From the above example you can conclude the time it took each stage to complete From the above example you can conclude the time it took each stage to complete
...@@ -136,10 +136,10 @@ as long as their total time: ...@@ -136,10 +136,10 @@ as long as their total time:
- **Test**: 5min - **Test**: 5min
- **Review**: 5h (19:00 - 14:00) - **Review**: 5h (19:00 - 14:00)
- **Staging**: 30min (19:30 - 19:00) - **Staging**: 30min (19:30 - 19:00)
- **Production**: Since this stage measures the sum of median time off all - **Total**: Since this stage measures the sum of median time of all
previous stages, we cannot calculate it if we don't know the status of the previous stages, we cannot calculate it if we don't know the status of the
stages before. In case this is the very first cycle that is run in the project, stages before. In case this is the very first cycle that is run in the project,
then the **Production** time is 10h 30min (19:30 - 09:00) then the **Total** time is 10h 30min (19:30 - 09:00)
A few notes: A few notes:
......
...@@ -18,7 +18,7 @@ module Gitlab ...@@ -18,7 +18,7 @@ module Gitlab
end end
def title def title
s_('CycleAnalyticsStage|Production') s_('CycleAnalyticsStage|Total')
end end
def legend def legend
......
...@@ -28,6 +28,7 @@ module Gitlab ...@@ -28,6 +28,7 @@ module Gitlab
gon.sprite_file_icons = IconsHelper.sprite_file_icons_path gon.sprite_file_icons = IconsHelper.sprite_file_icons_path
gon.emoji_sprites_css_path = ActionController::Base.helpers.stylesheet_path('emoji_sprites') gon.emoji_sprites_css_path = ActionController::Base.helpers.stylesheet_path('emoji_sprites')
gon.test_env = Rails.env.test? gon.test_env = Rails.env.test?
gon.disable_animations = Gitlab.config.gitlab['disable_animations']
gon.suggested_label_colors = LabelsHelper.suggested_colors gon.suggested_label_colors = LabelsHelper.suggested_colors
gon.first_day_of_week = current_user&.first_day_of_week || Gitlab::CurrentSettings.first_day_of_week gon.first_day_of_week = current_user&.first_day_of_week || Gitlab::CurrentSettings.first_day_of_week
gon.ee = Gitlab.ee? gon.ee = Gitlab.ee?
......
...@@ -187,13 +187,13 @@ module Sentry ...@@ -187,13 +187,13 @@ module Sentry
def parse_stack_trace(event) def parse_stack_trace(event)
exception_entry = event.dig('entries')&.detect { |h| h['type'] == 'exception' } exception_entry = event.dig('entries')&.detect { |h| h['type'] == 'exception' }
return unless exception_entry return [] unless exception_entry
exception_values = exception_entry.dig('data', 'values') exception_values = exception_entry.dig('data', 'values')
stack_trace_entry = exception_values&.detect { |h| h['stacktrace'].present? } stack_trace_entry = exception_values&.detect { |h| h['stacktrace'].present? }
return unless stack_trace_entry return [] unless stack_trace_entry
stack_trace_entry.dig('stacktrace', 'frames') stack_trace_entry.dig('stacktrace', 'frames') || []
end end
def map_to_error(issue) def map_to_error(issue)
......
...@@ -5508,9 +5508,6 @@ msgstr "" ...@@ -5508,9 +5508,6 @@ msgstr ""
msgid "CycleAnalyticsStage|Plan" msgid "CycleAnalyticsStage|Plan"
msgstr "" msgstr ""
msgid "CycleAnalyticsStage|Production"
msgstr ""
msgid "CycleAnalyticsStage|Review" msgid "CycleAnalyticsStage|Review"
msgstr "" msgstr ""
...@@ -5520,6 +5517,9 @@ msgstr "" ...@@ -5520,6 +5517,9 @@ msgstr ""
msgid "CycleAnalyticsStage|Test" msgid "CycleAnalyticsStage|Test"
msgstr "" msgstr ""
msgid "CycleAnalyticsStage|Total"
msgstr ""
msgid "CycleAnalyticsStage|is not available for the selected group" msgid "CycleAnalyticsStage|is not available for the selected group"
msgstr "" msgstr ""
...@@ -18158,6 +18158,9 @@ msgstr "" ...@@ -18158,6 +18158,9 @@ msgstr ""
msgid "The time taken by each data entry gathered by that stage." msgid "The time taken by each data entry gathered by that stage."
msgstr "" msgstr ""
msgid "The total stage shows the time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr ""
msgid "The unique identifier for the Geo node. Must match `geo_node_name` if it is set in gitlab.rb, otherwise it must match `external_url` with a trailing slash" msgid "The unique identifier for the Geo node. Must match `geo_node_name` if it is set in gitlab.rb, otherwise it must match `external_url` with a trailing slash"
msgstr "" msgstr ""
...@@ -19146,9 +19149,6 @@ msgstr "" ...@@ -19146,9 +19149,6 @@ msgstr ""
msgid "Total Contributions" msgid "Total Contributions"
msgstr "" msgstr ""
msgid "Total Time"
msgstr ""
msgid "Total artifacts size: %{total_size}" msgid "Total artifacts size: %{total_size}"
msgstr "" msgstr ""
......
...@@ -30,7 +30,7 @@ and corresponding views / partials / selectors in CE / EE. ...@@ -30,7 +30,7 @@ and corresponding views / partials / selectors in CE / EE.
Whenever `qa:selectors` job fails in your merge request, you are supposed to Whenever `qa:selectors` job fails in your merge request, you are supposed to
fix [page objects](../doc/development/testing_guide/end_to_end/page_objects.md). You should also trigger end-to-end tests fix [page objects](../doc/development/testing_guide/end_to_end/page_objects.md). You should also trigger end-to-end tests
using `package-and-qa-manual` manual action, to test if everything works fine. using `package-and-qa` manual action, to test if everything works fine.
## How can I use it? ## How can I use it?
......
...@@ -76,7 +76,7 @@ describe 'Cycle Analytics', :js do ...@@ -76,7 +76,7 @@ describe 'Cycle Analytics', :js do
click_stage('Staging') click_stage('Staging')
expect_build_to_be_present expect_build_to_be_present
click_stage('Production') click_stage('Total')
expect_issue_to_be_present expect_issue_to_be_present
end end
......
{
"eventID": "333b98e3b91341d8a6247edff171d8cf",
"dist": null,
"userReport": null,
"projectID": "1788822",
"previousEventID": "d32f1ce60de14911beec5109d9b5bdbd",
"message": null,
"id": "333b98e3b91341d8a6247edff171d8cf",
"size": 77202,
"errors": [
{
"data": {
"reason": "the cookie is missing a name/value pair",
"name": "request.cookies",
"value": "********"
},
"message": "Discarded invalid value",
"type": "invalid_data"
},
{
"data": {
"reason": "the cookie is missing a name/value pair",
"name": "request.cookies",
"value": "********"
},
"message": "Discarded invalid value",
"type": "invalid_data"
}
],
"culprit": "/",
"title": "ActiveRecord::NoDatabaseError: FATAL: database \"test_development\" does not exist",
"sdkUpdates": [],
"platform": "ruby",
"location": "active_record/connection_adapters/postgresql_adapter.rb",
"nextEventID": null,
"type": "error",
"metadata": {
"function": "rescue in connect",
"type": "ActiveRecord::NoDatabaseError",
"value": "FATAL: database \"test_development\" does not exist\n",
"filename": "active_record/connection_adapters/postgresql_adapter.rb"
},
"groupingConfig": {
"enhancements": "eJybzDhxY3J-bm5-npWRgaGlroGxrpHxBABcTQcY",
"id": "newstyle:2019-05-08"
},
"crashFile": null,
"tags": [
{
"value": "Chrome 78.0.3904",
"key": "browser",
"_meta": null
},
{
"value": "Chrome",
"key": "browser.name",
"_meta": null
},
{
"value": "Mac OS X 10.15.1",
"key": "client_os",
"_meta": null
},
{
"value": "Mac OS X",
"key": "client_os.name",
"_meta": null
},
{
"value": "development",
"key": "environment",
"_meta": null
},
{
"value": "error",
"key": "level",
"_meta": null
},
{
"value": "ruby",
"key": "logger",
"_meta": null
},
{
"value": "b56ae26",
"key": "release",
"_meta": null
},
{
"value": "Seans-MBP.fritz.box",
"key": "server_name",
"_meta": null
},
{
"value": "/",
"key": "transaction",
"_meta": null
},
{
"value": "http://localhost:3001/",
"key": "url",
"_meta": null
},
{
"query": "user.ip:\"::1\"",
"value": "ip:::1",
"key": "user",
"_meta": null
}
],
"dateCreated": "2019-12-08T21:48:07Z",
"dateReceived": "2019-12-08T21:48:08.579417Z",
"user": {
"username": null,
"name": null,
"ip_address": "::1",
"email": null,
"data": null,
"id": null
},
"entries": [],
"packages": {
"coffee-script": "2.4.1",
"uglifier": "4.1.20",
"ffi": "1.11.1",
"actioncable": "5.2.3",
"io-like": "0.3.0",
"rb-inotify": "0.10.0",
"spring": "2.1.0",
"loofah": "2.2.3",
"selenium-webdriver": "3.142.3",
"marcel": "0.3.3",
"sass-listen": "4.0.0",
"nokogiri": "1.10.4",
"activestorage": "5.2.3",
"activejob": "5.2.3",
"mimemagic": "0.3.3",
"faraday": "0.17.1",
"execjs": "2.7.0",
"activesupport": "5.2.3",
"rails-html-sanitizer": "1.2.0",
"byebug": "11.0.1",
"xpath": "3.2.0",
"msgpack": "1.3.1",
"childprocess": "1.0.1",
"rails-dom-testing": "2.0.3",
"public_suffix": "3.1.1",
"mini_mime": "1.0.2",
"arel": "9.0.0",
"coffee-rails": "4.2.2",
"bundler": "1.17.3",
"rails": "5.2.3",
"globalid": "0.4.2",
"sentry-raven": "2.12.3",
"concurrent-ruby": "1.1.5",
"capybara": "3.28.0",
"regexp_parser": "1.6.0",
"sprockets-rails": "3.2.1",
"tzinfo": "1.2.5",
"mail": "2.7.1",
"actionview": "5.2.3",
"rubyzip": "1.2.3",
"coffee-script-source": "1.12.2",
"listen": "3.1.5",
"i18n": "1.6.0",
"erubi": "1.8.0",
"rake": "12.3.3",
"nio4r": "2.4.0",
"activemodel": "5.2.3",
"web-console": "3.7.0",
"ruby_dep": "1.5.0",
"turbolinks": "5.2.0",
"archive-zip": "0.12.0",
"method_source": "0.9.2",
"minitest": "5.11.3",
"puma": "3.12.1",
"sass-rails": "5.1.0",
"chromedriver-helper": "2.1.1",
"sprockets": "3.7.2",
"bindex": "0.8.1",
"actionmailer": "5.2.3",
"rack-test": "1.1.0",
"bootsnap": "1.4.4",
"railties": "5.2.3",
"mini_portile2": "2.4.0",
"crass": "1.0.4",
"websocket-extensions": "0.1.4",
"multipart-post": "2.1.1",
"rb-fsevent": "0.10.3",
"jbuilder": "2.9.1",
"pg": "1.1.4",
"sass": "3.7.4",
"activerecord": "5.2.3",
"builder": "3.2.3",
"spring-watcher-listen": "2.0.1",
"websocket-driver": "0.7.1",
"thor": "0.20.3",
"thread_safe": "0.3.6",
"addressable": "2.6.0",
"prometheus-client-mmap": "0.9.8",
"tilt": "2.0.9",
"actionpack": "5.2.3",
"rack": "2.0.7",
"turbolinks-source": "5.2.0"
},
"sdk": {
"version": "2.12.3",
"name": "raven-ruby"
},
"_meta": {
"user": null,
"context": null,
"entries": {
"1": {
"data": {
"": null,
"cookies": {
"": {
"err": [
[
"invalid_data",
{
"reason": "the cookie is missing a name/value pair"
}
]
],
"val": "********"
}
},
"url": null,
"headers": null,
"env": null,
"query": null,
"data": null,
"method": null
}
}
},
"contexts": null,
"message": null,
"packages": null,
"tags": {},
"sdk": null
},
"contexts": {
"browser": {
"version": "78.0.3904",
"type": "browser",
"name": "Chrome"
},
"client_os": {
"version": "10.15.1",
"type": "os",
"name": "Mac OS X"
}
},
"fingerprints": [
"6aa133ea51857634f2d113de52b5cc61",
"e1613eeb169241eab95b76ab52a80c68"
],
"context": {
"server": {
"runtime": {
"version": "ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]",
"name": "ruby"
},
"os": {
"kernel_version": "Darwin Seans-MBP.fritz.box 19.0.0 Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64 x86_64",
"version": "Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64",
"build": "19.0.0",
"name": "Darwin"
}
}
},
"release": {
"dateReleased": null,
"commitCount": 0,
"url": null,
"data": {},
"lastDeploy": null,
"deployCount": 0,
"dateCreated": "2019-12-08T21:47:47Z",
"lastEvent": "2019-12-09T21:52:05Z",
"version": "b56ae26",
"firstEvent": "2019-12-08T21:47:47Z",
"lastCommit": null,
"shortVersion": "b56ae26",
"authors": [],
"owner": null,
"newGroups": 26,
"ref": null,
"projects": [
{
"slug": "gitlab-03",
"name": "gitlab-03"
}
]
},
"groupID": "1378364652"
}
\ No newline at end of file
This diff is collapsed.
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec' require 'lib/gitlab/cycle_analytics/shared_stage_spec'
describe Gitlab::CycleAnalytics::ProductionStage do describe Gitlab::CycleAnalytics::ProductionStage do
let(:stage_name) { :production } let(:stage_name) { 'Total' }
it_behaves_like 'base stage' it_behaves_like 'base stage'
end end
...@@ -218,4 +218,62 @@ describe Sentry::Client do ...@@ -218,4 +218,62 @@ describe Sentry::Client do
it_behaves_like 'issues has correct length', 1 it_behaves_like 'issues has correct length', 1
end end
end end
describe '#issue_latest_event' do
let(:sample_response) do
Gitlab::Utils.deep_indifferent_access(
JSON.parse(fixture_file('sentry/issue_latest_event_sample_response.json'))
)
end
let(:issue_id) { '1234' }
let(:sentry_api_response) { sample_response }
let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0' }
let(:sentry_request_url) { sentry_url + "/issues/#{issue_id}/events/latest/" }
let!(:sentry_api_request) { stub_sentry_request(sentry_request_url, body: sentry_api_response) }
subject { client.issue_latest_event(issue_id: issue_id) }
it_behaves_like 'calls sentry api'
it 'has correct return type' do
expect(subject).to be_a(Gitlab::ErrorTracking::ErrorEvent)
end
shared_examples 'assigns error tracking event correctly' do
using RSpec::Parameterized::TableSyntax
where(:event_object, :sentry_response) do
:issue_id | :groupID
:date_received | :dateReceived
end
with_them do
it { expect(subject.public_send(event_object)).to eq(sentry_api_response.dig(*sentry_response)) }
end
end
context 'error object created from sentry response' do
it_behaves_like 'assigns error tracking event correctly'
it 'parses the stack trace' do
expect(subject.stack_trace_entries).to be_a Array
expect(subject.stack_trace_entries).not_to be_empty
end
context 'error without stack trace' do
before do
sample_response['entries'] = []
stub_sentry_request(sentry_request_url, body: sample_response)
end
it_behaves_like 'assigns error tracking event correctly'
it 'returns an empty array for stack_trace_entries' do
expect(subject.stack_trace_entries).to eq []
end
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment